实体框架自引用实体

时间:2013-06-14 13:23:36

标签: entity-framework ef-code-first

我对实体框架有疑问。

public class User : Receiver
{
    public User()
    {
        if (Groups == null)
            Groups = new List<Group>();
        if (Buddies == null)
            Buddies = new List<User>();
    }

    [Required]
    public string PhoneNumber { get; set; }
    [ForeignKey("Guid"), JsonIgnore]
    public IList<User> Buddies { get; set; }
    [ForeignKey("Guid"), JsonIgnore]
    public IList<Group> Groups { get; set; }
}

public class Receiver
{
    public Receiver()
    {
        Guid = Guid.NewGuid();
        Created = DateTime.Now;
    }

    [Key]
    public Guid Guid { get; set; }
    [Required]
    public DateTime Created { get; set; }
}

当我尝试添加用户时...

User user = new User
            {
                Guid = new Guid("8cd094c9-e4df-494e-b991-5cf5cc03d6e3"),
                PhoneNumber = "+4991276460"
            };

        cmc.Receivers.Add(user);

...以follogwing错误结束。

  

Type“System.Collections.Generic.List`1 [Project.Models.User]”的对象无法转换为“Project.Models.User”。

当我注释掉以下两行时:

[ForeignKey("Guid"), JsonIgnore]
    public IList<User> Buddies { get; set; }

......程序运行良好。

我希望有人可以帮我解决这个问题。

否则会在此行遇到错误:cmc.Receivers.Add(user);

1 个答案:

答案 0 :(得分:0)

在您的地图中......

[ForeignKey("Guid"), JsonIgnore]
public IList<User> Buddies { get; set; }

...您指定User.Buddies是一对多关系的一部分,而User.Guid(= Receiver.Guid)是此关系中的外键。但是User.Guid也是主键,因此它必须是唯一的。因此,User不能包含Buddies列表,但只能包含一个参考。

映射毫无意义,但异常不是很有用且难以理解。 (不知何故,EF似乎在内部认识到Buddies不能是具有该映射的列表,并且希望将列表转换为单个引用。在我看来,它应该首先检测到映射是无效的。)< / p>

对于正确的一对多映射,您需要一个与主键不同的外键。您可以通过完全删除[ForeignKey]注释来实现这一目标......

[JsonIgnore]
public IList<User> Buddies { get; set; }

...在这种情况下,EF将在Receivers表中创建一个默认外键(它将是一些名称中带有下划线的列,但如果不这样,您可以使用Fluent API重命名该外键比如默认名称)或者将自己的外键属性添加到User类:

public Guid? BuddyGuid { get; set; }

[ForeignKey("BuddyGuid"), JsonIgnore]
public IList<User> Buddies { get; set; }