如何根据数据库中存储的内容创建正确的继承类
本文关键字:创建 继承 数据库 存储 何根 | 更新日期: 2023-09-27 18:32:08
可以使用
什么实用程序或模式来解决此问题? 我不知道可以用来协助解决这个问题。 我们可以使用某种类型的模式吗?
如果您有以下抽象类:
abstract class Foo
{
function void Something()
{
// Get the media type
}
}
以及从该类派生的以下类:
class Foo1 : Foo
{
public string MyId {get;set}
public string MyFile {get;set}
public TxtFile MyTextFile {get;set}
function void myFooFunction()
{
// Save File to Txt
}
}
class Foo2 : Foo
{
public string MyId {get;set}
public string MyFile {get;set}
public XMLFile MyXMLFile {get;set}
function MyOtherFunction()
{
// Save to XML
}
}
然后在存储库的 Linq(或类似)中,您可以执行以下操作:
var a = (from e in db.myTable
where e.myFileType == "XML"
Select e);
然后我们必须将其映射到正确的对象。喜欢这个:
Foo newFoo = FooFactory.CreateFooFor(a.myFileType.ToString())
newFoo.MyId = a.id;
newFoo.MyFile = a.myfile;
newFoo.MyXMLFile = a.xml;
工厂当然有帮助,但是您如何为多个"文件类型"(例如txt)执行此操作? 田野不匹配!
我是否必须编写更多执行相同操作的代码?我觉得一定有一些东西可以做到这一点。
首先,如果myFooFunction
和MyOtherFunction
都用于保存,则可以使用策略模式,只需定义和抽象Save()
方法即可在派生类中实现。您还可以查看模板方法模式。
尽管这不完全是一种模式,但您可能还希望在此处应用"上拉字段"重构,并将MyId
和MyFile
属性放在父类中。
为了创造...
生成器模式类似于工厂,但允许创建更复杂的对象。我不知道它与这个简化示例的契合度如何,但它可能适合您在实际代码中实际尝试执行的操作。应该不会。我只是先提到它,因为它是我心目中最接近工厂的。
还有映射器模式和数据映射器模式。您可以将映射封装在对象中,并让工厂返回映射器:
FooMapper mapper = FooMapperFactory.CreateFooMapperFor(a.myFileType);
Foo newFoo = mapper.CreateFoo(a);
我相信
你可以使用泛型来解决你的问题。我冒昧地更改了一些代码。 这行得通吗?
public abstract class Foo
{
public abstract void Save();
public void Something()
{
// Get the media type
}
}
public class FooText : Foo
{
public string MyId { get; set; }
public string MyFile { get; set; }
public string MyTextFile { get; set; }
public override void Save()
{
// Save File to Txt
}
}
public class FooXml : Foo
{
public string MyId { get; set; }
public string MyFile { get; set; }
public string MyXMLFile { get; set; }
public override void Save()
{
// Save to XML
}
}
public class FooFactory<T> where T : Foo, new()
{
public static T CreateFoo()
{
return new T();
}
}
如果您考虑对从数据库返回的数据或适配器模式使用反射,则可以设置一种动态方法来将字段映射到彼此。使用反射(以下是伪逻辑,因为反射是一种混乱的代码提供):
- 从目标类型获取所有公共属性的 PropertyInfo 对象列表
- 从数据库类型中获取所有公共属性的 PropertyInfo 对象列表
- 比较它们的名称/类型以创建映射
- 使用反射将数据库类型的值分配给目标类型
像这样的东西就可以了:
public void AssignAndMapTypes<DatabaseType, TargetType>(DatabaseType db, ref TargetType target)
{
var dbType = db.GetType();
var dbTypeProperties = dbType.GetProperties(System.Reflection.BindingFlags.Public);
var targetType = target.GetType();
var targetTypeProperties = targetType.GetProperties(System.Reflection.BindingFlags.Public);
foreach (var prop in targetTypeProperties)
{
var matchingProp = dbTypeProperties.Where(e => { return (string.Compare(e.Name, prop.Name, true) == 0) && (e.PropertyType == prop.PropertyType) }).FirstOrDefault();
if(matchingProp != null)
{
prop.SetValue(target, matchingProp.GetValue(db, null), null);
}
}
}