如何根据字段值自动创建具体类
本文关键字:创建 何根 字段 | 更新日期: 2023-09-27 17:55:36
考虑这个例子:
数据库(类似于 Stackoverflow)有一个表,其中的问题和答案位于同一个表中,可通过PostType
字段区分。 我想找回最新帖子的列表,无论是问题还是答案。
由于问题和答案共享共同的属性,因此这两个类都继承自抽象类ContentBase
。它们只添加几个与每种类型相关的附加字段。
如何获取投射到IList<ContentBase>
的内容项列表,而单个项具有基于条件字段的具体类型Question
或Answer
。
public abstract class ContentBase
{
public int Id { get; set; }
public string Title { get; set; }
public User Author { get; set; }
public abstract ContentType Type { get; }
...
}
public class Question : ContentBase
{
public override ContentType Type
{
get { return ContentType.Question; }
}
...
}
public class Answer: ContentBase
{
public override ContentType Type
{
get { return ContentType.Answer; }
}
...
}
然后,我的存储库将有一个调用:
IList<ContentBase> result = db.GetLatest();
我正在使用PetaPoco/NPoco,但我想如果使用Dapper,也会出现同样的问题。
问题
如何指示 DAL 根据特定字段的值实例化正确的具体类型(在这种情况下ContentType
)?
解释
我应该按照这些思路做一些事情:
db.Fetch<ContentBase, User>(...)
但我不能,因为ContentBase
是一个抽象类。如果我将此行更改为:
db.Fetch<dynamic, User>(...)
它仍然不起作用,因为我从 NPoco 收到一个InvalidOperationException
,说无法自动加入用户。
我想做到这一点的唯一方法是创建一个从PocoData
继承的新类,并提供我自己的GetFactory
委托实现。我认为。我认为没有任何其他扩展点可以实例化具体的 POCO,我不确定我是否应该这样做以及如何这样做,因为我正在处理抽象祖先类。
不确定我是否正确理解这一点。
-
你能通过拥有一个基类来解决这个问题,该基类获取枚举的整数值,将问答加载到一个集合中,然后在内存中将其拆分为 Q'a 和 A?这似乎简单得多。
-
也许分开问答:
var s = @"select q.Id, q.Title, q.ContentType as Type , q.Author as Name from QA q where q.ContentType = @0;"; var q = db.Fetch<Question,User>(s,1); var a = db.Fetch<Answer, User>(s,2);
-
你能通过使用多个结果集来解决这个问题吗?
var sql = @"select * from QA where contenttype = 1; select * from qa where contenttype =1;"; var com = db.FetchMultiple<Question,Answer>(sql); com.Dump();
注意:我的数据库表使用nvarchar
进行User
,并在您的底座中string
用于User
。
为ContentType
创建了一个枚举
void Main()
{
var sql = @"select * from QA where contenttype = 1; select * from QA where contenttype = 2;";
var com = db.FetchMultiple<Question, Answer>(sql);
com.Dump();
}
此处使用的其他方法和类型
public enum ContentType
{
Question,
Answer
}
public abstract class ContentBase
{
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public abstract ContentType Type { get; }
}
public class Question : ContentBase
{
public override ContentType Type
{
get { return ContentType.Question; }
}
}
public class Answer: ContentBase
{
public override ContentType Type
{
get { return ContentType.Answer; }
}
}