这是一个跟进: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表中将类型保存为字符串,甚至枚举以表示数据库中的类型。 现在我的问题是,是否有解决此问题的通用方法/行业标准?
答案 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;
}