未从数据库

时间:2017-09-03 02:12:36

标签: c# database entity-framework ado.net entity-framework-6

我正在玩Entity Framework 6 Code First,并且遇到多对多关系没有正确同步到我的内部"对象。

我得到了以下课程:

public class ClassA
{
    public String AId { get; set; }
    public ICollection<ClassB> Bs { get; set; }
    public ICollection<ClassC> Cs { get; set; }
}
public class ClassB
{
    public int BId { get; set; }
    ICollection<ClassA> As { get; set; }
}
public class ClassC
{
    public int CId { get; set; }
    public ClassA A { get; set; }
}

A和B具有多对多关系,其中A和C具有一对多的关系。我使用Fluent API来构建映射:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<ClassA>().ToTable("ClassA");
    modelBuilder.Entity<ClassA>().HasKey(a => a.AId);
    modelBuilder.Entity<ClassA>().HasManyClassB>(a => a.Bs).WithMany(b => b.As).Map(
            a =>
            {
                a.MapLeftKey("AId");
                a.MapRightKey("BId");
                a.ToTable("ClassAClassB");
            });

    modelBuilder.Entity<ClassA>().Property(a => a.OrderId).IsVariableLength().HasColumnName("AId");
    modelBuilder.Entity<ClassB>().ToTable("ClassB");
    modelBuilder.Entity<ClassB>().HasKey(b => b.BId);
    modelBuilder.Entity<ClassB>().Property(b => b.BId)
         .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
         .HasColumnName("BId");
    modelBuilder.Entity<ClassC>().ToTable("ClassC");
    modelBuilder.Entity<ClassC>().HasKey(c => c.CId);
    modelBuilder.Entity<ClassC>().HasRequired(c => c.A).WithMany(a => a.Bs).Map(m => m.MapKey("AId"));
    modelBuilder.Entity<ClassC>().Property(c => c.CId)    
         .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
         .HasColumnName("CId");
}

如果我创建类ClassA,ClassB和ClassC的对象,请将它们添加到我的数据库上下文并调用SaveChanges()。在我看来,值正确地存储在数据库中:

MariaDB [Test]> select * from ClassA;
+----------+
|   BId    |
+----------+
| 2017-002 |
+----------+

MariaDB [Test]> select * from ClassB;
+--------+
|   BId  |
+--------+
|    2   |
+--------+

MariaDB [OMSData]> select * from ClassAClassB;
+----------+-----+
|    AId   | BId |
+----------+-----+
| 2017-002 |  2  |
+----------+-----+

MariaDB [Test]> select * from classC;
+----+-----------+
| CId |    AId   |
+-----+----------+
|  1  | 2017-002 |
+-----+----------+

但是,如果我再次执行我的测试程序,则无法正确恢复关系。

这意味着:

  • ClassA中的B集合不包含任何对象(反之亦然)。
  • 如果我事先通过数据库上下文访问此对象,我只能通过ClassA访问ClassC的对象。

我是否必须手动调用同步或模型定义中是否有错误?

提前致谢!

2 个答案:

答案 0 :(得分:2)

对于与我面临同样问题的任何人,我的问题是我在相关实体中缺少virtual一词。据我所知,启用延迟加载时需要virtual,这有助于Entity Framework正确加载导航属性。希望对您有所帮助。

enter image description here

答案 1 :(得分:1)

您没有正确构建课程。从逻辑上讲,你需要在某处存储多对多的绑定,这意味着你需要一个存储多对多关系的第三个实体类。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

制作如下课程:

public class ClassA
{
    [Index(IsUnique = true)]
    [MaxLength(200)]
    public String AId { get; set; }
    public virtual List<AB> AB { get; set; }
    public List<ClassC> C { get; set; }
}
public class ClassB
{
    public int BId { get; set; }
    public virtual List<AB> AB { get; set; }
}
public class AB
{
    public int Id { get; set; }
    [Required]
    public virtual A A { get; set; }
    [Required]
    public virtual B B { get; set; }
    [MaxLength(200)]
    public string AId { get; set; }
    public int BId { get; set; }
}
public class ClassC
{
    public int CId { get; set; }
    public ClassA A { get; set; }
    public int AId { get; set; }
}

创建代码优先迁移,实体框架将理解这一点并相应地勾画出您的数据库。仅将A和B的ID存储在第三个实体AB中。