实体框架,如何避免这个问题
本文关键字:问题 何避免 框架 实体 | 更新日期: 2023-09-27 18:13:41
我有一个这样的方法:
public FbUser FindUserByGraphOrInsert(dynamic json, bool commit = false)
{
string graphId = json.id;
EntityDataModelContext context = DataContext.GetDataContext();
FbUser user = context.FbUsers.FirstOrDefault(u => u.FbGraphId == graphId);
if (user == null)
{
user = new FbUser();
user.FbGraphId = json.id;
user.FbUsername = StringExtensions.UnicodeDecode(json.name);
context.FbUsers.AddObject(user);
if (commit)
context.SaveChanges();
}
return user;
}
我在一个循环中反复调用这个方法(比如80次以上),使用commit = false
问题是,我希望这个方法让我知道用户是否已经在上下文中,但情况似乎并非如此。
结果是,当我最终保存更改时,我得到一个包含80个用户的列表,其中27个是不同的。
我希望这个方法返回那27,我怎么能改变它来实现这一点?
我真的需要每次都保存更改吗?
您不能"简单地"这样做,问题是每个查询默认情况下总是会命中数据库,因为EF无法知道您要么查询相同的数据,要么自打开连接以来数据库中没有底层更改。
但是,您可以检查ChangeTracker/ObjectStateManager是否存在已更改的对象,并在决定添加新对象之前查询该对象。
示例:var addedObjects = context.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added);
var equalObjects = addedObjects.OfType<MyEntity>().Where(x => x.Name == newObject.Name);
根据Polity的回答,我实现了以下扩展方法,并成功了。
public static IEnumerable<T> IncludeUnsaved<T>(this ObjectSet<T> set) where T : class
{
var addedObjects = set.Context.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added);
var equalObjects = addedObjects.Select(e => e.Entity).OfType<T>();
return equalObjects.Concat(set);
}