[英]Generic Way to Check If Entity Exists In Entity Framework?
我正在寻找一种通用方法来检查DbSet
中的实体。 像这样的东西,这是行不通的:
private DbContext DbContext { get; set; }
private DbSet<T> DbSet { get; set; }
public Boolean Exists(T entity) {
return ((from item in this.DbSet
where item == entity
select item).Count() > 0);
}
where item == entity
在 LINQ 到 SQL 中工作的行,但显然不是 LINQ 到 Entities。 由于实体可能有不同的键,我不能让它们全部继承自具有已知键的公共抽象以进行比较。
我可以这样做,但我担心将捕获异常作为验证过程的性能
这也不起作用,因为只要分离了实体,就无法获得OriginalValues
属性:
public Boolean Exists(T entity) {
try {
var current = this.DbContext.Entry(entity).OriginalValues;
// Won't reach this line if the entity isn't in the database yet
return true;
}
catch (Exception ex) {
return false;
}
}
如果实体存在,你想要通用的方式来检查实体是否被上下文加载或者通用的方式来查询数据库吗?
对于前一种情况使用:
public bool Exists<T>(T entity) where T: class
{
return this.Set<T>().Local.Any(e => e == entity);
}
对于后一种情况使用(它也会检查加载的实体):
public bool Exists<T>(params object[] keys)
{
return this.Set<T>().Find(keys) != null;
}
编辑:
EF 代码首先不应访问此类信息,但可以获取实体键的名称。 我认为这样的事情应该有效:
var objContext = ((IObjectContextAdapter)dbContext).ObjectContext;
var objSet = objContext.CreateObjectSet<T>();
var keyNames = objSet.EntitySet.ElementType.KeyMembers.Select(m => m.Name);
但这一切都没有意义。 您想要通用方法,但您的实体不共享必要的信息以允许通用方法。 现在你说你连键值都不知道。 使用这种“通用”方法将需要反思和手动构建表达式树。
感谢@Ladislav 让我朝着正确的方向前进。 下面是通用Exists()
方法的代码。
我想指出,这不需要反思,而且似乎表现得很好。 唯一让我不高兴的是TryGetObjectByKey()
具有附加找到的实体的副作用。 因为我不希望Exists()
有那个无意的结果,所以如果找到它,我必须分离实体。
public Boolean Exists(T entity) {
var objContext = ((IObjectContextAdapter)this.DbContext).ObjectContext;
var objSet = objContext.CreateObjectSet<T>();
var entityKey = objContext.CreateEntityKey(objSet.EntitySet.Name, entity);
Object foundEntity;
var exists = objContext.TryGetObjectByKey(entityKey, out foundEntity);
// TryGetObjectByKey attaches a found entity
// Detach it here to prevent side-effects
if (exists) {
objContext.Detach(foundEntity);
}
return (exists);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.