我有一个实体,我们称之为CommonEntity
,其主键在许多其他实体中用作外键。随着应用程序的开发,这些链接将继续增长。
我想知道是否可以安全删除CommonEntity
(即任何其他实体都没有使用它)。
我意识到我能做到
if(!ce.EntityA.Any() && !ce.EntityB.Any() ... && !ce.EntityN.Any())
{
//Delete
}
但是我希望能够自动检查所有关系,因为我不喜欢每次添加新关系时都必须手动更改此代码。也许EF4 +中有一些我不知道的东西?
我认为有可能使用事务范围来尝试删除对象并在其失败时将其回滚,但我不确定这种方法是否存在任何不良副作用。
有更好的方法吗?
编辑:看起来VS2012已使用EF5,即使该项目是.Net 4,因此它已经使用POCO创建了模型,即使它是从数据库生成的。
答案 0 :(得分:11)
让它失败。如果实体有很多关系,那么验证可能非常繁重。
public bool TryDelete(int id)
{
try
{
// Delete
return true;
}
catch (SqlException ex)
{
if (ex.Number == 547) return false; // The {...} statement conflicted with the {...} constraint {...}
throw; // other error
}
}
答案 1 :(得分:5)
你可以试试这个:
var allrelatedEnds = ((IEntityWithRelationships)ce).RelationshipManager.GetAllRelatedEnds();
bool hasRelation = false;
foreach (var relatedEnd in allrelatedEnds)
{
if (relatedEnd.GetEnumerator().MoveNext())
{
hasRelation = true;
break;
}
}
if (!hasRelation)
{
//Delete
}
答案 2 :(得分:2)
你可以使用Reflection(如果你不想使用"在SQL&#34上删除失败;) 我写这个是因为我不想删除实体,只想知道它是否与任何相关!
public static object GetEntityFieldValue(this object entityObj, string propertyName)
{
var pro = entityObj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).First(x => x.Name == propertyName);
return pro.GetValue(entityObj, null);
}
public static IEnumerable<PropertyInfo> GetManyRelatedEntityNavigatorProperties(object entityObj)
{
var props = entityObj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.CanWrite && x.GetGetMethod().IsVirtual && x.PropertyType.IsGenericType == true);
return props;
}
public static bool HasAnyRelation(object entityObj)
{
var collectionProps= GetManyRelatedEntityNavigatorProperties(entityObj);
foreach (var item in collectionProps)
{
var collectionValue = GetEntityFieldValue(entityObj,item.Name);
if (collectionValue != null && collectionValue is IEnumerable)
{
var col = collectionValue as IEnumerable;
if (col.GetEnumerator().MoveNext())
{
return true;
}
}
}
return false;
}
注意:上下文不得处置,并且必须启用代理 并且知道它将获得所有相关的记录记录(它太重了)
答案 3 :(得分:-1)
首先使用Find中的Find查找要删除的实体,并将实体传递给下面的函数。如果函数返回true,则表示无法删除并且存在外来数据。如果函数返回false,则表示没有父项或子记录,可以删除..
public static bool DeleteCheckOnEntity(object entity)
{
var propertiesList = entity.GetType().GetProperties();
return (from prop in propertiesList where prop.PropertyType.IsGenericType select prop.GetValue(entity) into propValue select propValue as IList).All(propList => propList == null || propList.Count <= 0);
}