我刚刚开始测试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来设置元。
答案 0 :(得分:1)
保持简单。该文档存储应该在您的应用程序中具有一个实例,并且您可以在构建期间定义架构属性。无需抽象商店。
一种方法是您可以创建自己的DocumentStore实现。您可以在源代码中引用测试文档存储类。
更新: 您可以在https://github.com/JasperFx/marten/blob/master/src/Marten.Testing/TestingDocumentStore.cs
中找到示例答案 1 :(得分:0)
我设法采取了一种很好的方法来使它更具动态性,而不是在DocumentStore的构建过程中全部如此。
请参见下面的代码。这个想法很简单: 1)分别创建StoreOptions 2)在创建DocumentStore之前,运行方法通过Reflection找到某个特定类型的所有类,这些类将添加表元数据 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);
}
因此,我现在也可以为每个要添加元数据的Type创建一个类,如下所示:
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处理程序保持干净,并将元数据分为特定的类,以提高可读性,清晰度和所有这些东西=)
希望有帮助。