我们有一个应用程序,其中一组复杂的数据模型存储在数据存储区中-我们称数据的单个组为DataFiles。可以将这些DataFiles调用到编辑器中进行更改,然后将其保存回存储中。此过程与从硬盘加载Excel文件,进行编辑然后选择另存为不同。
我们当前的App设计将DataFile存储和DataFile编辑器分为两个数据库和两个数据库上下文。这样,我们可以对商店和编辑器使用相同的C#模型,并且可以对编辑的DataFile做一些非常简单的映射,将其映射回商店,反之亦然。在最简单的情况下:
这消除了对属性进行1:1映射的需要。对于更复杂的数据结构,这也使得将A注入B相对容易
我们需要为商店和编辑器转移到单个数据库上下文。
问题是-在单个数据库上下文中,我们可以将一个C#数据模型绑定到数据库的两个单独的数据表吗?
这是我们正在尝试做的一个非常简单的例子。这不起作用,因为EF尝试将两个DbSet定义都映射到一个表(称为DataFile)
// C# model
namespace MyApp.Models
{
public partial class DataFile
{
public int Id { get; set; }
public int MyDataField { get; set; }
public string MyOtherDataField { get; set; }
}
}
// Database binding
public class AppDbContext : DbContext
{
public AppDbContext() : base("name=AppDbContext"){}
// Store Data File Access
public virtual DbSet<DataFile> StoreDataFiles { get; set; }
// Active Data File Access
public virtual DbSet<DataFile> EditorDataFiles { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
我认为这是一个解决方案,可以满足您的需求,唯一的警告是ID字段在两个表中都必须是唯一的,并且您需要自己处理。除此之外,此技术源自此处的“每种具体类型的表”。
我们要做的是使用您的类型具有的属性创建一个抽象类,并从中继承它。这应该使两个类保持同步,并且可以通过来回转换来获得一个或另一个。这里重要的是DatabaseGeneratedAttribute
设置为“ None”;使用此技术,由于两个表将具有相同的PK,EF无法说出它需要在表之间共享它们。
父类必须是抽象的。至少,这是我可以将其识别为DbSet而不为其创建表的唯一方法。
public abstract class DataFileParent
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
public int MyDataField { get; set; }
public string MyOtherDataField { get; set; }
}
public class DataFileEditor : DataFileParent
{
}
public class DataFileStore : DataFileParent
{
}
现在,我们可以创建我们的Context
类,只有一个类DbSet
可以在表之间共享。我们还将告诉上下文我们要根据实体的具体类型将实体映射到不同的表,这是通过OnModelCreating
方法完成的。
public class Context : DbContext
{
public DbSet<DataFileParent> DataFileParents { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<DataFileEditor>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("DataFileEditor");
});
modelBuilder.Entity<DataFileStore>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("DataFileStore");
});
}
}
就是这样!现在,当您想要创建DataFileStore
或时,DataFileEditor
您可以这样做,并添加以下内容:(假设Store
是type的变量DataFileStore
)
using (var db = new Context())
{
db.DataFileParents.Add(Store);
db.SaveChanges();
}
为此,我整理了一个小的控制台应用程序,并将其放在GitHub上。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句