2017-07-27 129 views
1

我正在嘗試將EF遷移到Dapper,並且正在尋找一種更好,更有效的方法來遷移現有的LINQ表達式「IQueryable」以使用Dapper。如何高效地將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可能是次優的,所以直接複製相同的次優SQL用於Dapper使用對我來說似乎是無意義的練習。

我所做的是確定執行最差的LINQ查詢,並在SQL中重寫它們 - 從頭開始​​ - 用於Dapper。我最終得到的是LINQ和Dapper在整個系統中的結合,受益於兩種方法的優勢,即LINQ的快速開發,以及Dapper的性能提升和優化的SQL查詢。