我设法做了一个很好的方法来保持它更加动态,而不是全部在 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 处理程序保持干净,并将元数据分成特定的类,以提高可读性、清晰度和所有这些 =)
希望能帮助到你。