繁体   English   中英

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

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

目前我正在使用此代码:

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

在每个实体中检查实体中是否存在任何集合(例如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;
}

这种方法在数百个地方放置是重复且耗时的。

我们怎样才能使它成为一个泛型函数,可以检查实体类型并使用反射或其他方法来检查实现ICollection<T>所有属性并执行查询来检查它们的计数?

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

即使您确实希望通过反射来解决集合以执行这样的检查,我也不会推荐它。 您正在查看的问题域看起来像是要围绕软删除实施业务逻辑,本质上说“如果我的所有孩子都被标记为已删除,我只能被标记为已删除”。 通过反思尝试执行此操作时您将很快遇到的问题包括:

  • 点击延迟加载
  • 复杂和慢速代码检查删除时的每个对象。

懒惰的装载风险和试图逃脱它将是我对龙的第一次警告。 我将考虑从存储库中利用IQueryable而不是返回单个域对象。 从那里,您可以灵活地深入到模型中,以确定对象是否有任何活动子项:

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

从那里你可以检查anon上的属性。 类型。 发送到服务器的查询在性能方面应该保持最佳,只需一次点击,代码是一个简单,可扩展的结构,您可以轻松扩展,而不必担心延迟加载等。 例如,如果要在将父项标记为已删除之前扩展有关哪些子项仍处于活动状态以处理的消息,则可以将其展开以返回活动子项。

暂无
暂无

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

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