简体   繁体   English

在实体框架中检查相关实体的通用方法

[英]Generic way for checking related entities count in Entity Framework

Currently I am using this code: 目前我正在使用此代码:

opportunity.Contacts.Where(x => x.IsDeleted = false).IsNullOrEmpty()

in each entity to check if any collection exists in the entity (example Opportunity ). 在每个实体中检查实体中是否存在任何集合(例如Opportunity )。

public bool Delete(int companyId, int opportunityId)
{
    var opportunity = _opportunityRepository.FindOne(companyId: companyId, opportunityId: opportunityId).FirstOrDefault();

    if (!opportunity.Contacts.Where(x => x.IsDeleted = false).IsNullOrEmpty())
    {
        throw new UserFriendlyException(ErrorMessages.UserFriendly.UnableToDeleteEntityHasRelatedData);
    }

    opportunity.IsDeleted = true;
    _opportunityRepository.Edit(opportunity); 
    CurrentUnitOfWork.Commit();

    return true;
}

This method is repetitive and time consuming to put in hundreds of places. 这种方法在数百个地方放置是重复且耗时的。

How can we make it a generic function which can check entity type and use reflection or another way to check all its properties which implement ICollection<T> and execute query to check their count? 我们怎样才能使它成为一个泛型函数,可以检查实体类型并使用反射或其他方法来检查实现ICollection<T>所有属性并执行查询来检查它们的计数?

[ForeignKey("DepartmentId")]
public virtual ICollection<DepartmentLocation> DepartmentLocations { get; set; }
[ForeignKey("DepartmentId")]
public virtual ICollection<EmployeePosition> EmployeePositions { get; set; }

Even if you did want to go through and resolve collections by reflection to perform a check like this, I would not recommend it. 即使您确实希望通过反射来解决集合以执行这样的检查,我也不会推荐它。 The problem domain you are looking at looks like that you want to enforce business logic around soft deletion that essentially says "I can only be marked as deleted if all of my children are first marked as deleted." 您正在查看的问题域看起来像是要围绕软删除实施业务逻辑,本质上说“如果我的所有孩子都被标记为已删除,我只能被标记为已删除”。 The issues you would quickly face with trying to do this through reflection include: 通过反思尝试执行此操作时您将很快遇到的问题包括:

  • Hits to Lazy Loading 点击延迟加载
  • Complex and slow code to inspect every object on delete. 复杂和慢速代码检查删除时的每个对象。

The lazy loading risk and trying to escape it would be my first warning of dragons. 懒惰的装载风险和试图逃脱它将是我对龙的第一次警告。 I'd be looking at leveraging IQueryable from the repository rather than returning a single domain object. 我将考虑从存储库中利用IQueryable而不是返回单个域对象。 From there you have the flexibility to drill down into your model to determine if an object has any active children: 从那里,您可以灵活地深入到模型中,以确定对象是否有任何活动子项:

var activeState = _opportunityRepository.GetById(companyId, opportunityId) // return IQueryable<Opportunity>
    .Select(o=> new {o.IsDeleted, HasActiveContact = o.Contacts.Any(c=> !c.IsDeleted)})
    .SingleOrDefault();

From there you can check properties on the anon. 从那里你可以检查anon上的属性。 type. 类型。 The query sent to the server should remain pretty optimal in terms of performance with a single hit and the code is a simple, extendable structure that you can expand upon easily without worrying about lazy loads and such. 发送到服务器的查询在性能方面应该保持最佳,只需一次点击,代码是一个简单,可扩展的结构,您可以轻松扩展,而不必担心延迟加载等。 You can expand it to return active children for instance if you want to extend a message about which children are still active to deal with before marking the parent as deleted. 例如,如果要在将父项标记为已删除之前扩展有关哪些子项仍处于活动状态以处理的消息,则可以将其展开以返回活动子项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM