【发布时间】:2014-06-13 07:15:17
【问题描述】:
我正在设计一个 ASP.NET Web API 原型,它需要与几个几乎相同的数据库通信。我们的每个客户都有自己的数据库结构实例,但有些客户专门用于与他们拥有的其他系统集成。因此,例如在一个数据库中,Client 表可能具有列 AbcID 以引用另一个系统中的表,但其他数据库将没有此列。除此之外,这两个表的名称和列相同。列也可以有不同的长度,例如varchar(50) 而不是varchar(40)。在某些数据库中,可以有一个额外的表。我首先专注于解决不同列的问题。
我希望使用 ORM 来处理 API 的数据访问层,现在我正在尝试使用实体框架。我已经解决了如何通过 API 调用动态连接到不同的数据库,但现在它们必须在结构上完全相同。
我尝试使用数据库优先的方法设置双 .edmx 模型,但这会导致模型之间的类名冲突。所以我尝试了 Code-first 并想出了这个(这不起作用)。
DbContext 扩展: 在构造函数中,我检查正在访问哪个数据库,如果它是特殊数据库之一,我将其标记为模型配置。
public partial class MK_DatabaseEntities : DbContext
{
private string _dbType = "dbTypeDefault";
public DbSet<Client> Client { get; set; }
public DbSet<Resource> Resource { get; set; }
public MK_DatabaseEntities(string _companycode)
: base(GetConnectionString(_companycode))
{
if(_companycode == "Foo")
this._dbType = "dbType1";
}
// Add model configurations
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Configurations
.Add(new ClientConfiguration(_dbType))
.Add(new ResourceConfiguration());
}
public static string GetConnectionString(string _companycode)
{
string _dbName = "MK_" + _companycode;
// Start out by creating the SQL Server connection string
SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder();
sqlBuilder.DataSource = Properties.Settings.Default.ServerName;
sqlBuilder.UserID = Properties.Settings.Default.ServerUserName;
sqlBuilder.Password = Properties.Settings.Default.ServerPassword;
// The name of the database on the server
sqlBuilder.InitialCatalog = _dbName;
sqlBuilder.IntegratedSecurity = false;
sqlBuilder.ApplicationName = "EntityFramework";
sqlBuilder.MultipleActiveResultSets = true;
string sbstr = sqlBuilder.ToString();
return sbstr;
}
}
客户端配置:
在Client 的配置中,我在将属性映射到数据库列之前检查了该标志。 但这似乎不起作用。
public class ClientConfiguration : EntityTypeConfiguration<Client>
{
public ClientConfiguration(string _dbType)
{
HasKey(k => k.Id);
Property(p => p.Id)
.HasColumnName("ID")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
if (_dbType == "dbType1")
{
Property(p => p.AbcId).HasColumnName("AbcID");
}
Property(p => p.FirstName).HasColumnName("FirstName");
Property(p => p.LastName).HasColumnName("LastName");
}
}
客户端类:
这就是我的Client 班级的样子,这里没什么奇怪的。
public class Client : IIdentifiable
{
public int Id { get; set; }
public string AbcId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public interface IIdentifiable
{
int Id { get; }
}
备用解决方案是使用原始 SQL 查询来处理有问题的表,并使用 ORM 处理其余的表,但如果有一些我没有想到的方法来做到这一点,那就太棒了。现在我正在尝试实体框架,但我不反对尝试其他一些 ORM,如果它可以做得更好。
【问题讨论】:
-
你能有一个工厂来生成不同公司代码的模型配置吗?
-
你的意思是像下面建议的@JotaBe?是的,我想这可能会奏效。
标签: c# asp.net asp.net-mvc entity-framework orm