检查实体是否具有 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> 检查,如开头所示。