实体框架代码首次更新了卸载所需导航属性的错误

时间:2011-12-15 10:21:07

标签: entity-framework ef-code-first

我发现,如果我根据需要设置导航属性(使用Required属性)并使用延迟加载代理,当我加载父实体并且除了尝试保存在同一上下文中什么也不做之外,会发生EntityValidationError这就像“需要xxx字段”。

使用Java中的hibernate和.NET中的NHibernate,可以只获取没有导航属性的实体(所有延迟加载),更新它并再次保存。该框架意识到导航引用没有任何改变,也不会抛出任何错误。

示例如下

[Table("Address")]
public class Address
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int AddressId { get; set; }

    [Required, StringLength(512)]
    public virtual string AddressLine1 { get; set; }
}

[Table("User")]
public class User
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }

    [Required]
    public string Name {get; set;}

    [Required]
    public virtual Address Address {get; set;}


}


void LoadAndSaveUser() {
    var user = Context.Users.First();
    user.Name = "foo";

    // if i comment out this line 
    // ( probably EF fetches the lazy loaded entiy ) 
    // the code works. it is strange though because i don't access any property/method of the Address

    // var dummy = user.Address

    Context.SaveChanges();
}

当我在Address属性上没有“Required”属性的情况下尝试此操作时,不会发生错误。使用Required属性,我得到“Address field is required!”。由于每个用户都应该有一个地址,我希望该属性创建一致的模型。

在某些论坛中,我发现帖子建议在加载父实体时包含导航属性(换句话说是急切加载),但如果我们有太多导航属性,那么这不是一种可行的方法。

我做错了什么或有没有其他方法来实现这样的功能?

1 个答案:

答案 0 :(得分:1)

public int AddressId课程中定义User。它会在加载用户时加载。我认为这样可以解决问题。

<强>更新: 好吧,我已经复制了你的问题。你有几个选择来防止这种情况发生。但有一件事是肯定的。您必须Address媒体资源中删除[必填] 属性。这是你的问题的根源(这是合理的,因为你告诉EF“我想要地址对象(不是外键而是导航属性)。如果它是null,则抛出异常“)。
另外,在AddressId类中定义int类型的User属性。

请注意,您还可以在public virtual ICollection<User> Users { get; set; }实体中定义Address

您可以通过将[Required]放在AddressId上或使用流畅的api告诉EF有关所需属性的信息:
在您的用户映射类中:
    this.HasRequired(t =&gt; t.Address)         。和很多()         .HasForeignKey(d =&gt; d.AddressId);