System.ArgumentException: Property set method not found.

Discussion of open issues, suggestions and bugs regarding ADO.NET provider for MySQL
emp51302
Posts: 46
Joined: Fri 19 Aug 2011 20:57

System.ArgumentException: Property set method not found.

Post by emp51302 » Wed 05 Sep 2012 21:50

I am trying to CopyDataMembers from source to target entity and I getting the following error.

Code: Select all

System.ArgumentException: Property set method not found.
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
   at MyClass.CopyDataMembers(DataContext dc, Object sourceEntity, Object targetEntity)
[/color]

All I am tring to do is get entity members using the following line of code.

Code: Select all

IEnumerable<MetaDataMember> dataMembers =
                    from mem in dc.Mapping.GetTable(sourceEntity.GetType()).RowType.DataMembers
                    where mem.IsAssociation == false
                    select mem
Note:
dc = Devart.Data.Linq.DataContext

Please help.

Thank you!

:cry:

emp51302
Posts: 46
Joined: Fri 19 Aug 2011 20:57

Re: System.ArgumentException: Property set method not found.

Post by emp51302 » Fri 07 Sep 2012 14:48

Hello can anyone help that why with the new version 7.2 of mysql dotConnect, the following code doesn't work for reflection?

All I am trying to do is copy source object to destination to clone it that way It creates a duplicate copy of it. This all seems to work with version 6.80.325 release.

But after the reference to System.Data.Linq was removed, I am not able to CopyDataMembers
from source to destination

Code: Select all

public static void CopyDataMembers(DataContext dc, object sourceEntity, object targetEntity){
 IEnumerable<MetaDataMember> dataMembers =
                    from mem in dc.Mapping.GetTable(sourceEntity.GetType()).RowType.DataMembers
                    where mem.IsAssociation == false
                    select mem;

                //IEnumerable<MetaDataMember> primaryKeyMembers = dc.Mapping.GetTable(typeof(TSource)).RowType.DataMembers.AsQueryable().Where(mem => mem.IsPrimaryKey == true);

                //go through the list of members and compare values
                foreach (MetaDataMember mem in dataMembers)
                {
                    object originalValue = mem.StorageAccessor.GetBoxedValue(targetEntity);
                    object newValue = mem.StorageAccessor.GetBoxedValue(sourceEntity);

                    //check if the value has changed
                    if (newValue == null && originalValue != null || newValue != null && !newValue.Equals(originalValue))
                    {
                        //use reflection to update the target
                        System.Reflection.PropertyInfo propInfo = targetEntity.GetType().GetProperty(mem.Name);
                        propInfo.SetValue(targetEntity, propInfo.GetValue(sourceEntity, null), null);


                    }
                }
}

StanislavK
Devart Team
Posts: 1710
Joined: Thu 03 Dec 2009 10:48

Re: System.ArgumentException: Property set method not found.

Post by StanislavK » Mon 10 Sep 2012 12:18

Sorry for the delay. The probable reason of the issue is that one of your entity's properties is read-only. We changed the default code generation template so that no setter is generated for read-only properties now. That is why reflection cannot change the property of the target object.

To resolve the issue, you can use one of the following options:
  • Disable the Read-Only option for your properties.
  • Modify the template so that setters are generated for all properties. To do so, find and remove the code block that includes 'if (!property.ReadOnly) {' (and the block where the curly brace is closed as well).
  • Instead of properties, access the underlying fields via reflection.
Please tell us if this helps.

emp51302
Posts: 46
Joined: Fri 19 Aug 2011 20:57

Re: System.ArgumentException: Property set method not found.

Post by emp51302 » Mon 10 Sep 2012 15:02

Thank you for the response.

Looking at the 3 options you have giving below, when you say "Modify the template so that setters are generated for all properties", are you trying to say that modify the template code generated by dotConnect Entity Developer using LinqConnect template?

Is there a way or option in the Entity developer which would help me do that. Because everytime I generate the new DataContext code using Entity Developer, I would have to find the Readonly Property and remove it?

In short in the EntityDeveloper is there an option which would say Generate Setters? or something like that which would help me fix the issue?

Also on different topic, the other BIG issue is in prior version when my datatype was LONG and if my variable was an INT, there was never a CAST issue, but now I am seeing that since the datatype in the Database is LONG and if I try to query it by passing an INT value for that field which is LONG, the app crashes, saying that datatype is incorrect. Why is that? In prior version the casting was never an issue for a LONG or INT type. Now I have to convert all my INT properties to LONG for it to work. Can this be fixed? Please advise!

