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



这是一个跟进:在数据库中保存类型的最佳方法?

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

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

interface IFeline
{
    Name;
}
class Leopard
{
    Name;
}
class Cheetah
{
    Name;
}

我会这样保存到数据库:

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

现在,我需要从DB中获取一份猫的清单。

public IEnumerable<IFeline> GetThemAll()
{
     //connection
     //query command 
     //reader
     while(reader.Read())
         yield return new ... { } //how do I get the actual felines here?
}

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

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

我不知道这是一种常见的方法还是行业标准,但是我认为,正如您提到的,您可以保存类型和汇编字符串以及数据。让它们恢复时,您可以使用激活剂返回这样的对象类型。

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;
}

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

如果您要序列化,那么最简单的方法是应得,您将获得适当的对象。

如果要将每个属性保存到数据库中的适当列,则需要额外的一列以识别对象的类型。

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);

所以现在您有一个列表,其中包括对象的"猎豹和豹"

List<IFeline> FelineList = new List<IFeline>();
foreach (IFeline obj in FelineList) {
    if ((obj) is Cheetah) {
        ListBox1.Items.Add(obj.Name);
    }
}

我希望有帮助!

最新更新