2017-06-18 89 views
1

算目前我使用此代碼:通用的方法在實體框架

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; } 
+1

爲什麼不啓用級聯刪除的關係? – haim770

+0

或者如果不需要級聯,則禁用級聯...刪除級聯的默認級別取決於所需的關係或可選... – grek40

回答

0

即使您確實想通過反射來解決集合來執行像這樣的檢查,我也不會推薦它。您正在查看的問題域看起來像要強制執行軟刪除的業務邏輯,基本上說「如果我的所有子項都被標記爲已刪除,我只能標記爲已刪除」。你會很快與試圖通過反射來做到這一點面臨的問題包括:

  • 巨片延遲加載
  • 複雜和緩慢的代碼檢查上刪除每個對象。

懶惰的加載風險,並試圖逃脫它將是我第一次警告龍。我會考慮利用存儲庫中的IQueryable,而不是返回一個域對象。從那裏,你可以靈活地深入到你的模型,以確定是否一個對象有任何積極的孩子:

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

從那裏你可以檢查匿名性。類型。發送到服務器的查詢在單次點擊時性能方面應該保持最佳狀態,代碼是一個簡單的可擴展結構,您可以輕鬆擴展,而不用擔心延遲加載等問題。例如,如果要在將父項標記爲已刪除之前擴展有關哪些子項仍處於活動狀態的消息,則可以將其展開爲返回活動子項。