【问题标题】:Linq query with list of flags带有标志列表的 Linq 查询
【发布时间】:2015-05-28 12:01:33
【问题描述】:

我正在尝试使用 Linq 查询从数据库中获取记录列表。

public void Main() {
    var filter = new Filter();
    filter.ReceiverState = new List<DocumentState> { DocumentState.Completed };
    var q = from d in Documents
            where filter.ReceiverState.Any(f => (d.ReceiverState & (int)f) != 0)
            select d;
    q.Dump();
}

public class Filter {
    public List<DocumentState> ReceiverState { get; set; }
}

[Flags]
public enum DocumentState {
    Sent = 1,
    NeedClarification = 2,
    Completed = 4,
    NeedResign = 8
}

但我收到此错误:

本地序列不能在查询运算符的 LINQ to SQL 实现中使用,但 Contains 运算符除外

我必须在过滤器中使用标记枚举列表。如何进行正确的 Linq 查询?

【问题讨论】:

  • 请格式化您的代码。
  • 您的查询有一些异味,1 您初始化过滤器和 filter.ReceiverState,但是在您的 linq 中您检查过滤器是否为空或 filter.ReceiverState 是否包含完成状态,该状态将始终为真.

标签: c# linq list enums flags


【解决方案1】:

这应该可行,

var filter = new Filter();
filter.ReceiverStates = new List<DocumentState> { DocumentState.Completed };
var documents = new List<Document>();
var result = documents.Where(d => filter.ReceiverStates.Contains(d.ReceiverState));

【讨论】:

  • 如果枚举没有 Flags 属性,这将起作用。
【解决方案2】:

您正在传递一个序列 (ReceiverState) 以将其与文档进行比较,linq to sql 不能以这种方式工作,您可以做的是传递一个值来比较,或者以其他方式获取文档和将它们与您的列表 (ReceiverState) 进行比较

我不确定你为什么在这里使用列表,我看到你只是在寻找标记为已完成的文档。

(没有尝试过任何代码,但我知道该方法会像我以前使用的那样有效)

var q = from d in Documents
        where (DocumentState)d.ReceiverState & DocumentState.Completed == DocumentState.Completed
        select d;

但是如果您需要使用列表作为过滤器,您可以尝试这个(对于大量记录来说不是最好的方法)但它会起作用,因为在您开始在文档中循环的那一刻,它不是 linq to sql 了,基本上你一次比较一个值。

var docs = from d in Documents select d;
foreach(var f in filter.ReceiverState)
{
   docs = docs.Where(x => (DocumentState)x.ReceiverState & f == f)
}

【讨论】:

  • 除了一些缺少的括号外,这是正确的答案。
猜你喜欢
  • 2015-08-28
  • 1970-01-01
  • 2013-06-30
  • 1970-01-01
  • 2020-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多