2011-10-07 12 views
16

Tôi muốn tìm kiếm này:LINQ to Entities (EF 4.1): Cách thực hiện một câu lệnh SQL LIKE với một ký tự đại diện ở giữa ('% term% term%')?

Post Cereal 

và có được điều này:

Post Honey Nut Cereal 

nơi thẻ hoang dã sẽ là không gian.

Tôi biết tôi có thể thực hiện SPLIT và một loạt AND và chứa() và dịch sang Biểu thức LINQ cho mỗi cụm từ dưới dạng đối tượng đặc tả, nhưng không có cách nào để tôn trọng ký tự đại diện trong thuật ngữ được gửi tới SQL ? Tôi đã xem các hàm SQL trong đó nó nằm trong LINQ to SQL, nhưng tôi không chắc nó là gì trong LINQ to Entities.

Tôi muốn làm điều gì đó như thế này:

term = '%' + term.Replace(' ', '%') + '%'; 
db.table.where(p => System.Data.Objects.SqlClient.SqlFunctions 
        .SqlMethods.Like(p.fieldname, term)); 

Bất kỳ lời đề nghị?

Trả lời

43

Tôi tin rằng bạn có thể sử dụng SqlFunctions.PatIndex:

dt.Table.Where(p => SqlFunctions.PatIndex(term, p.fieldname) > 0); 

SqlFunctions.PatIndex cư xử giống như các nhà điều hành SQL LIKE. Nó hỗ trợ tất cả các ký tự đại diện tiêu chuẩn bao gồm:

  • % Bất kỳ chuỗi số không hay nhiều ký tự.
  • _ (gạch dưới) Bất kỳ ký tự đơn nào.
  • [] Bất kỳ ký tự đơn nào trong phạm vi được chỉ định ([a-f]) hoặc được đặt ([abcdef]).
  • [^] Bất kỳ ký tự đơn nào không nằm trong phạm vi được chỉ định ([^ a-f]) hoặc đặt ([^ abcdef]).

SqlFunctions.PatIndex thường có sẵn khi SqlMethods.Like không có sẵn (bao gồm trong bộ điều khiển MVC)

+1

Điều này xứng đáng được nhiều phiếu bầu hơn. Điều này làm việc hoàn hảo cho tôi mà không có nhiều phức tạp. –

+0

Tiến sĩ Zim đã đúng, đang tìm kiếm giải pháp trong vài giờ và đây là giải pháp đơn giản nhất mà tôi tìm thấy. – user1841243

+0

Tôi đã thử điều này trong .NET và trực tiếp trong TSQL và cả hai cách đều không hiệu quả với tôi. Sử dụng EF 5, .NET 4.5 và VS 2012 – Matt

5

Nó có lẽ là dễ dàng hơn để vượt qua LINQ và sử dụng một bộ lọc Entity SQL:

var query - db.table.Where("TRIM(fieldname) LIKE @pattern"); 
query.Parameters.Add(new ObjectParameter("pattern", term)); // term == "%what%ever%" 

và loại query cụ IQueryable<TEntity> vì vậy bạn có thể áp dụng khai thác LINQ thêm.

+0

Tôi đang thử tính năng này trong LINQPad, nhưng có ngoại lệ này: 'EntitySqlException: 'BusinessName' không thể được giải quyết trong phạm vi hoặc ngữ cảnh hiện tại. Đảm bảo rằng tất cả các biến được tham chiếu đều nằm trong phạm vi, các lược đồ bắt buộc được tải và các không gian tên được tham chiếu chính xác.' Trong đó "Tên doanh nghiệp" là cột tôi đang cố gắng lọc. Không thể tìm ra cách vượt qua chuyện này. –

+0

@adrift Bạn cần phải thiết lập LINQPad với thông tin ngữ cảnh, tôi hầu như không sử dụng nó để không thể thực sự giúp đỡ (IIRC Tôi chỉ tham chiếu đến hội đồng với các loại ngữ cảnh và thực thể). – Richard

+1

Sử dụng Entity SQL là cách duy nhất để làm điều đó - L2E không hỗ trợ loại tìm kiếm ký tự đại diện này. Để khắc phục sự cố, hãy thử sử dụng 'it.BusinessName'. Các cột trong ESQL phải được tiền tố và 'nó' là tiền tố mặc định - [ở đây] (http://stackoverflow.com/questions/6202036/entity-framework-v4-1-like/6202346#6202346) là ví dụ đầy đủ về truy vấn . –

0

Chỉ cần làm rõ comment Ladislav của về it.BusinessName. Tôi nghĩ rằng những gì ông đang đề cập đến là tiền tố tên trường với .it. Các giải pháp trên hoạt động miễn là bạn tiền tố tên trường trong mệnh đề where với it.. Ngoài ra tôi không cần TRIM() trong trường hợp của tôi.

var query - db.table.Where("it.fieldname LIKE @pattern"); 
query.Parameters.Add(new ObjectParameter("pattern", term)); // term == "%what%ever%" 

Nó hoạt động hoàn hảo với cơ sở dữ liệu Oracle.

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