Entity Framework 6如何处理复杂的null对象?

时间:2017-05-11 20:48:31

标签: c# sql-server entity-framework

我在Code First Entity Framework 6项目类中有一个复杂的对象,如下所示:

public class myobject
{
  [Key]
  public int? id { get; set; } = null;
  public reason myreason { get; set; } // = new reason(); (1)
}
// [NotMapped] (2)
public class reason
{
  // [Key] (3)
  // public int? id { get; set; } = null; (3)
  public string reason { get; set; }
  public string value { get; set; }
}

我还有以下背景:

public class context : DbContext
{
  public context() : base("name=DataModel")
  {

  }
  public virtual DbSet<myobject> myObjectDb { get; set; }
  // public virtual DbSet<reason> myReasonDb { get; set; } (3)
}

所以当它像这样设置时,我得到一个如下所示的数据库表:

TABLE: myobject
INT (PRIMARY KEY): id
NVARCHAR(MAX): reason_reason (nullable)
NVARCHAR(MAX): reason_value (nullable)

但是,当我尝试将数据写入数据库时​​,如下所示:

var obj = new myobject();

using (var db = new context())
{
  // myobject.myreason = new reason(); (4)
  db.myobject.Add(obj);
  db.SaveChanges();
}

我明白了:

System.Data.Entity.Infrastructure.DbUpdateException: 'Null value for non-nullable member. Member: 'reason'.'
UpdateException: Null value for non-nullable member. Member: 'reason'.

所以我做了很多事情,我明白你在EF中不能有复杂的类型。我不完全清楚这些东西是否已经在EF6或旧版本中消失了。主要是,如果不允许空值,我会混淆b / c,为什么EF会在数据库中创建字段并使它们可以为空?这看起来很奇怪。

无论如何,如果我不评论上面的评论(1),这通常是我将如何处理这个问题,我仍然会遇到同样的问题。我认为这将确保在reason为空的情况下,它至少会有一个默认对象,虽然是空值,但可能不是很大的b / c它们是字符串。

所以我还发现,如果我取消评论上面的评论(2),这实际上会导致两个字段完全从数据库中删除(正如预期的那样,NotMapped)。我不再收到错误,但我也没有收到数据。

接下来我试着取消评论标记为(3)的评论,现在我得到了我的两个值,但它们完全是在新表中。同样,这是有道理的,代码将运行。但是,我正在寻找的是第一个版本的扁平格式,只是处理null对象的能力。

然后我回去了,而不是那个,我在实例化之后添加了new reason();,就像上面的注释(4)一样。这实际上是有效的,最初DB中的2个字段作为设置。所以这很有效。

我想我的问题是为什么(1)不起作用,但(4)有效吗?他们似乎应该完成相同的事情,虽然如果我这样做(4)然后我必须在每次实例化后执行此操作,而且,如果它首先为空,我必须检查每个值,b / c如果它已经有数据,我会覆盖。

此外,这是一个简单的例子,只有一个对象,我有一个更复杂的情况,有数百个。

任何帮助都会很棒!我完全迷失了。

我希望这是一个非常简单的解决方案,而且我错过了一些非常愚蠢的错误。

0 个答案:

没有答案