简体   繁体   中英

Issues with relationships using pocos in entity framework

I have an application where I use POCO classes and I'm getting an error when I try to set a relationship between a new object and a persisted object.

I have these classes: SecurityUser and SecurityGroup . SecurityUser has a property Group_ID where I can set the ID for the user group and a property SecurityGroup where I can set the object itself. When I try to set a new SecurityGroup for this property I get the "null reference" exception on the POCO class. Here's an example of my code:

using (SecurityEntities context = new SexurityEntities(connectionString))
{
    SecurityUser user = context.SecurityUsers.SingleOrDefault(cond => cond.User_ID == 1);
    SecurityGroup group = new SecurityGroup();
    user.SecurityGroup = group;

    context.SecurityGroups.AddObject(group);
    context.SaveChanges();
}

When I do this without using the entity framework without the POCO classes, everything goes well, but with POCOs it doesn't.

It's one of those ugly relationship fixup problems which are causing trouble with EF 4 POCOs every now and then.

If you take a look at the classes created by the POCO generator you'll see a region called " Association Fixup " containing some methods like FixupSecurityGroup or similar called from property setters of your POCOs. I could reproduce your problem but even after debugging I couldn't find exactly the point where it goes wrong in these fixup methods. So, I cannot explain why your code doesn't work.

But I found two solutions which work:

1) Don't create the group with new but use the CreateObject method:

SecurityUser user = context.SecurityUsers
    .SingleOrDefault(cond => cond.User_ID == 1);

SecurityGroup group = context.SecurityGroups.CreateObject();
user.SecurityGroup = group;

context.SaveChanges();

(I've removed AddObject . It's not necessary because EF recognizes that the group is new and creates an INSERT statement, but removing AddObject alone doesn't fix the problem.)

Your POCO properties are virtual and EF will create a dynamic proxy for the SecurityUser when you load it from the DB. Apparently for some reason a dynamic proxy also for the SecurityGroup you create is required, otherwise we get your null reference exception. CreateObject will create this proxy.

2) Alternatively you can turn off proxy creation:

context.ContextOptions.ProxyCreationEnabled = false;

SecurityUser user = context.SecurityUsers
    .SingleOrDefault(cond => cond.User_ID == 1);

SecurityGroup group = new SecurityGroup();
user.SecurityGroup = group;

context.SaveChanges();

Now, user is no dynamic proxy and the code also works when you create the group with an ordinary new operator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM