考虑这个例子:
数据库(类似于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会被实例化,我不确定我是否应该这样做以及,因为我' m处理抽象祖先类。
答案 0 :(得分:2)
我不确定我是否理解这一点。
你能解决这个问题吗?有一个基类取得Enum的整数值,将Q&amp; A加载到一个集合中,然后在内存中将它拆分为Q'a和A的?这似乎更简单。
也许可以选择Q&amp; A's:
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);
您能否使用multiple result sets解决此问题?
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; }
}
}