2010-03-28 32 views
6

Chuyển đến "câu hỏi cụ thể" nếu cần. Một số nền:Làm thế nào để viết LINQ SQL này như là một truy vấn động (sử dụng chuỗi)?

Kịch bản: Tôi có một bộ sản phẩm có bộ lọc "khoan xuống" (Đối tượng truy vấn) được điền bằng DDL. Mỗi lựa chọn DDL tiến bộ sẽ tiếp tục giới hạn danh sách sản phẩm cũng như các tùy chọn còn lại cho các DDL. Ví dụ, chọn một búa ra khỏi các công cụ giới hạn Kích thước sản phẩm để chỉ hiển thị kích thước búa.

Thiết lập hiện tại: Tôi đã tạo đối tượng truy vấn, gửi nó tới kho lưu trữ và cho mỗi tùy chọn vào hàm "giá trị bảng" của SQL trong đó giá trị null đại diện cho "nhận tất cả sản phẩm".

Tôi xem đây là một nỗ lực tốt, nhưng xa DDD có thể chấp nhận được. Tôi muốn tránh bất kỳ "lập trình" trong SQL, hy vọng làm tất cả mọi thứ với một kho lưu trữ. Nhận xét về chủ đề này sẽ được đánh giá cao.

câu hỏi cụ thể:

Làm thế nào tôi sẽ viết lại truy vấn này như một Dynamic Query? Một liên kết đến một cái gì đó như 101 Linq Examples sẽ là tuyệt vời, nhưng với một phạm vi truy vấn động. Tôi thực sự muốn chuyển sang phương thức này trường trong dấu ngoặc kép "" mà tôi muốn danh sách các tùy chọn và số lượng sản phẩm có tùy chọn đó.

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

Mỗi tùy chọn DDL sẽ có "Lựa chọn (21)" trong đó (21) là số lượng sản phẩm có thuộc tính đó. Khi chọn một tùy chọn, tất cả các DDL còn lại sẽ cập nhật với các tùy chọn và số lượng còn lại.

Edit: Ghi chú thêm:

.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 

Những gì tôi đã học được cho đến nay là LinqPad là tuyệt vời, nhưng vẫn đang tìm kiếm một câu trả lời. Cuối cùng, nghiên cứu ngẫu nhiên như thế này sẽ thắng thế tôi đoán. LOL.

Edit:

Jon Skeet đã có một ý tưởng tuyệt vời: đúc những gì tôi cần là IGrouping<string, Product>. Cảm ơn Jon Skeet! Khi bạn truyền đối tượng, bạn có thể liệt kê các tập hợp và nạp các kết quả vào một Danh sách riêng.

+0

Bạn có cần truy vấn động không? Không phải tiêu chí lọc của bạn (mệnh đề Where) là khía cạnh động duy nhất? – Gabe

+0

Tôi tin rằng tôi cần một DQ đầy đủ. Nếu không nhân đôi mã này cho mọi trường mà họ muốn lọc, tôi sẽ cần phải chỉ định trường GroupBy dưới dạng một chuỗi. –

+0

Truyền tới IGrouping chỉ có thể khi bạn trả lại 'nó'. Khi bạn sử dụng .Select ("mới (Key, nó là sản phẩm, đếm() như đếm)") làm thế nào để đúc này ???? –

Trả lời

4

Tôi không chắc chắn cách thực hiện điều này bằng cú pháp truy vấn (như trên), nhưng sử dụng cú pháp phương pháp, chúng tôi có thể sử dụng biểu thức < Func < như hình bên dưới.Mẫu này hoạt động dựa trên cơ sở dữ liệu AdventureWorks SQL Server (Bảng sản phẩm) và cho phép bạn chỉ định cột nào bằng cách sử dụng chuỗi (trong mẫu này tôi đã chọn Kích thước)

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

Nếu bạn xem C# Bits, tác giả sẽ thảo luận cách tạo bộ lọc xếp tầng bằng cách sử dụng Dữ liệu động. Có vẻ như bạn đang sử dụng Dữ liệu động nhưng anh ấy có trình tạo biểu thức đẹp có thể hữu ích cho bạn. Xem BuildQueryBody và sau đó là phần phương pháp mở rộng sau đây trên Iqueryable.

Vì bạn không sử dụng Dữ liệu động, bạn sẽ cần xử lý không có quyền truy cập vào đối tượng "MetaForeignKeyColumn", nhưng tôi nghi ngờ cách tiếp cận của bạn có thể giúp bạn với câu hỏi của bạn.

Tôi hy vọng điều này sẽ hữu ích.

Các vấn đề liên quan