2013-10-10 55 views
4

爲了我的天真而提前道歉。在LINQ查詢中對基類使用擴展方法

我正在使用實體框架來堅持我在域模型中定義的實體。我的域模型實體都從我的EntityBase類繼承。這有我希望成爲共同我所有的實體屬性:

public class EntityBase 
{ 
    public string CreatedBy { get; set; } 
    public DateTime? Created { get; set; } 

    public int ModifiedBy { get; set; } 
    public DateTime? Modified { get; set; } 

    public bool Enabled { get; set; } 
    public bool Deleted { get; set; } 
} 

現在,當我想用​​LINQ這將是很好查詢EF如果我沒有包括的元素,以檢查是否在特定的實體啓用或刪除。每個查詢都將涉及代碼,例如:

var messages = _db.Memberships.Where(m => m.UserId.Equals(userId)) 
           .SelectMany(m => m.Group.Messages) 
           .Include(m => m.Group.Category) 
           .Select(m => m.Enabled && !m.Deleted) 
           .ToList(); 

而不是這樣的,每次做,我想我會寫這將作用於IQueryable的

public static IQueryable<EntityBase> Active(this IQueryable<EntityBase> entityCollection) 
    { 
     return entityCollection.Where(e => e.Enabled && !e.Deleted); 
    } 

在我天真的話,我想我的擴展方法可以只包括這在任何LINQ查詢將返回我的實體從EntityBase類繼承 - 就像這樣:

var messages = _db.Memberships.Where(m => m.UserId.Equals(userId)) 
      .SelectMany(m => m.Group.Messages) 
      .Include(m => m.Group.Category) 
      .Active() <============================= Extension Methd 
      .ToList(); 

     return Mapper.Map<List<Message>,List<MessageDto>>(messages); 

然而,編譯器現在抱怨:

Error 2 Argument 1: cannot convert from 
      'System.Collections.Generic.List<Diffusr.Business.Entities.EntityBase>' to 
      'System.Collections.Generic.List<Diffusr.Business.Entities.Message>' 

問題:我能實現我想達到的目標,即我的所有實體僅返回啓用,不會被刪除的常用方法?如果是這樣,怎麼樣?

+0

您的錯誤不在查詢中,它在返回點。將鼠標懸停在'messages'的'var'上,看看這個類型是否符合你的期望。 – AakashM

+0

使用.NET 3.5我敢打賭? –

回答

3

而不是指定一個具體的類,使用泛型,因爲大多數擴展方法做:

public static IQueryable<T> Active<T>(this IQueryable<T> entityCollection) where T:EntityBase 
{ 
    return entityCollection.Where(e => e.Enabled && !e.Deleted); 
} 

我假設你正在使用某些版本的.NET早於4.0。在4.0之前不允許使用Generic covariance(即,當期望基類型的可枚舉類型時傳遞子類型的枚舉)。

即使在4.0之後,使用協變並不是絕對的好主意,因爲編譯器最終會做很多額外的檢查來確保類型安全,只要您嘗試將一些新值存儲到列表中。 Jon Skeet有一個nice article about this

+0

非常感謝您的理解。但是,當我嘗試使用通用版本IQueryable 時,Visual Studio只是不斷地抱怨它無法解析。我錯過了什麼 - 感覺很愚蠢!順便說一下,該項目是一個面向.NET 4.5的類庫?非常感謝任何幫助。 – jcaddy

+0

代碼和錯誤在哪裏? –

+0

Ooops,從聲明中丟失 –

3

可以通過更改擴展方法:

public static IQueryable<T> Active(this IQueryable<T> entityCollection) 
    where T : EntityBase 
{ 
    return entityCollection.Where(e => e.Enabled && !e.Deleted); 
}