LINQ2SQL:将谓词传递给子查询中的.Count(Func <t>,bool)</t>

时间:2010-12-22 10:17:37

标签: .net linq-to-sql

我对linq2sql中的谓词有疑问。我想要做的是将条件分成静态类,然后在我的查询中使用它们。我创建了一个带有一些函数的静态类:

public static class CountingFilters
    {
        public static  Func<CountingItem, bool> TotalItemsPredicate
            = ci =>
                      !ci.Deleted && ci.OdinProduct != null &&
                      ((ci.OdinProduct.NotOriginal == null && !ci.OdinProduct.Deleted)
                       || ((ci.OdinProduct.NotOriginal == ci.OdinProduct.GUID) && ci.OdinProduct.Deleted))
                      && (!ci.OdinProduct.Temp);

        public static  Func<CountingItem, bool> AlreadyCountedPredicate
            = ci =>
                TotalItemsPredicate(ci) && ci.CountedAmount.HasValue;
     }

如果我像这样使用它:

var count = CountingFacade.GetCountingItems().Count(CountingFilters.TotalItemsPredicate);

一切正常,我得到的结果。 但是当我尝试创建绑定到gridview的投影时,像这样:

var result = from f in countinglist
   let alreadyCounted = f.CountingItems.Count(CountingFilters.AlreadyCountedPredicate)
   let total = f.CountingItems.Count(CountingFilters.TotalItemsPredicate)
   select new CountingProjection
   {
          AlreadyCountedProducts = alreadyCounted,
          Description = f.Description,
          NumberOfProducts = total,
          PlannedDate = f.PlannedDate.Value,
          Site = f.Site,
          Status = f.Status,
          Type = f.Type,
          GUID = f.GUID,

   };

抛出异常“用于查询运算符'Count'的不支持的重载。”出于某种原因,据我所知,我的谓词没有被翻译成SQL ...有谁能告诉我,我做错了什么?提前谢谢。

2 个答案:

答案 0 :(得分:1)

您通常需要返回Expression&lt; FUNC&LT;&GT;&GT;将它们翻译成SQL。

查看predicate builder

this值得一看

答案 1 :(得分:1)

另一种方法是使用Extension方法。如果您不想深入了解Expression等,它将为您节省大量时间。您的代码将如下所示:

public static class CountingFilters
{
     public static int TotalItems(this IEnumerable<CountingItem> source)
     {
         return source.Count(ci => !ci.Deleted && ci.OdinProduct != null &&
                          ((ci.OdinProduct.NotOriginal == null && !ci.OdinProduct.Deleted)
                           || ((ci.OdinProduct.NotOriginal == ci.OdinProduct.GUID) && ci.OdinProduct.Deleted))
                          && (!ci.OdinProduct.Temp));
     }

     public static int AlreadyCounted(this IEnumerable<CountingItem> source)
     {
         return source.Count(ci => !ci.Deleted && ci.OdinProduct != null &&
                          ((ci.OdinProduct.NotOriginal == null && !ci.OdinProduct.Deleted)
                           || ((ci.OdinProduct.NotOriginal == ci.OdinProduct.GUID) && ci.OdinProduct.Deleted))
                          && (!ci.OdinProduct.Temp) && ci.CountedAmount.HasValue);
     }
}

    var result = from f in countinglist
       let alreadyCounted = f.CountingItems.AlreadyCounted()
       let total = f.CountingItems.TotalItems()
       select new CountingProjection
       {
              AlreadyCountedProducts = alreadyCounted,
              Description = f.Description,
              NumberOfProducts = total,
              PlannedDate = f.PlannedDate.Value,
              Site = f.Site,
              Status = f.Status,
              Type = f.Type,
              GUID = f.GUID,

       };