美文网首页
2020-03-31 16:00:00 InverseProve

2020-03-31 16:00:00 InverseProve

作者: daiwei_9b9c | 来源:发表于2020-05-21 20:38 被阅读0次

    提纲

    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个关系,

    • Post 中的 Author 和 Contributor
    • User 中的 AuthoredPosts 和 ContributedToPosts
      而EF 不知道这些关系其实是2对导航-反向导航的关系 ,所以采取默认的处理措施,
      即给 每一个关系都会在数据库的相关实体中(也就是 Post 表中) 中创建一个外键.
      看到这儿就很简单了,

    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 显得更加智能一点...

    相关文章

      网友评论

          本文标题:2020-03-31 16:00:00 InverseProve

          本文链接:https://www.haomeiwen.com/subject/xjtguhtx.html