首页 文章

我可以将两个实体映射到两个不同的表吗?

提问于
浏览
0

我正在使用EF和Code First . 我尝试将两个实体映射到两个不同的表 . 首先,我尝试将Material映射到表Materials,然后我尝试将PlannedMaterial映射到Materials和ScheduleRows .

一个ScheduleRow需要在Materials表中有一行Foreigtn键 . 从Materials表到ScheduleRows表没有外键 .

这些是我的实体 .

public class Material
{
    public int Id { get; set; }  // from material table
    public string Name { get; set; }  // from material table

    // public PlannedMaterial PlannedMaterial { get; set; } Do I need this? I don't want a relation from this side.
}

public class PlannedMaterial
{
    public int Id { get; set; }  // from *ScheduleRow table*
    public string Name { get; set; } // from *material table*
    public int SequenceNo { get; set; } // from *ScheduleRow* table

    public Material Material { get; set; } // Do I need this? I'm only interrested in the Name column from the material table
}

这些是我的 table .

CREATE TABLE [dbo].[RunScheduleRow](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [SequenceNo] [int] NOT NULL,
    [Material_id] [int] NOT NULL)  -- FK to Material table


 CREATE TABLE [dbo].[Material](
    [Id] [int] NOT NULL,
    [Name] [nvarchar](max) NULL)

我想在OnModelCreating(DbModelBuilder模型构建器)中使用流畅的API进行映射 . 可能吗?怎么样?

我感谢所有的想法和建议 .

2 回答

  • 0

    我觉得你的设计并不好 . 您尝试管理ScheduleRow和Material Tables之间的关系,但这种关系可以由实体框架管理 .

    public class Material
    {
        public int Id { get; set; }  // from material table
        public string Name { get; set; }  // from material table
       public ICollection<ScheduleRow> ScheduleRows{ get; set; }
    
    }
    
    public class ScheduleRow
    {
        public int Id { get; set; }  // from *ScheduleRow table*
          public int SequenceNo { get; set; } // from *ScheduleRow* table
    
        public Material  Material { get; set; } 
    }
    

    配置你的shcema

    public class YourContext: DbContext 
    {
        public SchoolDBContext(): base() 
        {
        }
    
        public DbSet<Material> Materials { get; set; }
        public DbSet<ScheduleRow> ScheduleRows { get; set; }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //Configure default schema
            modelBuilder.HasDefaultSchema("YourShema");
        }
    }
    

    将实体映射到表

    namespace CodeFirst_FluentAPI_Tutorials {

    public class YourContext: DbContext 
        {
            public YourDBContext(): base() 
            {
            }
    
            public DbSet<Material> Materials { get; set; }
            public DbSet<ScheduleRow> ScheduleRows { get; set; }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                    //Configure default schema
                modelBuilder.HasDefaultSchema("YourSchema");
    
                //Map entity to table
                modelBuilder.Entity<Material>().ToTable("Material");
                modelBuilder.Entity<ScheduleRow>().ToTable("RunScheduleRow","dbo");
    
            }
        }
    }
    

    要配置列名称,请将此指令添加到上下文中

    modelBuilder.Entity<YourEntity>()
                        .Property(p => p.propertyname)
                        .HasColumnName("Caolum_name")
                        .HasColumnOrder(your_column_order)
                        .HasColumnType("column_type");
    

    希望对你有所帮助 .

  • 0

    在您跳到解决方案之前,请阅读此内容,它将阐明EF实体的用户身份,因为我可以向您保证,这不是您认为的那样 .

    Rules of EF:

    • 像您这样的EF实体必须可以转换为SQL表 .

    • 与其他对象的数据链接相同 . 例如,如果您创建自己的类型,则不会本机支持 .

    • 同样适用于查询 . 在EF中,使用的列表类型主要是IEnumerable(只读)和ICollection(读/写) . 如果您再也不会再次发布回数据库,那么使用数组和列表等是可以接受的

    So what are you missing? 你我的好先生,缺少规则1,所以你必须 Build 一个软实体(常规DTO /模型/类)

    有点像这样 . 但请注意,现在PlannedMaterial不会保存在任何地方 .

    public class PlannedMaterial
    {
        public PlannedMaterial(ScheduleRow s, Material m){
            ScheduleRow = s;
            Material = m;
        }
        public int Id { get{return _s.Id; } set{_s.Id = value;} }
        public string Name { get{return _m.Name; } set{_m.Name = value; }
        public int SequenceNo { get{return _s.SequenceNo; } set{_s.SequenceNo = value; } 
    
        Material _m{ get; set; }
        ScheduleRow _s{ get; set; }
    }
    

    以下是如何处理您的实体

    public class Material
    {
        public int Id { get; set; }
        public string Name { get; set; }
    
        public virtual ICollection<ScheduleRow> ScheduleRows { get; set; } 
    }
    
    public class ScheduleRow 
    {
        public int Id { get; set; }
        public int SequenceNo { get; set; }
    
        public virtual Material Material { get; set; } 
    }
    

    上下文(参见构建器)

    public class YourContext: DbContext 
    {
        public SchoolDBContext(): base() 
        {
        }
    
        public DbSet<Material> Materials { get; set; }
        public DbSet<ScheduleRow> ScheduleRows { get; set; }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //Fluent API
            modelBuilder.Entity<Material>()
                .HasMany(e => e.ScheduleRow)
                .WithRequired(e => e.Material)
                .HasForeignKey(e => e.Id)
                .WillCascadeOnDelete(false);
    
            base.OnModelCreating(modelBuilder);
        }
    }
    

    链接:FluentAPI

相关问题