C#Entity Framework嵌套成员在一行

时间:2016-09-16 22:45:51

标签: c# entity-framework

我是实体框架的新手,我希望将嵌套成员存储在数据库中,但是所有这些成员都在一行中(我有很多嵌套成员,并且不希望有这么多表)。

我发现,使用内部类的工作方式完全符合我的要求,例如:

public class ClassA
{
    [Key]
    public int id { get; set; }
    public int x { get; set; }
    public int y { get; set; }

    public virtual ClassB B {get;set;}
    public virtual ClassC C { get; set; }

    public class ClassB
    {
        public int b { get; set; }
    }

    public class ClassC
    {
        public int c { get; set; }
    }
}

这实际上是我想要的,但有一个问题:内部类不能为空。例如:

ClassA a = new ClassA();
a.B = new ClassA.ClassB();
a.B.b = 10;
a.C = null;

引发异常“非可空成员的空值”。 是否可以(例如使用注释)使其可以为空?

非常感谢!

2 个答案:

答案 0 :(得分:0)

您已使用ClassB和ClassC作为导航属性。 你可以添加一个外键属性。

public int? ClassCId { get; set; }

在dbcontext类中,您可以使用流畅的api而不是数据注释为ClassA添加此关系。流畅的api可以让您更好地控制创建关系。

   protected override void OnModelCreating(DbModelBuilder modelBuilder)
    { 
       modelBuilder.Entity<ClassA>()
           .HasOptional(c => c.ClassC)
           .WithMany()
           .HasForeignKey(c => c.ClassCId)
           .WillCascadeOnDelete(false);

       base.OnModelCreating(modelBuilder);
    }

你可以为ClassB做同样的事情。

答案 1 :(得分:0)

如果要将嵌套成员存储在一行中(主成员的同一行,在您的情况下为ClassA),则必须将它们标记为ComplexTypes。

[ComplexType]
public class ClassB
{
    public int b { get; set; }
}

[ComplexType]
public class ClassC
{
    public int c { get; set; }
}

在这种情况下,ClassA表中将包含ClassB和ClassC的列 要使用此配置,您需要属性ClassA.B和ClassA.C始终不为null,但您可以将ClassB和ClassC属性(b和c)标记为可为空。

当我使用复杂类型时,我使用与此类似的模型

public class ClassA
{
    public ClassA()
    {
        // Create Always complex type instances
        B = new ClassB();
        C = new ClassC();
    }

    [Key]
    public int id { get; set; }
    public int x { get; set; }
    public int y { get; set; }

    public ClassB B { get; set; } // virtual is not required by EF because this property won't be lazy loaded
    public ClassC C { get; set; }

    [ComplexType]
    public class ClassB
    {
        public int? b { get; set; }
    }

    [ComplexType]
    public class ClassC
    {
        public int? c { get; set; }
    }
}

关于可以为空的ComplexTypes,你可以看看这里 Complex Types of Nullable Values
Required Properties on optional Entity Framework Complex Types

否则,您可以拥有更多(在您的情况下为几个)具有1-1关系的表格 您可以在堆栈溢出时搜索此配置。如果B和C属性通常为null并且ClassB和ClassC具有多个属性,则此配置在写入期间也可能更有效(它取决于DBMS和块长度)。