2017-09-06 7 views
2

Dapperのためにsqlを動的に生成して実行しようとしていますが、単に型を渡すだけで、sqlが動的に生成されて実行されます。Dapperクエリマップの動的Func <>

例クラス:

public class User 
{ 
    [Key] 
    public int UserId { get; set; } 
    public Address Address { get; set; } 
} 
public class Address 
{ 
    [Key] 
    public int UserId { get; set; } 
    public string PostCode { get; set; } 
} 

が効果的に次のことを実行します:

// sql: "SELECT User.UserId, Address.UserId, Address.PostCode FROM User LEFT JOIN Address ON Address.User = User.UserId"... // auto generated from 'User' type including join to 'Address'; 

connection.Query<User, Address, User>(sql, /*** map argument needs to be dynamic Func<> ***/); 

ので、実行時にのみ知られているこれらのタイプUser & Address与え、どのように私は、適切なデリゲートFunc<User, Address, User>を生成することができます引数にmapを渡しますか?私はリフレクションを使用してFunc<>を作成するために見ている

Func<User, Address, User> map = (u, a) => { 
    u.Address = a; 
    return u; 
} 

examplesは、私の場合には、彼らはその型の引数は、>/FUNC < ,,>/FUNC <、(機能<を変えるものではなく、種類が知られていると仮定します,,,など)。

助けてください。式を使って何かが付いているかどうかを調べる例を続けます。

+0

https://stackoverflow.com/a/21731667/1264882 – WithMetta

答えて

1

これは私が得たものと同じくらいです。 Dapperのリポジトリをクローンして、Query()メソッドの動作を調べましたが、古いバージョンのVisual Studioを使用しています。

public static class DynamicFuncHelper 
{ 
    public static Delegate CreateFunc(Type type1, Type type2) 
    { 
     Type funcType = typeof(Func<,,>).MakeGenericType(type1, type2, type1); 
     MethodInfo method = 
      typeof(DynamicFuncHelper<,>) 
      .MakeGenericType(type1, type2) 
      .GetMethod("SetAddressProperty", 
       BindingFlags.Public | BindingFlags.Static 
      ); 
     return Delegate.CreateDelegate(funcType, method); 
    } 
} 

public static class DynamicFuncHelper<T,U> 
    where T : class 
    where U : class 
{ 
    public static T SetAddressProperty(T obj1, U obj2) 
    { 
     obj1.GetType().InvokeMember("Address", 
      BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty, 
      Type.DefaultBinder, obj1, new[] { obj2 }); 
     return obj1; 
    } 
} 

このユニットテストを合格

[TestClass] 
public class DynamicFuncTest 
{ 
    [TestMethod] 
    public void TestDynamicMapper() 
    { 
     var actualUser = new User { UserId = 1 }; 
     var actualAddress = new Address { PostCode = "12345", UserId = 1 }; 
     var testSetAddress = DynamicFuncHelper.CreateFunc(typeof(User), typeof(Address)); 
     var delegateResult = testSetAddress.DynamicInvoke(actualUser, actualAddress); 
     Assert.AreEqual(actualUser, delegateResult, "Delegate result was not actualUser"); 
     Assert.AreEqual(actualAddress, actualUser.Address, "User address was not expected address"); 
    } 
} 
+0

ねえ、お返事に感謝。それは有望に見えますが、私はまだ 'Func'の型引数がいくつでもあるかもしれないという事実に固執しています。私は問題を解決するように見える[このライブラリ](https://www.nuget.org/packages/Dapper.Mapper/)を見つけました。マップ引数を解決するためにそれを引き上げることになるかもしれません。 –

関連する問題