2015-09-25 111 views
1

刚开始用短小精悍(来自的NuGet)工作,无法弄清楚如下:使用数字参数占位符小巧玲珑

这工作:

_connection.Query<MySalesPerson>(@"select * from Sales.SalesPerson where territoryId = @id", 
        new {id = territory.TerritoryID}); 

这不作品:

_connection.Query<MySalesPerson>(@"select * from Sales.SalesPerson where territoryId = @0", 
        new {id = territory.TerritoryID}); 

所以它不占用数字占位符,它是标准行为还是我错过了某些东西。与PetaPoco一样的作品风起云涌

回答

1

Dapper对查询参数使用对象(不是列表)。这意味着它不能(可靠地)使用索引来获取属性值(因为在形式上,对象中的属性顺序是未指定的)。

详细来说,您应该检查CreateParamInfoGenerator()方法,发出的代码使用GetProperties()来读取您的对象的所有公共参数。没有太多的事情可以做,除非你分叉并改变它。

守则参数指标转化为属性的名称简单明了,性能排序可以用代码C# Get FieldInfos/PropertyInfos in the original order?

注实现了GetProperties()不支持棘手的用途(例如,实现IDynamicMetaObjectProvider对属性名称映射到指数无论你'能够从一个值数组中发出你自己的类型请注意,成员名限制是由语言设置的,而不是由CLR或CIL设置,那么你可以创建一个名称为数字的属性的类型,这是一个概念证明:

object CreatePropertiesFromValues(params object[] args) { 
    // Code to emit new type... 

    int index = 0; 
    foreach (object arg in args) { 
     var name = index.ToString(); 
     var type = typeof(object); // We don't need strongly typed object! 
     var field = typeBuilder.DefineField("_" + name, type, FieldAttributes.Private); 

     var property = typeBuilder.DefineProperty(name, PropertyAttributes.HasDefault, type, null); 

     var method = typeBbuilder.DefineMethod("get_" + name, 
      MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, 
      type, Type.EmptyTypes); 

     var generator = method.GetILGenerator(); 
     generator.Emit(OpCodes.Ldarg_0); 
     generator.Emit(OpCodes.Ldfld, field); 
     generator.Emit(OpCodes.Ret); 

     property.SetGetMethod(method); 

     ++index; 
    } 

    // Code to create an instance of this new type and to set 
    // property values (up to you if adding a default constructor 
    // with emitted code to initialize each field or using _plain_ 
    // Reflection). 
} 

现在你可以使用这样的:

_connection.Query<MySalesPerson>(@"select * from Sales.SalesPerson where territoryId = @0", 
    CreatePropertiesFromValues(territory.TerritoryID)); 

嗯......它总是有趣与反思玩散发出但它是一个大量的工作,只是为了增加对位置参数的支持。改变Dapper代码可能会更容易(即使这个函数实际上是一个大错综复杂的混乱)。

至于最后要注意的......现在我们也有罗斯林那么我们可以知道哪些属性声明(甚至更多)为了不过到目前为止,我没有用它玩...

+0

感谢详细的解释,让我看看我能如何适应相同的东西 –