2017-07-27 11 views
1

私はEFをDapperに移行しようとしています。Dapperを使用するために、既存のlinq式「IQueryable」を移行する方法について、より効率的な方法を探しています。EF linqクエリをDapperに効率的に移行する方法は?

例:

public class MyDbContext : DbContext 
{ 
    public DbSet<MyEntity> MyEntity { get; set; } 
    +20 more entities.. 
} 

// Inside repository 
using (var context = new MyDbContext()) 
{ 
    context.MyEntity.Where(x => x.Id == 1) // How can I easily migrate this linq to Dapper? 
} 

上記のコードは、私だけが移行しようとしているかの簡単な例です。これらのクエリの中には、単純なものと複雑なものが混在するものがあります。現在、リポジトリ内にそのようなアプローチを使用しているMyDbContextに20以上のリポジトリと20以上のDbSetがあります。

インターネットで検索したところ、より良いアプローチは見つかりませんでした。今のところこれを行う唯一の方法は、linqをクエリ文字列に変換してDapperで使用することです。それは実行可能だが退屈で巨大な努力である。 Dapperに移行する理由はパフォーマンスです。

誰も私が現在考えているよりもこれを行う良い方法がありますか?

答えて

0

私は自分の問題に薬を発見しました。クエリをインターセプトする代わりに、述語を渡して既存の関数と同じようなLinq関数を作成することができます。

public class QueryLinq 
{ 
    private readonly IDatabase _database; 
    public QueryLinq(IDatabase database) 
    { 
     _database = database; // Dapper implementation 
    } 

    public IEnumberable<T> Where<T>(Func<T,bool> predicate) 
    { 
     var enumerable = _database.Query<T>(); 
     return enumerable(predicate); 
    } 
} 

// Existing Repository 
public class MyRepository 
{ 
    private readonly QueryLinq _queryLinq; 
    public MyRepository(QueryLinq queryLinq) 
    { 
     _queryLinq = queryLinq; 
    } 

    public IEnumerable<MyEntity> SelectMyEntity() 
    { 
     // Before 
     // using (var context = new MyDbContext()) 
     // {    
     // context.MyEntity.Where(x => x.Id == 1); 
     // } 

     // Now 
     return _queryLinq.Where<MyEntity>(x => x.Id == 1); 
    } 
} 

// Database implementation 
public class Database : IDatabase 
{ 
    public IEnumerable<T> Query<T>() 
    { 
     var type = typeof(T); 
     var attributes = type.GetCustomAttributes(typeof(TableAttribute), false); 

     if (attributes == null && attributes.Length <= 0) 
      throw new Exception($"Table name is missing for {type.Name}"); 

     var tableName = (attributes[0] as TableAttribute).Name; 

     using(var dbConnection = new SqlConnection()) 
     { 
      // Some code here 
      return dbConnection.Query<T>($"SELECT * FROM {tableName}")); 
     } 
    } 
} 

この方法では、既存のクエリについて心配する必要はありません。

0

Entity Framework Loggingを使用して、生成されたSQLをVisual Studioコンソールに出力できます。

_context.Database.Log = x => Trace.WriteLine(x); 

サービスまたはレポジトリのクラスに簡単に追加できます。

私はあなたがやっていることを正確にやっているのと同じ理由からです。 LINQが生成するSQLが準最適であることがわかるので、使用するDapper用の準最適SQLを直接コピーすることは、無意味な行為のように思えます。

私が行ったことは、最悪の場合実行するLINQクエリを特定し、SQLでそれらをゼロから書き直して、Dapperで使用することです。私が結んできたのは、システム全体でLINQとDapperを組み合わせたもので、LINQの急速な開発と、Dapperと最適化されたSQLクエリのパフォーマンス向上の両方の利点から利益を得ています。

関連する問題