如何根据字段值自动创建具体类

时间:2014-03-31 13:47:28

标签: c# petapoco mapper table-per-hierarchy npoco

考虑这个例子:

数据库(类似于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处理抽象祖先类。

1 个答案:

答案 0 :(得分:2)

我不确定我是否理解这一点。

  1. 你能解决这个问题吗?有一个基类取得Enum的整数值,将Q&amp; A加载到一个集合中,然后在内存中将它拆分为Q'a和A的?这似乎更简单。

  2. 也许可以选择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);
    
  3. 您能否使用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();
    
  4. 注意:我的数据库表使用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; }
        }
    }