c# – 在小巧玲珑中查询抽象模型

c# – 在小巧玲珑中查询抽象模型,第1张

概述我正在使用Table Per Hierarchy数据库继承,其中所有派生类型的列都在一个表中.每个派生表都使用字符串Discriminator字段标识,该字段包含派生类的名称: ---------------------| tanimal |---------------------| animalid || discriminator || 我正在使用table Per HIErarchy数据库继承,其中所有派生类型的列都在一个表中.每个派生表都使用字符串discriminator字段标识,该字段包含派生类的名称:
---------------------| tanimal           |---------------------| animalID          || discriminator     || furcolour         || feathercolour     |---------------------public abstract class Animal{    public int AnimalID { get; set; }    public string discriminator { get { return GetType().name; } }}public class Bird : Animal{    public string FeatherColour { get; set; }}public class Dog : Animal{    public string FurColour { get; set; }}

正如所料,当通过Dapper的查询方法检索它时,我无法创建抽象类的实例.我希望这会返回一个Animal列表,它们的值是相应的派生类型.

var animals = Connection.query<Animal>("SELECT * FROM tanimal")

我试图增加对此的支持是不成功的.在传入sqlMapper.cs :: GetTypeDeserializer()之前,如果传入的类型是抽象类,那么我将类型替换为以下方法中返回的类型:

static Type GetDerivedType(Type abstractType,IDataReader reader){    var discriminator = abstractType.GetProperty("discriminator");    if (discriminator == null)        throw new InvalIDOperationException("Cannot create instance of abstract class " + abstractType.Fullname + ". To allow dapper to map to a derived type,add a discriminator fIEld that stores the name of the derived type");    return Type.GetType((string)reader["discriminator"]);}

但是,此时看起来还没有打开读取器,因此当没有数据存在时无效尝试读取失败.

这是正确的方法吗?有没有任何努力在其他地方支持这个?

解决方法 你可以使这个工作,但它不如使用Dapper的默认行为与单独的表.

需要为每一行调用GetDeserializer,这意味着它需要在内部发生(reader.Read())

通过修改queryImpl< T>你可以达到你想要的效果.假设你得到的结果是:

var results = connection.query<Animal>("SELECT * FROM tanimal");

然后是queryImpl< T>的try {}块的开头.将会:

try{cmd = command.SetupCommand(cnn,info.ParamReader);if (wasClosed) cnn.open();// We can't use SequentialAccess any more - this will have a performance hit.reader = cmd.ExecuteReader(wasClosed ? CommandBehavior.CloseConnection : CommandBehavior.Default);wasClosed = false; // You'll need to make sure your typePrefix is correct to your type's namespacevar assembly = Assembly.GetExecutingAssembly();var typePrefix = assembly.Getname().name + ".";while (reader.Read()){    // This was already here    if (reader.FIEldCount == 0) //https://code.Google.com/p/dapper-dot-net/issues/detail?ID=57        yIEld break;    // This has been moved from outsIDe the while    int hash = GetColumnHash(reader);    // Now we're creating a new DeserializerState for every row we read     // This can be made more efficIEnt by caching and re-using for matching types    var discriminator = reader["discriminator"].ToString();    var convertToType = assembly.GetType(typePrefix + discriminator);    var tuple = info.Deserializer = new DeserializerState(hash,GetDeserializer(convertToType,reader,-1,false));    if (command.AddToCache) SetqueryCache(IDentity,info);    // The rest is the same as before except using our type in ChangeType    var func = tuple.Func;    object val = func(reader);    if (val == null || val is T)    {        yIEld return (T)val;    }    else    {        yIEld return (T)Convert.ChangeType(val,convertToType,CultureInfo.InvariantCulture);    }}// The rest of this method is the same

这将使该方法仅适用于鉴别器字段,因此您可能想要创建自己的queryImpl< T>如果你需要这个与其他查询正常工作.此外,我不能保证这将在每种情况下都有效,只测试两行,每种类型一个 – 但这应该是一个很好的起点.

总结

以上是内存溢出为你收集整理的c# – 在小巧玲珑中查询抽象模型全部内容,希望文章能够帮你解决c# – 在小巧玲珑中查询抽象模型所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1243879.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存