2008-09-17 16 views
20

Có ai biết cách áp dụng điều kiện loại "trong giá trị" bằng LINQ-to-Entities không? Tôi đã thử những điều sau đây nhưng nó không hoạt động:Cách thực hiện "nơi có giá trị" trong LINQ-to-Entities 3.5

var values = new[] { "String1", "String2" }; // some string values 

var foo = model.entitySet.Where(e => values.Contains(e.Name)); 

Tôi tin rằng điều này hoạt động trong LINQ-to-SQL? Có suy nghĩ gì không?

+0

Related: http://stackoverflow.com/questions/6994730/how-to-workaround-contains-for-net-3-5-dont-support –

Trả lời

0

Có nó dịch để SQL, nó tạo ra một tiêu chuẩn trong bản Tuyên Bố như thế này:.

CHỌN [t0] [col1] FROM [table] [t0] ĐÂU [col1] IN ('Giá trị 1 ', 'Value 2')

+0

Khi sử dụng LINQ-to-Entities trong khung ADO.NET Entity, tôi nhận được một ngoại lệ nói rằng "Chứa" không thể dịch được . Tôi biết những gì nó nên dịch nhưng nó không hoạt động. –

0

Sử dụng phương pháp mà không nhất luôn làm việc

var results = from p in db.Products 

      where p.Name == nameTextBox.Text 

      select p; 
+0

Cảm ơn Gabe. Tôi biết về cú pháp LINQ thay thế và nó hoạt động chính xác theo cùng một cách. Câu hỏi của tôi ở đây là làm thế nào để làm điều kiện kiểu "where in values". –

19

cập nhật: tìm ra cách để làm điều này. Và EF sẽ tạo ra SQL thích hợp trên cơ sở dữ liệu. Tôi không chắc chắn nếu điều này là dành cho chỉ EF4 nhưng tôi đã đầu từ Entity Framework 4.0 Công thức


var listOfIds=GetAListOfIds(); 
var context=CreateEntityFrameworkObjectContext(); 
var results = from item in context.Items 
       where listOfIds.Contains(item.Category.Id) 
       select item; 
//results contains the items with matching category Ids 

Truy vấn này tạo ra đúng tại khoản trên phía máy chủ. Tôi chưa thử nghiệm nó với EF 3.5 nhưng nó hoạt động với EF4.

NB: Các giá trị được chuyển vào mệnh đề trong không phải là các tham số để đảm bảo bạn xác thực đầu vào của mình.

+0

Cảm ơn Mike, bạn là một nhà vô địch. –

+0

Cảm ơn bạn đã bổ sung! –

+0

Ok, cuối cùng tôi cũng đã thử nghiệm điều này.Thật không may nó không hoạt động cho những gì tôi đang làm nhưng tôi đã tìm thấy câu trả lời ở đây: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2670710&SiteID=1 Cảm ơn sự giúp đỡ mặc dù , ur vẫn là một nhà vô địch! –

1

Chứa không được hỗ trợ trong EF tại thời điểm này.

1

FYI:

Nếu bạn đang sử dụng ESql, bạn có thể sử dụng khi hoạt động. Tôi không có VS 2008 Với tôi, nhưng mã nên được một cái gì đó như sau:

var ids = "12, 34, 35"; 
using (context = new Entites()) 
{ 
    var selectedProducts = context.CreateQuery<Products>(
     String.Format("select value p from [Entities].Products as p 
         where p.productId in {{{0}}}", ids)).ToList(); 
    ... 
} 
1

Đối với các trường hợp khi bạn muốn sử dụng biểu thức khi truy vấn dữ liệu của bạn, bạn có thể sử dụng phương pháp mở rộng sau (điều chỉnh sau khi http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/095745fe-dcf0-4142-b684-b7e4a1ab59f0/):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Linq.Expressions; 
using System.Data.Objects; 

namespace Sample { 
    public static class Extensions { 
     public static IQueryable<T> ExtWhereIn<T, TValue>(this ObjectQuery<T> query, 
        Expression<Func<T, TValue>> valueSelector, 
        IEnumerable<TValue> values) { 
      return query.Where(BuildContainsExpression<T, TValue>(valueSelector, values)); 
     } 
     public static IQueryable<T> ExtWhereIn<T, TValue>(this IQueryable<T> query, 
      Expression<Func<T, TValue>> valueSelector, 
      IEnumerable<TValue> values) { 
      return query.Where(BuildContainsExpression<T, TValue>(valueSelector, values)); 
     } 
     private static Expression<Func<TElement, bool>> BuildContainsExpression<TElement, TValue>(
       Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values) { 
      if (null == valueSelector) { throw new ArgumentNullException("valueSelector"); } 
      if (null == values) { throw new ArgumentNullException("values"); } 
      ParameterExpression p = valueSelector.Parameters.Single(); 
      // p => valueSelector(p) == values[0] || valueSelector(p) == ... 
      if (!values.Any()) { 
       return e => false; 
      } 
      var equals = values.Select(value => (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value, typeof(TValue)))); 
      var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.Or(accumulate, equal)); 
      return Expression.Lambda<Func<TElement, bool>>(body, p); 
     } 
    } 
    class Program { 
     static void Main(string[] args) { 
      List<int> fullList = new List<int>(); 
      for (int i = 0; i < 20; i++) { 
       fullList.Add(i); 
      } 

      List<int> filter = new List<int>(); 
      filter.Add(2); 
      filter.Add(5); 
      filter.Add(10); 

      List<int> results = fullList.AsQueryable().ExtWhereIn<int, int>(item => item, filter).ToList(); 
      foreach (int result in results) { 
       Console.WriteLine(result); 
      } 
     } 
    }  
} 

Sử dụng tiện ích thật sự dễ dàng (như bạn có thể thấy trong ví dụ). Để sử dụng nó trên một đối tượng cơ sở dữ liệu, giả sử bạn đang lọc một bảng có tên là "Sản phẩm" theo nhiều hơn một id, bạn có thể làm một cái gì đó như thế:

class Product { 
    public int Id { get; set; } 
    /// ... other properties 
} 


List<Product> GetProducts(List<int> productIds) {  
    using (MyEntities context = new MyEntities()) { 
     return context.Products.ExtWhereIn<Product, int>(product => product.Id, productIds).ToList(); 
    } 
} 
+0

Bạn đã thử áp dụng giải pháp cho một danh sách lớn? –

+0

Không thực sự, tôi đã sử dụng điều này trên một số dự án và không bao giờ có bất kỳ vấn đề. Tôi đoán tôi không quan trọng nữa, vì EF2 đã có tính năng này với phần mở rộng .Contains() – Lucian

+1

Hoàn toàn ngu ngốc để bỏ phiếu cho câu trả lời này. Sự cần thiết cho một giải pháp phức tạp và có thể chậm như vậy không phải là lỗi của người cung cấp câu trả lời này nhưng của EF 1. (Cố định: +1) – Slauma

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