2010-03-28 22 views
6

根据需要跳到“具体问题”。一些背景:如何将此Linq SQL作为动态查询(使用字符串)?

该场景:我有一组产品具有填充DDL的“向下钻取”过滤器(查询对象)。每个渐进DDL选择将进一步限制产品列表以及为DDL保留哪些选项。例如,从工具中选择一个锤子将产品尺寸限制为仅显示锤子尺寸。

当前设置:我创建了一个查询对象,将它发送到一个存储库,并将每个选项提供给一个SQL“表值函数”,其中空值表示“获取所有产品”。

我认为这是一个很好的努力,但远没有DDD可以接受。我想避免SQL中的任何“编程”,希望可以通过一个存储库来完成所有任务。对此主题的评论将不胜感激。

具体问题:

我将如何改写这个查询作为Dynamic Query?一个类似于101 Linq Examples的链接将会非常棒,但是具有动态查询范围。我真的想传递给这个方法的领域在引号“”我想要一个选项列表和有多少产品有这个选项。

from p in db.Products 
group p by p.ProductSize into g 
select new Category { 
     PropertyType = g.Key, 
     Count = g.Count() } 

每个DDL选项将具有“选择(21)”,其中(21)是具有该属性的产品的数量。选择一个选项后,所有其他剩余的DDL将随其余选项和计数一起更新。

编辑:其他注意事项:

.OrderBy("it.City") // "it" refers to the entire record 
.GroupBy("City", "new(City)") // This produces a unique list of City 
.Select("it.Count()") //This gives a list of counts... getting closer 
.Select("key") // Selects a list of unique City 
.Select("new (key, count() as string)") // +1 to me LOL. key is a row of group 
.GroupBy("new (City, Manufacturer)", "City") // New = list of fields to group by 
.GroupBy("City", "new (Manufacturer, Size)") // Second parameter is a projection 

Product 
.Where("ProductType == @0", "Maps") 
.GroupBy("new(City)", "new (null as string)")// Projection not available later? 
.Select("new (key.City, it.count() as string)")// GroupBy new makes key an object 

Product 
.Where("ProductType == @0", "Maps") 
.GroupBy("new(City)", "new (null as string)")// Projection not available later? 
.Select("new (key.City, it as object)")// the it object is the result of GroupBy 

var a = Product 
     .Where("ProductType == @0", "Maps") 
     .GroupBy("@0", "it", "City") // This fails to group Product at all 
     .Select("new (Key, it as Product)"); // "it" is property cast though 

我已经学会为止是LinqPad是太棒了,但仍然在寻找一个答案。最终,我猜想这样的完全随机研究将占上风。大声笑。

编辑:

乔恩斯基特有一个奇妙的想法:投什么,我需要为IGrouping<string, Product>。感谢Jon Skeet!一旦你投射了这个物体,你可以枚举这些物体并将结果输入到一个单独的List中。

+0

你需要一个整体动态查询?是不是你的过滤标准(Where子句)是唯一的动态方面? – Gabe 2010-03-29 06:29:20

+0

我相信我需要一个完整的DQ。如果没有为他们想要过滤的每个字段重复此代码,我需要将GroupBy字段指定为字符串。 – 2010-03-29 06:45:43

+0

仅当您返回'it'时,才能将其转换为IGrouping 。当你使用.Select(“新(键,它作为产品,计数()作为计数)”)如何投这个? – 2012-11-01 14:04:30

回答

4

我不知道如何做到这一点使用的查询语法(如上),但使用方法的语法,我们可以使用表达式< Func键<,如下图所示。此示例工程对AdventureWorks的SQL Server数据库(产品表),并允许您使用字符串来指定哪些列组(在此示例中,我选择尺寸)

using System; 
using System.Linq; 
using System.Linq.Expressions; 

namespace LinqResearch 
{ 
    public class Program 
    { 
     [STAThread] 
     static void Main() 
     { 
      string columnToGroupBy = "Size"; 

      // generate the dynamic Expression<Func<Product, string>> 
      ParameterExpression p = Expression.Parameter(typeof(Product), "p"); 

      var selector = Expression.Lambda<Func<Product, string>>(
       Expression.Property(p, columnToGroupBy), 
       p 
      ); 

      using (LinqDataContext dataContext = new LinqDataContext()) 
      { 
       /* using "selector" caluclated above which is automatically 
       compiled when the query runs */ 
       var results = dataContext 
        .Products 
        .GroupBy(selector) 
        .Select((group) => new { 
         Key = group.Key, 
         Count = group.Count() 
        }); 

       foreach(var result in results) 
        Console.WriteLine("{0}: {1}", result.Key, result.Count); 
      } 

      Console.ReadKey(); 
     } 
    } 
} 
1

如果你看一看C# Bits,论述了如何使用动态数据来创建级联滤波器。这听起来不像你使用动态数据,但他确实有一个很好的表达式生成器,可能对你有帮助。请参阅BuildQueryBody,然后查看Iqueryable上扩展方法的以下部分。由于您没有使用动态数据,您将需要处理无法访问“MetaForeignKeyColumn”对象,但我怀疑他的方法可能会帮助您解决您的问题。

我希望这会有所帮助。