我在想哪种是使用不同数据库的模型定义的最佳方法。 我有几个共享相同对象的项目。第一个项目使用 SQlite 数据库,而第二个项目使用实体框架。
所以考虑这个对象定义:
[Table("Members")] <---- Specific attribute of Sqlite
class Person
{
[PrimaryKey] <---- Specific attribute of Sqlite
public Guid Id {get; set;}
public string Name {get; set;}
[Ignore] <---- Specific attribute of Sqlite
public int Age {get; set;}
}
现在,如果我想重用此定义,我必须删除 Sqlite 属性并使用 Entity Framework 属性更改它们。
我应该像这样创建一个 BasePerson 对象吗
class Person
{
public Guid Id {get; set;}
public string Name {get; set;}
public int Age {get; set;}
}
然后根据使用的数据库派生子对象,如下所示覆盖属性?
using Sqlite;
[Table("Members")]
class PersonSqlite : Person
{
[PrimaryKey]
public override Guid Id {get; set;}
[Ignore]
public override int Age {get; set;}
}
using EntityFramework;
[Table("Members")]
class PersonEF : Person
{
[Key]
public override Guid Id {get; set;}
[Ignore]
public override int Age {get; set;}
}
让我知道你对此的想法。
如果您使用实体框架来定义模型,无论是使用 Fluent API 还是数据注释,您应该能够在所有支持的数据库(包括 SQLite)中使用该模型。您应该只需要在配置实体框架时更改数据库提供程序。
这是假设所有项目实际上都使用实体框架,而不是其他 ORM 或完全不同的访问方法,如 ADO.NET。如果是这种情况,您可以在同一个类上使用多个属性,则只需在属性中包含命名空间即可:
[Sqlite.Table("Members")]
[EntityFramework.Table("Members")]
class Person
但是,如果有人忘记一个属性或另一个属性,这会增加不一致的风险。在项目之间调动开发人员时可能会导致培训问题。因此,我可能会建议对所有项目使用相同的数据库访问方法。
请注意,可能有一些数据库特定的功能不适用于其他数据库。但表名、键和忽略对于所有数据库来说应该是通用的。
答案是用于配置的流畅API:
public class PersonEntityTypeConfiguration : IEntityTypeConfiguration<Person>
{
public void Configure(EntityTypeBuilder<Person> builder)
{
builder.Ignore(b => b.Age);
}
}
将按照约定获取 ID。很多东西都是按照惯例配置的,我建议阅读一下。
此配置的大部分对于所有数据库都是通用的。如果您需要执行一些特定于数据库的配置,您可以注入您
IConfiguration
并执行以下操作:
if(configuration.IsPostgres())
{
builder.DoSomethingPostgresSpecific();
}
if(configration.IsSqlLite())
{
builder.DoSomethingSqliteSpecific();
}
IsPostgres()
和IsSqlite()
不存在——你必须弄清楚如何检测它。如果你想让它更容易,你可以将 DbKind
属性放入 appSettings.json 中。
从系统中选择*。
x$io_global_by_file_by_latency
从系统中选择*。statements_with_full_table_scans
从系统中选择*。x$schema_table_statistics
[表(“成员”)]
PersonEF 类:人
{其中年龄=48;
[按键] 公共覆盖 Guid Id {get;设置;}
[忽略]
公共覆盖 int Age {get;放;}
从键值中选择 *
其中年龄 = 15+,
当局部性 = jpp 时,
服务车道1
协议 FD = 16;
}