2009-09-15 80 views
4

我有一個[國旗]枚舉是這樣的:如何在Linq中將標誌枚舉用於實體查詢?

[Flags] 
public enum Status 
{ 
    None = 0, 
    Active = 1, 
    Inactive = 2, 
    Unknown = 4 
} 

A狀態枚舉可以包含兩個值,如:

Status s = Status.Active | Status.Unknown; 

現在我需要創建一個LINQ查詢(LINQ到ADO.NET實體)並要求記錄的狀態是以上,即活動或未知;

var result = from r in db.Records 
      select r 
      where (r.Status & (byte)s) == r.Status 

當然,我得到一個錯誤,因爲LINQ to Entities只知道處理Where子句中的基本類型。

錯誤是:

無法創建 類型「閉合類型」的恆定值。在此上下文中僅支持原始 類型(如Int32,String和 Guid)。

有沒有可行的方法?我可能有一個狀態枚舉有10個可能的值,並查詢5個狀態。如何以優雅的方式使用Flags枚舉構造查詢?

謝謝。

更新

這似乎是一個LINQ到實體問題。我認爲在LINQ to SQL中起作用(不確定,沒有測試過)。

+0

你查詢(如果它的工作)只會返回狀態是同時'活動'*和*'未知'的記錄。那是你要的嗎? – LukeH 2009-09-15 11:40:07

+0

不,這是一個或不是一個。所以'Status s = Status.Active | Status.Unknown;」是正確的。謝謝! – 2009-09-15 11:42:30

+0

@Vasi:該部分是正確的,但「Status.Active | Status.Unknown'」相當於「'1 | 4'」,它是'5'。因此,你的'where'子句有效地說「where(r.Status&5)== r.Status'」,這與「r.Status == 5'相同」,這與說(英文)「,其中'r.Status'既是'Active' *又是'Unknown'」! – LukeH 2009-09-15 11:50:06

回答

0

我不知道EF,但可以插入額外的演員工作?

var result = from r in db.Records 
      where ((byte)r.Status & (byte)s) == (byte)r.Status 
      select r 
+0

r。狀態已經是字節了,我還在te問題中添加了演員。 這不是問題,問題是它不會運行。它編譯但不運行。看到問題中的錯誤。 – 2009-09-15 11:38:26

0

試試這樣說:

byte status = (byte)(Status.Active | Status.Unknown); 

var result = from r in db.Records 
      select r 
      where (r.Status & status) != 0 
+0

我認爲Where中的評估不能轉換爲esql或類似的東西。這就是爲什麼我得到以下例外的原因: 「無法創建類型爲'閉包類型'的常量值。在此上下文中僅支持基本類型(如Int32,String和Guid)。 – 2009-09-15 11:40:40

+0

@Vasi:是的,但是您的版本中有錯誤嗎? – LukeH 2009-09-15 12:04:19

+0

我有同樣的錯誤。 – 2009-09-15 12:30:26

1
var result = from r in db.Records 
      where r.Status == s 
      select r 
0

我不能確定,如果按位與運算的工作,但盡力鑄造s到一個int:

 int i = (int)s; 
     var result = from r in db.Records 
      select r 
      where (r.Status & i) == r.Status 

哪數據庫引擎你使用?可能該引擎不支持按位操作。

參考:http://www.matthidinger.com/archive/2008/02/26/entity-framework-comparison-frustration-explained.aspx

+0

通過MS SQL Server使用LINQ to Entities。 – 2009-09-15 12:25:51

+0

這不是鑄造問題。 – 2009-09-15 12:28:23

+0

不,這是一個問題,它不能將枚舉的結果轉換爲原生SQL類型。因此使用整數比較可能會奏效。 – 2009-09-15 12:39:08

0

的folloiwng在C#中對我的作品

public const StatusTypes ActiveAlert = StatusTypes.Accepted | StatusTypes.Delivered; 

     int flags = (int)ActiveAlert; 

     try 
     { 
      var query = from p in model.AlertsHistory 
         where (p.UserId == clientId 
         && (p.Status.HasValue && (p.Status.Value & flags) != 0)) 
         select p; 
      var aList = query.ToList(); 

      return (aList); 


     } 
     catch (Exception exc) 
     { 
      log.Error("Exception getting Alerts History for user.", exc); 
      throw; 
     } 
3

只需使用HasFlag()

var result = from r in db.Records 
     where r.Status.HasFlag(s) 
     select r 
0

在DB標誌枚舉必須是整數。之後,你可以嘗試這樣:

Status s = Status.Active | Status.Unknown; 

var result = from r in db.Records 
where (s & r.Status) == r.Status 
select r