私はクエリを持っています:
var query = DataContext.Fotos.Where(x => x.Pesquisa.Contais("myTerm")
生成されるSQLは次のとおりです。
SELECT
...
FROM Fotos AS [Extent1]
WHERE [Extent1].[Pesquisa] LIKE N'%mytem%'
しかし、私は使用する必要があります:
SELECT
...
FROM Fotos AS [Extent1]
WHERE CONTAINS ([Extent1].[Pesquisa], 'my term')
エンティティフレームワーク6を使用して全文検索を実行する方法
Entity Framework 6は全文検索をサポートしていないようですが、インターセプターには回避策があります。
http://www.entityframework.info/Home/FullTextSearch
更新リンクが機能しないため、ここに元のコンテンツがあります:
Microsoft TSQLは、述語(CONTAINSおよびFREETEXT)によるフルテキストクエリをサポートしています
たとえば、テーブルノートがあるとします。
Create table Notes ( Id int Identity not null, NoteText text ) CREATE FULLTEXT CATALOG [Notes Data]
このテーブルでWord 'John'を含むレコードを検索する場合は、以下を発行する必要があります。
SELECT TOP (10) * from gps.NOTES WHERE contains(NoteText, '(john)')
残念ながら、Enityフレームワークはまだ全文検索述語をサポートしていません。 EFv6の場合、代行受信を使用して回避策を作成できます。
アイデアは、プレーンなString.Containsコード内で検索テキストをいくつかの魔法のWordでラップし、sqlがSqlCommandで実行される直前にインターセプターを使用してアンラップすることです。
まず、インターセプタークラスを作成します。
public class FtsInterceptor : IDbCommandInterceptor { private const string FullTextPrefix = "-FTSPREFIX-"; public static string Fts(string search) { return string.Format("({0}{1})", FullTextPrefix, search); } public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) { } public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) { } public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { RewriteFullTextQuery(command); } public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { } public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) { RewriteFullTextQuery(command); } public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) { } public static void RewriteFullTextQuery(DbCommand cmd) { string text = cmd.CommandText; for (int i = 0; i < cmd.Parameters.Count; i++) { DbParameter parameter = cmd.Parameters[i]; if (parameter.DbType.In(DbType.String, DbType.AnsiString, DbType.StringFixedLength, DbType.AnsiStringFixedLength)) { if (parameter.Value == DBNull.Value) continue; var value = (string)parameter.Value; if (value.IndexOf(FullTextPrefix) >= 0) { parameter.Size = 4096; parameter.DbType = DbType.AnsiStringFixedLength; value = value.Replace(FullTextPrefix, ""); // remove prefix we added n linq query value = value.Substring(1, value.Length - 2); // remove %% escaping by linq translator from string.Contains to sql LIKE parameter.Value = value; cmd.CommandText = Regex.Replace(text, string.Format( @"\[(\w*)\].\[(\w*)\]\s*LIKE\s*@{0}\s?(?:ESCAPE N?'~')",parameter.ParameterName), string.Format(@"contains([$1].[$2], @{0})",parameter.ParameterName)); if (text == cmd.CommandText) throw new Exception("FTS was not replaced on: " + text); text = cmd.CommandText; } } } } }
私はこのように定義できる拡張関数を使用しました:
static class LanguageExtensions { public static bool In<T>(this T source, params T[] list) { return (list as IList<T>).Contains(source); } }
それでは、サンプルを使用方法を作成してみましょう。エンティティークラスが必要です注:
public class Note { public int Id { get; set; } public string NoteText { get; set; } }
マッピング構成:
public class NoteMap : EntityTypeConfiguration<Note> { public NoteMap() { // Primary Key HasKey(t => t.Id); } }
そして、私たちのDbContext祖先:
public class MyContext : DbContext { static MyContext() { DbInterception.Add(new FtsInterceptor()); } public MyContext(string nameOrConnectionString) : base(nameOrConnectionString) { } public DbSet<Note> Notes { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new NoteMap()); } }
これで使用する準備が整いました。 「ジョン」を検索してみましょう:
class Program { static void Main(string[] args) { var s = FtsInterceptor.Fts("john"); using (var db = new MyContext("CONNSTRING")) { var q = db.Notes.Where(n => n.NoteText.Contains(s)); var result = q.Take(10).ToList(); } } }
EFで生のSQLクエリを使用できます。したがって、別の簡単な回避策があります。
using (DBContext context = new DBContext())
{
string query = string.Format("Select Id, Name, Description From Fotos Where CONTAINS(Pesquisa, '\"{0}\"')", textBoxStrToSearch.Text);
var data = context.Database.SqlQuery<Fotos>(query).ToList();
dataGridView1.DataSource = data;
}
入力検証等は省略しています。編集:コードはOPのクエリに従って変更されます。