Entity Framework 代码优先:如何不使用 "principal" 和相同 ID 的概念设置一对一关系?

Entity Framework code first: How to set a one to one relationships not using the concept of "principal" and same id?

我有两个 class。第一个是这样的:

public class User
{
    public int Id { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public string Name { get; set; }
    public DateTime Birth { get; set; }
    public Sex Sex { get; set; }
    public List<Album> Albums { get; set; }
    public DateTime Created { get; set; }

    public Picture ProfilePicture { get; set; }
}

第二个是这样的:

public class Picture
{
    public int Id { get; set; }
    public Album Album { get; set; }
    public string Path { get; set; }
    public string Description { get; set; }
    public DateTime Created { get; set; }

    public User User { get; set; }
}

图片保存在table中,用户可以在相册中拥有任意数量的图片,并通过相册访问。这是 Album class:

public class Album
{
    public int Id { get; set; }
    public User User { get; set; }
    public AlbumType Type { get; set; }
    public List<Picture> Pictures { get; set; }
    public string Name { get; set; }
    public DateTime Created { get; set; }
}

有一个 Picture 对象,我希望能够检索该图片的 User 所有者,执行类似 picture.User 的操作,目前有效。但是这些图片中只有一张可以是个人资料图片。因为几乎总是检索个人资料图片,所以我希望能够在代码中执行如下操作:

LoadPicture(user.ProfilePicture.Id);

我的问题是 EF 认为我想创建一个一对一的关系,我必须在其中定义一个主体,并且两个实体必须具有相同的 ID。 Picture 的实体必须有自己的 ID,User 的实体也必须有自己的 ID。我怎么能对 EF 这么说,所以 user.ProfilePicture.Id 有效?

我们将不胜感激。

Having a Picture object, I want to be able to retrieve the User owner of that picture, doing something like picture.User, that currently works.

我建议您删除或重命名 User 属性,因为它具有误导性 - 图片的所有者是 Picture.Album.User,而这个 属性 确实代表User.ProfilePicture.

的反转

此外,您确实需要(作为例外情况)使用流畅的 API.

解决 User.ProfilePicture 关系的 principal/dependent 部分

所以,这里有选项:

(A) 删除 Picture.User 属性

public class Picture
{
    public int Id { get; set; }
    public Album Album { get; set; }
    public string Path { get; set; }
    public string Description { get; set; }
    public DateTime Created { get; set; }
}

并在 DbContext OnModelCreating 覆盖中使用以下内容:

modelBuilder.Entity<User>()
    .HasOptional(e => e.ProfilePicture)
    .WithOptionalPrincipal();

(B) 重命名 Picture.User 属性

public class Picture
{
    public int Id { get; set; }
    public Album Album { get; set; }
    public string Path { get; set; }
    public string Description { get; set; }
    public DateTime Created { get; set; }
    public User ProfileOf { get; set; }
}

并使用

modelBuilder.Entity<User>()
    .HasOptional(e => e.ProfilePicture)
    .WithOptionalPrincipal(e => e.ProfileOf);

这两个选项都将在 Picture table 中引入 int? 列作为 FK 到 User table.