1

添加具有 1 级一对多关系的实体非常简单。

using (var dbCtx = new DbContext())
{
    dbCtx.Stuff.Add(myObject);
    dbCtx.SaveChanges();
}

但是如何添加具有 2 个级别的对象?以同样的方式添加它省略了 2. 级别。这意味着没有保存 Bar 对象(在下面的示例中)。我究竟做错了什么?

对象图

继承的对象

public class BaseEntity
{
    public int Id;
    // Omitted properites...
}

public class MyEntity : BaseEntity
{
    // Omitted properites...

    // Navigation properties
    public virtual ICollection<Foo> Foos { get; set; }
}

嵌套对象(1:M)

public class Foo // 1. level
{
    public int Id;
    public int MyEntityId;

    // Omitted properites...

    // Navigation properties
    public virtual ICollection<Bar> Bars { get; set; }
    public virutal MyEntity MyEntity { get; set; }
}

public class Bar // 2. level
{
    public int Id;
    public int FooId;

    // Omitted properites...

    // Navigation properties
    public virutal Foo Foo { get; set; }
}

使用 fluent API 进行映射设置

继承的对象

public class BaseEntityMap : EntityTypeConfiguration<BaseEntity>
{
    public BaseEntityMap()
    {
        // Primary Key
        this.HasKey(t => t.Id);

        // Properties
        // Table & Column Mappings
        this.ToTable("BaseEntitySet");
        this.Property(t => t.Id).HasColumnName("Id");
        // ...
    }
}

public class MyEntityMap : EntityTypeConfiguration<MyEntity>
{
    public MyEntityMap()
    {
        // Table & Column Mappings
        this.ToTable("BaseEntitySet_MyEntities");
    }
}

嵌套对象(1:M)

public class FooMap : EntityTypeConfiguration<Foo>
{
    public FooMap()
    {
        // Primary Key
        this.HasKey(t => t.Id);

        // Table & Column Mappings
        this.ToTable("FooSet");
        this.Property(t => t.Id).HasColumnName("Id");
        this.Property(t => t.MyEntityId).HasColumnName("MyEntity_Id");

        // Relationships
        this.HasRequired(t => t.MyEntity)
            .WithMany(t => t.Foos)
            .HasForeignKey(d => d.MyEntityId);
    }
}

public class BarMap : EntityTypeConfiguration<Bar>
{
    public BarMap()
    {
        // Primary Key
        this.HasKey(t => t.Id);

        // Table & Column Mappings
        this.ToTable("BarSet");
        this.Property(t => t.Id).HasColumnName("Id");
        this.Property(t => t.FooId).HasColumnName("Bar_Id");

        // Relationships
        this.HasRequired(t => t.Foo)
            .WithMany(t => t.Bars)
            .HasForeignKey(d => d.FooId);
    }
}

存储库

public void Add(BaseEntity item)
{
    using (var ctx = new DbContext())
    {
        ctx.BaseEntities.Add(item);
        ctx.SaveChanges();
    }
}
4

1 回答 1

0

\想发布我的答案以防它对其他人有帮助,因此专家可以将其撕成碎片并发布真正的答案。对我来说,它并没有突然开始工作:)

如果我正确理解了您的对象图,则 MyEntity 有 Foos 有 Bars。我有一个类似的结构,但是当调用“SaveChanges”时,会抛出一个 DbUpdateException 并显示一条消息

“多个实体可能具有相同的主键。”

以下是我如何让它为我工作:

第 1 步:将 Id 属性从 int 更改为 int?并将它们初始化为空。对我来说,这是一个比普通整数更准确的模型。当一个实体是新的时,ID 字面意思是“未定义或未知”。0 是一个定义的数字,由于某种原因,EF 存在 ID 相同的问题,即使在添加记录时也是如此。

public class BaseEntity
{
    public BaseEntity()
    {
        this.Id = null;
    }

    public int? Id;
    // Omitted properites...
}

public class Foo
{
    public Foo()
    {
        this.Id = null;
    }

    public int? Id;
}

public class Bar
{
    public Bar()
    {
        this.Id = null;
    }

    public int? Id;
}

第 2 步:将“DatabaseGeneratedOption.Identity”标志添加到映射中的 Id 属性。我相信这可以防止在将实体添加到数据上下文的情况下“需要”它。

public class BaseEntityMap : EntityTypeConfiguration<BaseEntity>
{
    public BaseEntityMap()
    {
        // Primary Key
        this.HasKey(t => t.Id);

        // Properties
        // Table & Column Mappings
        this.ToTable("BaseEntitySet");
        this.Property(t => t.Id).HasColumnName("Id")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        // ...
    }
}

public class FooMap : EntityTypeConfiguration<Foo>
{
    public FooMap()
    {
        // Primary Key
        this.HasKey(t => t.Id);

        // Table & Column Mappings
        this.ToTable("FooSet");
        this.Property(t => t.Id).HasColumnName("Id")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        this.Property(t => t.MyEntityId).HasColumnName("MyEntity_Id");

        // Relationships
        this.HasRequired(t => t.MyEntity)
            .WithMany(t => t.Foos)
            .HasForeignKey(d => d.MyEntityId);
    }
}

public class BarMap : EntityTypeConfiguration<Bar>
{
    public BarMap()
    {
        // Primary Key
        this.HasKey(t => t.Id);

        // Table & Column Mappings
        this.ToTable("BarSet");
        this.Property(t => t.Id).HasColumnName("Id")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        this.Property(t => t.FooId).HasColumnName("Bar_Id");

        // Relationships
        this.HasRequired(t => t.Foo)
            .WithMany(t => t.Bars)
            .HasForeignKey(d => d.FooId);
    }
}
于 2013-09-25T13:14:29.187 回答