2020-03-31 16:00:00 InverseProve

2020-05-21  本文已影响0人  daiwei_9b9c

提纲

InverseProperty 标注的用途

用于在某一个导航属性上标注其在相关实体上的反向导航属性,构造函数必须指定相关实体上的反向导航属性,且此属性的类型必须和导航属性的反向导航属性一致.

先看不带有 InversePropery 的例子,但是在 EFCore中无法运行

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public User Author { get; set; }
    public User Contributor { get; set; }
}

public class User
{
    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public List<Post> AuthoredPosts { get; set; }
    public List<Post> ContributedToPosts { get; set; }
}

这个例子在 EFCORE中无法创建表.
错误原因,
Unable to determine the relationship represented by navigation property 'User.AuthoredPosts' of type 'List<Post>'.
不能查明到由导航属性 User.AuthoredPosts (类型, List<Post>) 所表示的关系
这个 determine 有 查明/探测/决定的意思. 我们这儿就翻译作 查明 吧.

但是在 EF中,这个可以创建表,只是在 Post表中会有4个外键,
因为 EF找到了 4个关系,

InverseProperty 标注用来标注某一个导航属性在相关实体中的另外一端的反向导航.

所以,它带有一个构造函数,也就是相关实体的导航属性的名称.
稍微改一下代码. 测试InverseProperty指向一个 int 类型的字段,想用这个字段作为外键.

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    [InverseProperty(nameof(User.AuthoredPosts)]
    public User Author { get; set; }
    public User Contributor { get; set; }

    public int OtherContributorId  { get; set; }
}

public class User
{
    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public List<Post> AuthoredPosts { get; set; }

    [InverseProperty(nameof(Post.OtherContributorId)]
    public List<Post> ContributedToPosts { get; set; }
}

以上代码也无法执行,EFCORE会判断反向导航的属性是否和导航属性的类型是否匹配.
只是报了一个奇怪的错误: System.ArgumentNullException: Value cannot be null. (Parameter 'type')

正确写法如下:

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    [InverseProperty(nameof(User.AuthoredPosts)]
    public User Author { get; set; }

    public User Contributor { get; set; }
}

public class User
{
    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<Post> AuthoredPosts { get; set; }

    [InverseProperty(nameof(Post.Contributor)]
    public List<Post> ContributedToPosts { get; set; }
}

至少,比起 EF 来, EFCorer 显得更加智能一点...

上一篇下一篇

猜你喜欢

热点阅读