Ben*_*nC3 11 .net c# asp.net-mvc entity-framework entity-framework-4
我有一个实体,我们称它为CommonEntity
主键,在许多其他实体中用作外键.随着应用程序的开发,这些链接将继续增长.
我想要一种方法来查看是否CommonEntity
可以安全删除(即它没有被任何其他实体使用).
我意识到我能做到
if(!ce.EntityA.Any() && !ce.EntityB.Any() ... && !ce.EntityN.Any())
{
//Delete
}
Run Code Online (Sandbox Code Playgroud)
但是我希望能够自动检查所有关系,因为我不喜欢每次添加新关系时都必须手动更改此代码.也许EF4 +中有一些我不知道的东西?
我认为有可能使用事务范围来尝试删除对象并在它失败时将其回滚,但我不确定这种方法是否存在任何不良副作用.
有更好的方法吗?
编辑:看起来VS2012使用EF5即使项目是.Net 4,所以它创建了POCO模型,即使它是从数据库生成的.
y34*_*34h 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
}
}
Run Code Online (Sandbox Code Playgroud)
小智 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
}
Run Code Online (Sandbox Code Playgroud)
您可以为此使用反射(如果您不想使用“SQL 删除失败”)我写这个是因为我不想删除实体,只想知道它是否与任何实体相关!
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;
}
Run Code Online (Sandbox Code Playgroud)
请注意:上下文不能被处置,代理必须被启用,并且知道它将获得所有相关的记录到内存(它太重了)
归档时间: |
|
查看次数: |
11837 次 |
最近记录: |