簡體   English   中英

如何在 Linq 中使用 Dapper

[英]How to use Dapper with Linq

我正在嘗試從實體框架轉換為 Dapper,以期提高數據訪問性能。

我使用的查詢采用謂詞形式,例如Expression<Func<TModel, bool>>

舉個例子:

我有以下代碼需要轉換為使用 Dapper。

我目前在做什么:

public async Task<List<TModel>> Get(Expression<Func<TModel, bool>> query)
{
    // this.Context is of type DbContext
    return await this.Context.Set<TModel>().Where(query).ToListAsync();
}

我想做什么:

public async Task<List<TModel>> Get(Expression<Func<TModel, bool>> query)
{
    using (IDbConnection cn = this.GetConnection)
    {
        return await cn.QueryAsync<TModel>(query);
    }
}

我的 google-fu 失敗了,有人可以幫忙嗎?

編輯:

請注意,我確實找到了: https : //github.com/ryanwatson/Dapper.Extensions.Linq

但我似乎無法弄清楚如何使用它。

首先,Dapper 的一位作者說,當有人問

是否有計划使 Dapper.net 與 IQueryable 接口兼容?

沒有這方面的計划。 這遠遠超出了 dapper 試圖做的事情。 到目前為止,我會說這是對立的。 Dapper core 試圖成為那些喜歡 SQL 的人的朋友。

(參見https://stackoverflow.com/a/27588877/3813189 )。

在某種程度上,正如您所建議的那樣,這確實表明 NuGet 的各種擴展包可能會有所幫助。

我嘗試過DapperExtensions ,這使得以編程方式編寫查詢過濾器變得更容易 - 例如。

using System.Data.SqlClient;
using DapperExtensions;

namespace StackOverflowAnswer
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var cn = new SqlConnection("Server=.;Database=NORTHWND;Trusted_Connection=True;"))
            {
                var list = cn.GetList<Products>(
                    Predicates.Field<Products>(f => f.Discontinued, Operator.Eq, false)
                );
            }
        }

        class Products
        {
            public int ProductId { get; set; }
            public string ProductName { get; set; }
            public bool Discontinued { get; set; }
        }
    }
}

我也試過Dapper.Extensions.Linq (你建議的包),它承諾

以此為基礎,通過 Linq 查詢提供高級數據庫訪問。 流體配置使設置簡單快捷。

不幸的是,我也不能走得很遠。 沒有太多文檔,並且測試似乎沒有涵蓋 QueryBuilder,這似乎是用於將 Linq 表達式轉換為 Dapper Extensions 謂詞的類(如問題Parsing boolean expressions with the QueryBuilder所建議的) . 我嘗試了以下操作,這需要將 IEntity 接口添加到我的 DTO -

using System;
using System.Data.SqlClient;
using System.Linq.Expressions;
using Dapper.Extensions.Linq.Builder;
using Dapper.Extensions.Linq.Core;
using DapperExtensions;

namespace StackOverflowAnswer
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var cn = new SqlConnection("Server=.;Database=NORTHWND;Trusted_Connection=True;"))
            {
                Expression<Func<Products, bool>> filter = p => !p.Discontinued;
                var queryFilter = QueryBuilder<Products>.FromExpression(filter);

                var list = cn.GetList<Products>(
                    queryFilter
                );
            }
        }

        class Products : IEntity
        {
            public int ProductId { get; set; }
            public string ProductName { get; set; }
            public bool Discontinued { get; set; }
        }
    }
}

.. 但它在運行時失敗並出現錯誤

找不到 StackOverflowAnswer.Program+Products 的運算符

我不確定為什么手動生成 Predicate(第一個示例)有效,但 QueryBuilder 沒有。

我想說的是,在您的問題上留下的評論越來越看起來是正確的,您將需要重新編寫代碼,遠離與實體框架一起使用的表達式。 由於很難找到關於這個 QueryBuilder 類的任何信息,我會擔心(即使你確實讓它工作了)你遇到的任何問題都很難獲得幫助(並且錯誤可能無法修復)。

我編寫了一個實用程序來使用屬性與 Dapper 一起使用 EF。 我解析謂詞並轉換為 SQL。

“用戶”POCO:

[Table("Users")]
public class User
{
    [Key]
    [Identity]
    public int Id { get; set; }

    public string Login { get; set;}

    [Column("FName")]
    public string FirstName { get; set; }

    [Column("LName")]
    public string LastName { get; set; }

    public string Email { get; set; }

    [NotMapped]
    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", FirstName, LastName);
        }
    }
}

和簡單的查詢:

using (var cn = new SqlConnection("..."))
{
    var usersRepository = new DapperRepository<User>(cn)
    var allUsers = await userRepository.FindAllAsync(x => x.AccountId == 3 && x.Status != UserStatus.Deleted);
}

也許它對你有用?

MicroOrm.Dapper.Repositories

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM