Joh*_*ohn 12 .net c# reflection abstract-class dapper
我试图用一些精巧的查询替换讨厌的LINQ 2 SQL命中以改善性能.在这样做时,我必须将一堆不同的对象编织在一起,以便创建保存ASN信息所需的所有信息所需的大对象.
我目前遇到的问题是抽象类Orders,这个类是由两个单独的类AutionOrder和MerchantOrder使用discriminator属性实现的.
由于我不能使用dapper来创建一个抽象类的对象,而是使用其中一个公共类.然而,当它构建对象时,它在其内部失败GetSettableProps
是找到正确的DeclaringType
但该GetProperty
方法在寻找属于internal
或是的属性时返回null EntitySet
.我试图用它来破解它t.BaseType.GetProperty
并且p.GetAccessors().First().GetBaseDefinition().DeclaringType.GetProperty(p.Name).GetSetMethod(true)
没有成功.
虚拟对象:
订购
OrderID,名称,地址,RowVersion(内部),货件(EntitySet),OrderDetails(EntitySet),客户(EntityRef)
装船
ShipmentID,OrderID,TrackingNumber
订单详细信息
OrderDetailID,OrderID,Product,QTY,Price
顾客
客户ID,姓名,
对于这个特定的SQL命中,我试图抓住我需要的一些1对1关系映射.
SELECT o.*from Orders as o left join customer as c on o.CustomerID = c.CustomerID其中o.OrderID in(1,2,3);
这就是我用来利用小巧玲珑的东西,并让它做到这一点:
using (var connection = new SqlConnection(_ConnectionString))
{
connection.Open();
results = connection.Query<MerchantOrder, MerchantCustomer, MerchantOrder>(sql.ToString(),
(o, c) => { o.Customer = c; return o; },
splitOn: "CustomerID");
}
Run Code Online (Sandbox Code Playgroud)
如果我将Order改为公共类,这个问题就会消失,但这不是一个理想的副作用.尝试为RowVersion设置propInfo时失败 - 将此切换为公共而不是内部解决了这个问题 - 虽然不是所希望的.但是当它试图为Order创建Shipments对象时失败了.当Order是公共类时,这一点都不是问题.
此外,我正在进行单独的查询以引入多对一的关系,例如将订单发送到订单和订单的订单详细信息,并将结果规范化为正确的订单对象.MerchantOrder几乎是一个没有真正特殊逻辑的空类.这里区分不同的是我们最终找到在实际SQL命中之前被抽象出来的CustomerID.
此外,我在12/20/2011使用最新版本的dapper.
我真的很喜欢小巧玲珑,但这个问题让我头晕目眩 - 所以感谢你的帮助!
这是一个bug,现在已在trunk中修复:
public class AbstractInheritance
{
public abstract class Order
{
internal int Internal { get; set; }
protected int Protected { get; set; }
public int Public { get; set; }
public int ProtectedVal { get { return Protected; } }
}
public class ConcreteOrder : Order
{
public int Concrete { get; set; }
}
}
// http://stackoverflow.com/q/8593871
public void TestAbstractInheritance()
{
var order = connection.Query<AbstractInheritance.ConcreteOrder>("select 1 Internal,2 Protected,3 [Public],4 Concrete").First();
order.Internal.IsEqualTo(1);
order.ProtectedVal.IsEqualTo(2);
order.Public.IsEqualTo(3);
order.Concrete.IsEqualTo(4);
}
Run Code Online (Sandbox Code Playgroud)
一方面注意,根据设计,我们不在基类中设置私有字段或属性.这种行为可能是神奇的,也不一致.
例如:
class A { private int a {get; set;} }
class B : A { private int a {get; set;} }
class C: B {}
// What should "select 1 a" do? Set it on A? Set it on B? Set it on Both? Set it on neither?
Run Code Online (Sandbox Code Playgroud)
我们选择"既不设置它"