0

我刚开始测试Marten (2.9),到目前为止我很喜欢它。但是,我不确定我是否遵循该DocumentStore.For方法。例如,在 Marten 的“dbhandler”中,我可以这样写:

    public MartenDbHandler()
    {
        store = DocumentStore.For(_ =>
        {
            _.AutoCreateSchemaObjects = AutoCreate.CreateOrUpdate;
            _.Connection("host=localhost;database=marten;password=root;username=postgres");
            _.Schema.For<Customer>().Index(x => x.PopulationRegistryNumber);
        });
    }

但很自然,当我初始化数据库并提供连接字符串时,我不想拥有所有的模式代码。

所以我想,也许我可以传递store变量,然后做同样的事情,但是For事情不存在:

在此处输入图像描述

...而且我还没有真正找到以任何其他方式设置架构的方法。

我真正想做的是有一个接口,当我启动我的应用程序时,它会动态加载和执行(通过反射),它可以处理这些事情,就像一个IMartenMetaData看起来像这样的接口:

public interface IMartenMetaData
{
    SetMetaData(DocumentStore store);
}

然后在那个/那些类中实现模式的东西,但这不起作用,因为我不能使用 DocumentStore 来设置元。

4

2 回答 2

2

把事情简单化。文档存储应该在您的应用程序中有一个实例,并且您在构建期间定义架构属性。无需抽象存储。

一种方法是您可以创建自己的 DocumentStore 实现。您可以参考源代码中的测试文档存储类。

更新:您可以在这里找到示例https://github.com/JasperFx/marten/blob/master/src/Marten.Testing/TestingDocumentStore.cs

于 2018-08-16T00:20:56.560 回答
0

我设法做了一个很好的方法来保持它更加动态,而不是全部在 DocumentStore 的构建中。

请看下面的代码。这个想法很简单:1)单独创建 StoreOptions 2)在创建 DocumentStore 之前,运行通过反射找到将添加表元数据的特定类型的所有类的方法 3)创建 DocumentStore

public MartenDbHandler()
{
    StoreOptions so = new StoreOptions();
    so.Connection("host=localhost;database=marten;password=root;username=postgres");
    so.AutoCreateSchemaObjects = AutoCreate.CreateOrUpdate;
    SetTableMeta(so);
    store = new DocumentStore(so);
}

private void SetTableMeta(StoreOptions storeOptions)
{
    // We get the current assembly through the current class
    var currentAssembly = Assembly.GetExecutingAssembly();
    // we filter the defined classes according to the interfaces they implement
    var stuff = currentAssembly.DefinedTypes.Where(type => type.IsSubclassOf(typeof(MartenTableMetaDataBase))).ToList();

    foreach (Type type in stuff)
    {
        IMartenTableMetaData temp = (IMartenTableMetaData)Activator.CreateInstance(type);
        temp.SetTableMetaData(storeOptions);
    }
    OnLogEvent?.Invoke(this, $"{stuff.Count} table meta data initialized");
}

IMartenTableMetaData 是 IMartenTableMetaData 接口的基类。在下面的示例中,没有使用基类,但我通常觉得有一个基类很好(我使用与另一个 ORM 类似的方法,我实际上使用了基类)。但是,如果您对它没有用处,可以删除基类。

internal abstract class MartenTableMetaDataBase : IMartenTableMetaData
{
    public void SetTableMetaData(StoreOptions storeOptions)
    {
        SetSpecificTableMetaData(storeOptions);
    }

    protected abstract void SetSpecificTableMetaData(StoreOptions storeOptions);
}

和界面:

public interface IMartenTableMetaData
{
    void SetTableMetaData(StoreOptions storeOptions);
}

所以,我现在可以为我想添加元数据的每个类型创建一个类,如下所示:

internal class MartenTableMetaDataCustomer : MartenTableMetaDataBase
{
    protected override void SetSpecificTableMetaData(StoreOptions storeOptions)
    {
        storeOptions.Schema.For<Customer>().Index(x => x.Muni);
    }
}

或者

internal class MartenTableMetaDataDriver : MartenTableMetaDataBase
{
    protected override void SetSpecificTableMetaData(StoreOptions storeOptions)
    {
        storeOptions.Schema.For<Driver>().Index(x => x.Username);
    }
}

等等

这将使 Marten DB 处理程序保持干净,并将元数据分成特定的类,以提高可读性、清晰度和所有这些 =)

希望能帮助到你。

于 2018-08-17T01:53:16.793 回答