Note: No datatype issue during compile time, the project compiles fine! The datatype issue only comes during runtime!


Please HELP! I have already renewed 2 of my licenses for dotConnect and was a bit upset with the sudden changes to the new version in 7.2

Thank you again.

StanislavK
Devart Team
Posts: 1710
Joined: Thu 03 Dec 2009 10:48

Re: System.ArgumentException: Property set method not found.

Post by StanislavK » Tue 11 Sep 2012 11:42

Entity Developer uses T4-like templates to generate code for models. The default template does not generate setters for read-only properties. To change this behaviour, please modify the template:
  • Find the template in the Templates node of the Model Explorer tool window.
  • In the context menu, select the 'Copy to Model Folder' item. At this point, the template will be added to your solution and so you will be able to modify it.
  • Open the template and find the following entry:

    Code: Select all

    if (!property.ReadOnly) {
  • Remove the code block that contains it, as well as the code block that contains the corresponding closing curly brace.
  • Save the template and re-generate the code for the model. At this point, read-only properties should have setters.
As for the cast issue, please specify the following:
  • the exact server data type used for the problem column (e.g., 'bigint(20)');
  • whether the .NET data type of the corresponding property is Int32 or Int64;
  • a sample scenario in which the issue can be reproduced (e.g., inserting a new entity, or querying the table with a condition like 'LongProperty == 1').
We are sending you a test application, please change it so that the problem can be reproduced, or send us your sample.

emp51302
Posts: 46
Joined: Fri 19 Aug 2011 20:57

Re: System.ArgumentException: Property set method not found.

Post by emp51302 » Tue 11 Sep 2012 21:24

Ok I changed the code in the template where there was: if (!property.ReadOnly) {

After doing that, my original problem still remains when I call the CopyDataMembers Function I still get the error Property Set Method Not Found!!!!

Please help its really important. I created the template as suggested and re-generated the code. Compiles fine, but then when I call the CopyDataMembers method (as previoulsy told) I can the Argument Exception error: Property Set Method Not Found!

Would appreciate any help!!!! I love your product, but I am stuck here and that method is really really important!

Thanks again!

MariiaI
Devart Team
Posts: 1472
Joined: Mon 13 Feb 2012 08:17

Re: System.ArgumentException: Property set method not found.

Post by MariiaI » Wed 12 Sep 2012 07:40

As for the issue with CopyDataMembers, we have sent you a sample project. Please check that the letter is not blocked by your mail filter. Please try the sample and make changes to it, so that the issue could be reproduced, and send it back to us, or send us your model.

As for the second issue, have you received the sample project that we had sent you?

emp51302
Posts: 46
Joined: Fri 19 Aug 2011 20:57

Re: System.ArgumentException: Property set method not found.

Post by emp51302 » Wed 12 Sep 2012 13:52

Thank you for the quick response. I received your email related to the CopyDataMembers issue this morning and I am going to test it out and reply you back with my findings. I really want the CopyDataMembers using reflection to work :( I feel sad that I purchased 2 licenses for dotConnect and I am having this weird issue :shock: . I will work on the sample you provided and respond you back asap.

On the other issue, Yes I did receive the email for CAST from INT to LONG and vice versa. I am not able to overcome that. The only way I was able to resolve the issue was to change my INT variables to LONG. This is a pain, since in prior versions of dotConnect 6.x and below this was never an issue and even though I do something like;

Code: Select all

ArticleVersion articleVersionSource = bdcSource.ArticleVersions.Single(av => av.ArticleVersionId == ArticleVersionID);
Here in the above line of Linq Expression, av.ArticleVersionId is of datatype long? of object type ArticleVersion (which is article_version table in MySQL database). On the other hand ArticleVersionID is a variable of type INT.

FYI, the actual datatype for article_version_id (ArticleVersionId) in the database is INT(10), but when it generates the Objects and Classes using dotConnect for Linq Entity Developer tool it makes it as long?, which is okay, but why do I have to CAST it?

The only solution I found was to make my variable which I have defined in ASP.NET as INT to LONG. Am I missing anything?

Any help would be appreciated!

emp51302
Posts: 46
Joined: Fri 19 Aug 2011 20:57

Re: System.ArgumentException: Property set method not found.

Post by emp51302 » Wed 12 Sep 2012 19:06

Hmm here's the fix or should I say hack? I suppose.. When I change the code below in CopyDataMembers method;

Original Line:

Code: Select all

IEnumerable<MetaDataMember> dataMembers = 
             from mem in dc.Mapping.GetTable(sourceEntity.GetType()).RowType.DataMembers
             where mem.IsAssociation == false
             select mem;
TO

Modfied To:

Code: Select all

IEnumerable<MetaDataMember> dataMembers = 
             from mem in dc.Mapping.GetTable(sourceEntity.GetType()).RowType.DataMembers
             where mem.IsAssociation == false && mem.IsPrimaryKey == false
             select mem;
All I added was && mem.IsPrimaryKey == false and it works perfect!, since the auto-generated primary key is ReadOnly, which in this case was ArticleVersionId, I had to exclude that field column!

Am I right? Does it make sense?

Please advise.

Awaiting your response!

MariiaI
Devart Team
Posts: 1472
Joined: Mon 13 Feb 2012 08:17

Re: System.ArgumentException: Property set method not found.

Post by MariiaI » Thu 13 Sep 2012 12:17

We are sending you the sample project with reflection again. Please try the sample and make changes to it, so that the issue could be reproduced, and send it back to us, or send us your sample.

As for the CAST issue, we still couldn't reproduce it. Please check the default mapping in the Tools->Entity Developer->Options->Server Options->MySql (Server Type "Int" should be mapped to .NET Type "Int32"). Also, please send us a small test project (with simple tables), which demonstrates this behaviour.

emp51302
Posts: 46
Joined: Fri 19 Aug 2011 20:57

Re: System.ArgumentException: Property set method not found.

Post by emp51302 » Fri 14 Sep 2012 15:20

Hi Mariia - I have sent you a sample asp.net project via email which has a sample asp.net project and Mysql script for a single table along with some 10 records.

I noticed that the sample you sent works great if its a .net console application but throws exception when using CopyDataMembers in asp.net web application and the method fails.

If you look at my code sent via email, only if I add, && mem.IsPrimaryKey == false in the
Linq expression then it seems to do the trick and work. But I would like to avoid that and know why the same code fails in asp.net application and works ok in .net console application?

Please let me know if Devart figures out the fix.

Thank you and awaiting the response on the same.

Best,

:?

emp51302
Posts: 46
Joined: Fri 19 Aug 2011 20:57

Re: System.ArgumentException: Property set method not found.

Post by emp51302 » Mon 17 Sep 2012 13:52

Hi Mariia/Devart Team - Any updates on the sample asp.net application which I sent? The code works ok in console application but NOT in asp.net application.

Please advise.

Thank you,

Best,

MariiaI
Devart Team
Posts: 1472
Joined: Mon 13 Feb 2012 08:17

Re: System.ArgumentException: Property set method not found.

Post by MariiaI » Mon 17 Sep 2012 14:14

Thank you for the test project. We have investigated it. This is an expected behaviour. The error occurs because the 'ArticleVersionId' property is database-generated, and the default template does not create setters for database-generated properties (as it is not expected that they will be changed explicitly). Thus, you can disable the 'Auto Generated' option for this property to resolve the issue.

Besides, to make the code more efficient, you can use the MetaDataMember accessors instead of searching for properties via reflection. In particular, it will resolve the initial problem, as storage accessors work with underlying fields instead of property getters and setters.

For example, please replace this code:

Code: Select all

System.Reflection.PropertyInfo propInfo = targetEntity.GetType().GetProperty(mem.Name);
propInfo.SetValue(targetEntity, propInfo.GetValue(sourceEntity, null), null);
with the following:

Code: Select all

mem.StorageAccessor.SetBoxedValue(ref targetEntity, newValue);
Please inform us about the results.

emp51302
Posts: 46
Joined: Fri 19 Aug 2011 20:57

Re: System.ArgumentException: Property set method not found.

Post by emp51302 » Mon 17 Sep 2012 15:40

Hi Mariia - Excellent! That works! So that problem is now solved!

Now on the other CAST issue, from INT to LONG and vice-versa. Is that a know issue which is there in 7.2. I read one of the post which also had similar type of issue like mine related to CAST.

Please advise.

Best,

MariiaI
Devart Team
Posts: 1472
Joined: Mon 13 Feb 2012 08:17

Re: System.ArgumentException: Property set method not found.

Post by MariiaI » Tue 18 Sep 2012 12:32

We're glad the first problem was resolved.
As for the CAST issue, we have reproduced it. We are working on it now and will inform you when it is fixed.

JIC: if in your project the int(10) datatype is mapped to long(int64), please check the default mapping in the Tools->Entity Developer->Options->Server Options->MySql. The "Int" Server Type should be mapped to the "Int32" .NET Type. Otherwise, please set .NET Type to "Int32" and re-generate your model.

Post Reply