4 entity-framework .net-4.0 entity-framework-4 self-tracking-entities
自我跟踪实体.真棒.
除非你做了类似的事情
return Db.Users;
Run Code Online (Sandbox Code Playgroud)
没有任何自我跟踪实体在跟踪(直到可能,它们被反序列化).
精细.因此,我们必须认识到返回给我们的实体可能没有启用跟踪.
怎么办???
我尝试过的事情
对于给定的方法体:
using (var db = new Database())
{
if (update.ChangeTracker.ChangeTrackingEnabled)
db.Configurations.ApplyChanges(update);
else
FigureItOut(update, db);
db.SaveChanges();
update.AcceptChanges();
}
Run Code Online (Sandbox Code Playgroud)
以下FigureItOut所有实现都失败了:
db.Configurations.Attach(update);
db.DetectChanges();
Run Code Online (Sandbox Code Playgroud)
也不
db.Configurations.Attach(update);
db.Configurations.ApplyCurrentValues(update);
Run Code Online (Sandbox Code Playgroud)
也不
db.Configurations.Attach(update);
db.Configurations.ApplyOriginalValues(update);
Run Code Online (Sandbox Code Playgroud)
也不
db.Configurations.Attach(update);
db.Configurations.ApplyChanges(update
Run Code Online (Sandbox Code Playgroud)
除了以外我也无法想象其他任何东西
究竟,我应该对不跟踪自己的自我跟踪实体做些什么?
小更新:
盲目地将实体标记为修改过的作品,然而这看起来有点臭.在这种情况下,这是我们能做的最好的吗?
小智 6
方案1
以下是一些建议的做法.当您在WCF场景中使用STE时,您应该依赖STE实现的更改跟踪器,以便在服务器端执行以下操作.
db.Users.ApplyChanges(user);
db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
方案2但是,如果您在服务器上,建议的做法是在objectcontext的partial类上创建一个名为EnableChangeTracking的方法.该方法将查询处于未更改状态的实体,该实体实现IObjectWithChangeTracker并打开更改跟踪,所以这样的事情
user = db.users.first(u => u.userid == 1);
db.EnableChangeTracking();
Run Code Online (Sandbox Code Playgroud)
现在尝试从最初从中检索用户实体的不同上下文中保存用户实体
db2.users.ApplyChanges(user);
db2.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
方案3如果在服务器端您连接到从中检索用户实体的同一对象上下文,则使用STE作为简单的poco对象,如下所示
user = db.users.first(u => u.userid == 1);
user.LastName = "XYZ";
db.DetectChanges(); //no need for it cuz Savechanges implicitly calls this.
db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
方案4如果从不同的上下文中检索用户实体,那么上下文u将使用它来保存,那么这里是另一个选项,其中u将实体标记为已修改,而不关心修改了什么.
user = db.users.first(u => u.userid == 1);
var db2 = new ObjectContext();
user.LastName = "XYZ";
db2.Users.Attach(user);
// i prefer this option..
db2.ObjectStateManager.ChangeObjectState(user,EntityState.Modified);
db2.SaveChanges(); // updates all columns
Run Code Online (Sandbox Code Playgroud)
方案5如果从不同的上下文中检索用户实体,那么上下文u将使用它来保存,那么这里是另一个选择,其中你检索原始实体.
user = db.users.first(u => u.userid == 1);
user.lastName ="XYZ";
var db2 = new ObjectContext();
db2.Users.First(u => u.userid == user.userid);
db2.users.ApplyCurrentValues(user);
db2.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
这是一篇描述几个场景的博客文章. http://weblogs.asp.net/zeeshanhirani/archive/2010/03/30/modifying-self-tracking-entity-on-the-server.aspx
我在我的Entity Framework 4.0食谱书中广泛地介绍了这些概念,并提供了很多场景.