目前我正在使用此代码:
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; }
答案 0 :(得分:0)
即使您确实希望通过反射来解决集合以执行这样的检查,我也不会推荐它。您正在查看的问题域看起来像是要强制执行围绕软删除的业务逻辑,基本上说是&#34;如果我的所有孩子都被标记为已删除,我只能被标记为已删除。&#34;试图通过反思来解决这个问题时会遇到的问题包括:
懒惰的装载风险并试图逃脱它将是我对龙的第一次警告。我正在考虑从存储库中利用IQueryable而不是返回单个域对象。从那里,您可以灵活地深入到模型中,以确定对象是否有任何活动子项:
var activeState = _opportunityRepository.GetById(companyId, opportunityId) // return IQueryable<Opportunity>
.Select(o=> new {o.IsDeleted, HasActiveContact = o.Contacts.Any(c=> !c.IsDeleted)})
.SingleOrDefault();
从那里你可以检查anon上的属性。类型。发送到服务器的查询在性能方面应该保持最佳,只需一次点击,代码是一个简单,可扩展的结构,您可以轻松扩展,而不必担心延迟加载等。例如,如果要在将父项标记为已删除之前扩展有关哪些子项仍处于活动状态以处理的消息,则可以将其展开以返回活动子项。