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

本文关键字:两个 实体 我可以 映射 | 更新日期: 2024-09-08 04:34:17

我使用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
}

这些是我的桌子。

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(DbModelBuildermodelBuilder)中使用流畅的API进行映射。有可能吗?怎样

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

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

我认为你的设计不好。您试图管理ScheduleRow和Material表之间的关系,但这种关系可以通过实体框架来管理。

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");
    }
}

将实体映射到表

命名空间代码First_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");

希望对你有所帮助。

在您跳到解决方案之前,请阅读本文,它将阐明EF实体的用户用途,因为我可以向您保证,它不是您认为的那样。

EF规则:

  1. 类等EF实体必须可转换为SQL表
  2. 来自其他对象的数据链接也是如此。例如,如果您制作自己的类型,则本机将不支持该类型
  3. 查询也是如此。在EF中,使用的列表类型主要是IEnumerable(只读)和ICollection(读/写)。如果您再也不发布回数据库,那么使用数组和列表等是可以接受的。¨

那么你错过了什么我的好先生,你错过了第一条规则。所以你必须制作一个软实体(常规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