如何根据数据库中存储的内容创建正确的继承类

本文关键字:创建 继承 数据库 存储 何根 | 更新日期: 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)执行此操作? 田野不匹配!

我是否必须编写更多执行相同操作的代码?我觉得一定有一些东西可以做到这一点。

如何根据数据库中存储的内容创建正确的继承类

首先,如果myFooFunctionMyOtherFunction都用于保存,则可以使用策略模式,只需定义和抽象Save()方法即可在派生类中实现。您还可以查看模板方法模式。

尽管这不完全是一种模式,但您可能还希望在此处应用"上拉字段"重构,并将MyIdMyFile属性放在父类中。

为了创造...

生成器模式类似于工厂,但允许创建更复杂的对象。我不知道它与这个简化示例的契合度如何,但它可能适合您在实际代码中实际尝试执行的操作。应该不会。我只是先提到它,因为它是我心目中最接近工厂的。

还有映射器模式

和数据映射器模式。您可以将映射封装在对象中,并让工厂返回映射器:

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