从数据库中读取对象的多态方式

时间:2014-02-08 04:16:37

标签: c# .net database-design types polymorphism

这是一个跟进:Best way to save type of class in database?,几乎是同一个问题,但是以更一般的方式。

我经常遇到必须将基类/接口对象保存到数据库的情况,我需要读回数据,实例化为 实际 具体对象并返回一个列表。

一个简单的演示可以更好地解释它。

interface IFeline
{
    Name;
}

class Leopard
{
    Name;
}

class Cheetah
{
    Name;
}

我会像这样保存到数据库:

IFeline felix = new Cheetah();
felix.Save(); //saved to db

现在我需要从db获取一个felines列表。

public IEnumerable<IFeline> GetThemAll()
{
     //connection
     //query command 
     //reader

     while(reader.Read())
         yield return new ... { } //how do I get the actual felines here?
}

我希望问题很清楚。 我没有针对每个具体类的单独表格它们都是通用的,一个表足以容纳它们。

我想从表中获取具体实例。我知道某种类型的信息必须与数据一起保存。我可以尝试一些方法,比如在db表中将类型保存为字符串,甚至枚举以表示数据库中的类型。 现在我的问题是,是否有解决此问题的通用方法/行业标准?

2 个答案:

答案 0 :(得分:1)

我不确定你是如何保存到数据库的。 您是序列化然后将其保存到数据库还是纯文本?

如果你是序列化,那么最简单的方法就是反序列化,你将获得适当的对象。

如果要将每个属性保存到数据库中的相应列,那么您需要拥有 一个额外的列来标识对象的类型。

while(reader.Read())

if type of object is 'Cheetah' then
  Cheetah oFeline = new Cheetah { Name = "Cheetah_A" };
  FelineList.Add(oFeline);

if type of object is 'Leopard' then
  Leopard oFelineL = new Leopard { Name = "Leopard_A" };
  FelineList.Add(oFelineL);

所以现在你有一个包含对象'Cheetah和Leopard'的列表

List<IFeline> FelineList = new List<IFeline>();

foreach (IFeline obj in FelineList) {
    if ((obj) is Cheetah) {
        ListBox1.Items.Add(obj.Name);
    }
}

我希望有所帮助!

答案 1 :(得分:1)

我不知道这是一种常见的方法还是行业标准,但我认为,正如您所提到的,您可以将Type和程序集字符串与数据一起保存。将它们取回后,您可以使用Activator返回正确类型的对象。

var assemblyName = reader["assembly_name"];
var typeName = reader["type_name"];

var instance = Activator.CreateInstance(assemblyName, typeName);
if (instance != null)
{
    var feline = instance.Unwrap();

    // reading object's properties

    yield return feline;
}