将linq查询构建为函数

时间:2012-02-17 14:51:12

标签: c# linq

var query = (from material in dataContext.Materials
             join materialCategories in dataContext.MaterialCategories on material.Id equals
             materialCategories.Material.Id
             select new
                    {
                        material.Id,
                        material.Name,
                        material.Taken,
                        materialCategories.CategoryName
                    });
//Filter by date
query = query.Where(x => x.Taken >= minDate && x.Taken <= maxDate);

我想提取“query.Where(x =&gt; x.Taken&gt; = minDate&amp;&amp; x.Taken&lt; = maxDate);”到一个返回查询的函数,但问题是该函数不理解x.Taken是什么。

我如何实现这一目标?

6 个答案:

答案 0 :(得分:3)

您需要使用命名类型而不是未命名的类型。 创建一个新课程:

public class Category
{
    int Id;
    string Name;
    DateTime Taken;
    string CategoryName;
}

如果需要,您可以将字段设为属性。

然后代替:

select new {...}

使用你的班级:

select new Category {...}

之后你就可以拥有这个:

private IQueryable<Category> FilterFunction(IQueryable<Category> query)
{
    query = query.Where(x => x.Taken >= minDate && x.Taken <= maxDate);
    return query;
}

或使用IEnumerable&lt;&gt;取决于你在这里做了什么。

答案 1 :(得分:1)

你需要将你的对象提升为一个真正的类型,而不是一个类型,然后你可以做:

 private static Func<YourObject, bool> Predicate(DateTime minDate, DateTime maxDate)
        {
            return x => x.Taken >= minDate && x.Taken <= maxDate;
        }

答案 2 :(得分:0)

您无法将匿名对象传递给方法。您必须创建一个类型并从第一个查询返回该类型的新实例。

答案 3 :(得分:0)

泛型将为您完成所有这些。

public IQueryable<T> betweenDates<T>(IQueryable<T> query, DateTime maxdate, DateTime mindate) where T : YourClass
{
  return query.Where(x => x.Taken >= minDate && x.Taken <= maxDate);
}

答案 4 :(得分:0)

你不能用匿名对象来做这件事,而不是一些带有反射的hackery。我会创建一个具有这些属性的类,并从函数返回IENumerable。

答案 5 :(得分:-1)

你真的不想这样做。使用LINQ语法保留查询可以让框架优化数据查询。如果将其拉出到函数中,则必须从数据库返回所有数据,然后在客户端进行过滤。呸!有关更多信息,请参阅“为什么将LINQ转换为SQL查询表达式转换为表达式树?”在http://blogs.msdn.com/b/charlie/archive/2008/01/31/expression-tree-basics.aspx