3

考虑这个例子:

数据库(类似于 Stackoverflow)有一个表格,其中问题和答案在同一个表格中,可按PostType字段区分。我想取回最新帖子的列表,无论是问题还是答案。

由于问题和答案具有共同的属性,因此两个类都继承自一个抽象类ContentBase。他们只添加了与每种类型相关的几个附加字段。

IList<ContentBase>当单个项目是具体类型QuestionAnswer基于条件字段时,如何获取投射到的内容项目列表。

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>(...)

它仍然行不通,因为我InvalidOperationException从 NPoco 那里得到了一条说Can't auto join User

我想这样做的唯一方法是创建一个继承自的新类PocoData并提供我自己的GetFactory委托实现。我认为。我认为没有任何其他可扩展点可以实例化具体的 POCO,而且我不确定我是否应该这样做以及如何处理抽象祖先类。

4

1 回答 1

2

不确定我是否理解正确。

  1. 你能通过一个基类来解决这个问题,它接受枚举的整数值,将 Q&A 加载到一个集合中,然后在内存中在 Q'a 和 A 之间拆分它?这似乎要简单得多。

  2. 也许会单独获得问答:

    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);
    
  3. 你能通过使用多个结果集来解决这个问题吗?

    var sql  = @"select * from QA where contenttype = 1; select * from qa where
    contenttype  =1;";
    var com = db.FetchMultiple<Question,Answer>(sql);
    com.Dump();
    

注意:我的数据库表用于nvarcharUserstring在您的基础中为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; }
    }
}
于 2014-04-01T05:44:06.203 回答