c# - Entity Framework update virtual property directly without creating new record -
here simple entity:
public class customer : entity { public virtual location location { get; set; } }
now suppose have customer already:
var customer = new customer() {location = new location("china")};
and want update location:
var customer = context.customers.first(x => x.location.country == "china"); customer.location = new location("america"); context.savechanges();
and when @ database, location record "china" has not been deleted: database has 2 location records association 1 customer record.
the reason issue i'm using virtual keyword on customer.location property, , when query customer entity database didn't use include method load location property, , did not use accesses lazy load it. ef can't track , know china
location entity should deleted.
i think approach used update virtual property in line intuition. want update property, use update instruction "entity.xxx=...", add being forced use access of property or method call while loading "entity.xxx" not intuitive.
so looking better way replace entity's virtual property directly. suggestions?
solutions update
i'm find 2 way easy,
first can use identifying relation(recommend).
another way can use objectcontext.deleteobject method, below example code:
public static class efcollectionhelper { public static void updatecollection<t, tvalue>(this t target, expression<func<t, ienumerable<tvalue>>> memberlamda, tvalue value)where t : entity { var memberselectorexpression = (memberexpression)memberlamda.body; var property = (propertyinfo)memberselectorexpression.member; var oldcollection = memberlamda.compile()(target); oldcollection.clearup(); property.setvalue(target, value, null); } public static void clearup<t>(this ienumerable<t> collection) { //convert dbcontext iobjectcontextadapter var objcontext = ((iobjectcontextadapter) program.dbcontext).objectcontext; (int = 0; < collection.count(); i++) { objcontext.deleteobject(collection.elementat(i)); } } }
and can write code like:
customer.updatecollection(x => x.locations, null);
not sure want, got.
the reason getting 2 locations because use new location("american");
add reference new location (ef don't know if china used customer, , never delete it, in type of query)
now if said.
customer.location.country = "america"
the china overwritten america, working specific location
's property.
read coments on question little extras
if want update location (new location("some new location")
). this.
location oldlocation = customer.location; location newlocation = new location("america"); //check if new location country !exist if(!context.locations.any(a=> a.country == newlocation.country)) { //if don't exist add (avoiding location duplicate) customer.location = newlocation; //if important delete old location //(important after removed dependency, //thats why after new location added) context.locations.remove(oldlocation) //finally save changes context.savechanges(); }
Comments
Post a Comment