DapperとDapperExtensionsの上にラッパー拡張メソッドを作成しています。現時点では、LINQのWhere<T>
拡張メソッドと同様に、GetList<T>
拡張メソッドにフィルタリングを追加しようとしています。私はthis questionを見てきましたが、.NETの中にEqualsExpression
という型がないので、私はMarc Gravell suggestedを実装できません。ここに私の問題の説明に役立ついくつかのデモコードは次のとおりです。離散式を引き出す<>
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
かp => p.MarketId == marketId
のいずれかを渡すとき、expression.Body
はタイプUnaryExpression
です。後者の場合、expression.Body
は実際には{Convert((p.MarketId == 2))}
を含んでいます。私が有用であることが判明している可能性がLeft
とRight
性質があるので、残念なことです
var binaryExpression = expression as BinaryExpression;
戻りnull
を、しようと
。
だから、誰も私が望むものを達成する方法を知っていますか?さらにラインを下に私はOperator
列挙型に基づいて列挙を選ぶことができるようにしたいと思います。どんな助けも大歓迎です。
私の推測では、 'UnaryExpression'の' Operand'プロパティはあなたが探している 'BinaryExpression'でしょう。 – Iridium
@イリジウムあなたが正しいと思います。デバッグでは、 'expression.Body'の' Operand'が 'LogicalBinaryExpression'型であることがわかりますが、' expression.Body.Operand'のコードにどうやってアクセスすればいいですか?インテリセンスはそれを解決できませんか? –
@Iridiumは絶対に正しいですが、今すぐ試してみましょう: 'BinaryExpression binary =(exparyBinary unaryExpression).Operand as BinaryExpression; 'は、はるかに望ましい' BinaryExpression'を生成します。 @ Jon Skeetは、なぜ変換が現れるのかをあなたに完全に説明しました(値の型は 'object'に囲まれています)...あなた自身が送るより複雑な式のツリーに注意してください。あなたは、プログラマ側で可能性の高いスペクトルを持つ式ツリーパーサーを実行することはできませんし、ライブラリライターの側で非常に大きな前提を作る... –