检查实体是否具有 Code First 中的依赖项
Check if entity has dependencies in Code First
我试图在允许删除之前检查我的实体是否有任何依赖项:
通常我们可以通过以下方式为每个实体类型执行此操作:
public class Company{
public int id;
public string name;
public virtual IList<Department> Departments { get; set; }
public virtual IList<Building> Buildings {get;set;}
public bool hasDependencies => Departments.Any() || Buildings.Any();
}
但我想对实体可能具有的任何导航属性进行一般性处理
注意:已启用延迟加载。
public bool HasDependencies()
{
int ExampleEntityId = 2; // just example
Company companyEntity = _unitofwork.CompanyRepository.GetEntityById(ExampleEntityId);
IEnumerable<PropertyInfo> propertyInfoList = _unitofwork.CompanyRepository.GetNavigationProperties();
bool dependenciesExist = false;
foreach (PropertyInfo property in propertyInfoList)
{
dependenciesExist = companyEntity.**property**.Any(); //This obviously doesn't work, but just to convey the intent.
if (dependenciesExist) {
break;
};
}
return dependenciesExist;
}
这是 GetNavigationProperties 方法:
public IEnumerable<PropertyInfo> GetNavigationProperties()
{
var modelData = _context.Model.GetEntityTypes(typeof(TEntity)).ToList()[0];
var propertyInfoData = modelData.GetNavigations().Select(x => x.PropertyInfo);
return propertyInfoData;
}
我查看了很多页面,包括以下内容以弄清楚这一点:
EF5 How to get list of navigation properties for a domain object
Check if entity has references in other entities in Code First
如果您依赖具有加载导航(惰性、急切或显式)的物化实体实例,您可以轻松模拟对集合的 Any
检查,因为它们都可以转换为 IEnumerable<object>
,例如
dependenciesExist = property.GetValue(entity) is IEnumerable<object> collection
&& collection.Any();
但请注意 GetNavigations()
API 不会 return 跳过导航(即 EF Core 5.0 通过隐式连接实体引入 many-to-many)- 这些是 return 由 GetSkipNavigations()
API 编辑。同时GetNavigations()
returns bot collection和reference navigations,所以如果你需要过滤掉它们,或者单独处理它们,你最好return EF Core元数据对象而不是反射部分。例如
var entityType = _context.Model.FindEntityType(typeof(TEntity));
var collectionNavigations = entityType.GetNavigations()
.Where(nav => nav.IsCollection)
.Concat<INavigationBase>(entityType.GetSkipNavigations());
var referenceNavigations = entityType.GetNavigations()
.Where(nav => !nav.IsOnDependent);
对于参考导航,您只需执行 null
检查
dependenciesExist = property.GetValue(entity) != null
对于集合(跳过 many-to-may 或常规 one-to-many)执行 IEnumerable<object>
检查,如开头所示。
我试图在允许删除之前检查我的实体是否有任何依赖项:
通常我们可以通过以下方式为每个实体类型执行此操作:
public class Company{
public int id;
public string name;
public virtual IList<Department> Departments { get; set; }
public virtual IList<Building> Buildings {get;set;}
public bool hasDependencies => Departments.Any() || Buildings.Any();
}
但我想对实体可能具有的任何导航属性进行一般性处理
注意:已启用延迟加载。
public bool HasDependencies()
{
int ExampleEntityId = 2; // just example
Company companyEntity = _unitofwork.CompanyRepository.GetEntityById(ExampleEntityId);
IEnumerable<PropertyInfo> propertyInfoList = _unitofwork.CompanyRepository.GetNavigationProperties();
bool dependenciesExist = false;
foreach (PropertyInfo property in propertyInfoList)
{
dependenciesExist = companyEntity.**property**.Any(); //This obviously doesn't work, but just to convey the intent.
if (dependenciesExist) {
break;
};
}
return dependenciesExist;
}
这是 GetNavigationProperties 方法:
public IEnumerable<PropertyInfo> GetNavigationProperties()
{
var modelData = _context.Model.GetEntityTypes(typeof(TEntity)).ToList()[0];
var propertyInfoData = modelData.GetNavigations().Select(x => x.PropertyInfo);
return propertyInfoData;
}
我查看了很多页面,包括以下内容以弄清楚这一点:
EF5 How to get list of navigation properties for a domain object
Check if entity has references in other entities in Code First
如果您依赖具有加载导航(惰性、急切或显式)的物化实体实例,您可以轻松模拟对集合的 Any
检查,因为它们都可以转换为 IEnumerable<object>
,例如
dependenciesExist = property.GetValue(entity) is IEnumerable<object> collection
&& collection.Any();
但请注意 GetNavigations()
API 不会 return 跳过导航(即 EF Core 5.0 通过隐式连接实体引入 many-to-many)- 这些是 return 由 GetSkipNavigations()
API 编辑。同时GetNavigations()
returns bot collection和reference navigations,所以如果你需要过滤掉它们,或者单独处理它们,你最好return EF Core元数据对象而不是反射部分。例如
var entityType = _context.Model.FindEntityType(typeof(TEntity));
var collectionNavigations = entityType.GetNavigations()
.Where(nav => nav.IsCollection)
.Concat<INavigationBase>(entityType.GetSkipNavigations());
var referenceNavigations = entityType.GetNavigations()
.Where(nav => !nav.IsOnDependent);
对于参考导航,您只需执行 null
检查
dependenciesExist = property.GetValue(entity) != null
对于集合(跳过 many-to-may 或常规 one-to-many)执行 IEnumerable<object>
检查,如开头所示。