我正忙于在Dapper和DapperExtensions之上创建包装扩展方法。目前我正在尝试将过滤添加到GetList<T>
扩展方法中,类似于 LINQ 的Where<T>
扩展方法。我已经看到了这个问题,但似乎我无法实现Marc Gravell的建议,因为 .NET 4.5 中没有类型EqualsExpression
。这是一些演示代码,可帮助解释我的问题:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq.Expressions;
using DapperExtensions;
namespace Dapper.Extensions.Demo
{
public class Program
{
private static readonly string ConnectionString = ConfigurationManager.ConnectionStrings["DapperDbContext"].ConnectionString;
public static IDbConnection Connection { get { return new SqlConnection(ConnectionString); } }
public static void Main(string[] args)
{
const int marketId = 2;
var matchingPeople = Connection.Get<Person>(p => p.MarketId, marketId); // This works
// Below is a LambdaExpression. expression.Body is, bizarrely, a UnaryExpression with a Convert
//var matchingPeople = Connection.Get<Person>(p => p.MarketId == marketId); // Does not work
foreach (var person in matchingPeople)
{
Console.WriteLine(person);
}
if (Debugger.IsAttached)
Console.ReadLine();
}
}
public static class SqlConnectionExtensions
{
public static IEnumerable<T> Get<T>(this IDbConnection connection, Expression<Func<T, object>> expression, object value = null) where T : class
{
using (connection)
{
connection.Open();
// I want to be able to pass in: t => t.Id == id then:
// Expression<Func<T, object>> expressionOnLeftOfFilterClause = t => t.Id;
// string operator = "==";
// object valueFromLambda = id;
// and call Predicates.Field(expressionOnLeftOfFilterClause, Operator.Eq, valueFromLambda)
var predicate = Predicates.Field(expression, Operator.Eq, value);
var entities = connection.GetList<T>(predicate, commandTimeout: 30);
connection.Close();
return entities;
}
}
}
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
public int MarketId { get; set; }
public override string ToString()
{
return string.Format("{0}: {1}, {2} - MarketId: {3}", Id, Surname, FirstName, MarketId);
}
}
}
特别注意我的Get<T>
扩展方法:当我传入p => p.MarketId
orp => p.MarketId == marketId
时,expression.Body
类型为UnaryExpression
. 对于后者,expression.Body
实际上包含{Convert((p.MarketId == 2))}
.
尝试
var binaryExpression = expression as BinaryExpression;
Returns null
,这很不幸,因为有一些我可能会发现有用的属性Left
。Right
那么,有谁知道如何实现我想要的?更进一步,我希望能够Operator
根据传入的 lambda 表达式选择枚举。任何帮助将不胜感激。