在EF数据库上下文中使用相同的c#模型两次

在EF数据库上下文中使用相同的c#模型两次,c#,entity-framework,orm,datamapper,C#,Entity Framework,Orm,Datamapper,我们有一个应用程序,其中一组复杂的数据模型保存在一个数据存储中——我们称之为单独的数据文件集。可以将这些数据文件调用到编辑器中进行更改,然后将更改保存回存储区。这个过程与从硬盘加载Excel文件、编辑然后选择“保存”或“另存为”没有什么不同 我们当前的应用程序设计将数据文件存储和数据文件编辑器分离为两个数据库和两个数据库上下文。通过这种方式,我们可以对存储和编辑器使用相同的C#模型,并且可以将编辑后的数据文件映射回存储,反之亦然。在最简单的情况下: 得到 A=B 拯救B 这样就不需要对属性进

我们有一个应用程序,其中一组复杂的数据模型保存在一个数据存储中——我们称之为单独的数据文件集。可以将这些数据文件调用到编辑器中进行更改,然后将更改保存回存储区。这个过程与从硬盘加载Excel文件、编辑然后选择“保存”或“另存为”没有什么不同

我们当前的应用程序设计将数据文件存储和数据文件编辑器分离为两个数据库和两个数据库上下文。通过这种方式,我们可以对存储和编辑器使用相同的C#模型,并且可以将编辑后的数据文件映射回存储,反之亦然。在最简单的情况下:

  • 得到
  • A=B
  • 拯救B
这样就不需要对属性进行1:1映射。对于更复杂的数据结构,它还使得A向B的注入相对容易

我们需要为存储和编辑器移动到单个数据库上下文

问题是-在单个数据库上下文中,我们能否将一个C#数据模型绑定到数据库中的两个独立数据表

下面是一个非常简单的例子,说明我们正在尝试做什么。这不起作用,因为EF试图将两个DbSet定义映射到一个表(称为数据文件)

/C#模型
名称空间MyApp.Models
{
公共部分类数据文件
{
公共int Id{get;set;}
public int MyDataField{get;set;}
公共字符串MyOtherDataField{get;set;}
}
}
//数据库绑定
公共类AppDbContext:DbContext
{
public AppDbContext():base(“name=AppDbContext”){}
//存储数据文件访问
公共虚拟数据库集StoreDataFiles{get;set;}
//主动数据文件访问
公共虚拟数据库集编辑器数据文件{get;set;}
公共静态应用程序上下文创建()
{
返回新的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");
            });
        }
    }

我为此准备了一个小控制台应用程序,并将其安装在上面。

我认为这是一个解决方案,可以满足您的需要,唯一需要注意的是,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");
            });
        }
    }

我为此制作了一个小控制台应用程序,并将其放在上面。

这里似乎有一个更好的解释,该建议似乎涵盖了两个表组合在一起以覆盖模型中的所有属性的情况。在我们的例子中,这两个数据库表是彼此的复制,并且都映射到模型中的所有属性?例如,如果您使用一个ID/GUID字段来区分两个同名的数据文件,会怎么样?是的,早在一开始,我们就开始使用这种方法,但在数据文件存在的位置和原因方面,它变得非常混乱。按照我们现在的方式,存储表只包含存储的数据。编辑器表仅包含当前可编辑的数据。。。但您已经了解了一些东西,也许我们可以考虑使用一些标识存储和编辑器的附加属性回到未来DataFiles@Xcheque“也许我们可以考虑回到未来”。。。我明白你在那里做了什么。这里似乎有一个更好的解释,建议似乎涵盖了两个表组合在一起以涵盖模型中的所有属性的情况。在我们的例子中,这两个数据库表是彼此的复制,并且都映射到模型中的所有属性?例如,如果您使用一个ID/GUID字段来区分两个同名的数据文件,会怎么样?是的,早在一开始,我们就开始使用这种方法,但在数据文件存在的位置和原因方面,它变得非常混乱。按照我们现在的方式,存储表只包含存储的da