我们已经知道了,Code--First默认的约定,如果你没有包含外键属性在父类中,那么他会为我们创建{Class Name}_{primary Key}外键。这个InverseProperty特性用在:类之间当有多重关系的时候。

看下下面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EF3
{
   public class Student
    {
       public int StudentId { get; set; }

       public string StudentName { get; set; }

       public Standard CurrentStandard { get; set; }

       public Standard PriviousStandard { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EF3
{
   public class Standard
    {
       public int StandardId { get; set; }

       public string StandardName { get; set; }

       public ICollection<Student> CurrentStudent { get; set; }

       public ICollection<Student> PreviousStudent { get; set; }

    }
}

  上面的代码中,Student实体包含两个Standard类型的导航属性,同样的Standard实体包含两个集合类型的Student导航属性,Code-First创建了4个列为他们之间的关系:

InverseProperty这个特性可以重写这个默认的约定,下面的代码中,我们可以在Standard中使用InverseProperty特性来修正这个问题。

我们先看一下错误的例子:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;

namespace EF3
{
   public class Standard
    {
       public int StandardId { get; set; }

       public string StandardName { get; set; }

       /// <summary>
       /// InverseProperty,反属性特性
       /// </summary>
       [InverseProperty("one")]
       public ICollection<Student> CurrentStudent { get; set; }

       /// <summary>
       /// InverseProperty,反属性特性
       /// </summary>
       [InverseProperty("two")]
       public ICollection<Student> PreviousStudent { get; set; }

    }
}

上面的反属性特性里面我随便输入不存在的字符,然后:

提示这个反属性特性作用的属性CurrnentStudent不合法,这个属性one不是合法的导航属性。

然后我们看下正确的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;

namespace EF3
{
   public class Standard
    {
       public int StandardId { get; set; }

       public string StandardName { get; set; }

       /// <summary>
       /// InverseProperty,反属性特性
       /// </summary>
       [InverseProperty("CurrentStandard")]
       public ICollection<Student> CurrentStudent { get; set; }

       /// <summary>
       /// InverseProperty,反属性特性
       /// </summary>
       [InverseProperty("PriviousStandard")]
       public ICollection<Student> PreviousStudent { get; set; }

    }
}

这个代码里面把Student实体中的导航属性的名称放进去。就可以了。

你当然可以使用外键特性来包含外键属性,请看下面的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EF3
{
   public class Student
    {
       public int StudentId { get; set; }

       public string StudentName { get; set; }

       public int ForeignKeyCurrent { get; set; }
       public int ForeignKeyPrevious { get; set; }

       [ForeignKey("ForeignKeyCurrent")]
       public Standard CurrentStandard { get; set; }

        [ForeignKey("ForeignKeyPrevious")]
       public Standard PriviousStandard { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;

namespace EF3
{
   public class Standard
    {
       public int StandardId { get; set; }

       public string StandardName { get; set; }

       /// <summary>
       /// InverseProperty,反属性特性
       /// </summary>
       [InverseProperty("CurrentStandard")]
       public ICollection<Student> CurrentStudent { get; set; }

       /// <summary>
       /// InverseProperty,反属性特性
       /// </summary>
       [InverseProperty("PriviousStandard")]
       public ICollection<Student> PreviousStudent { get; set; }

    }
}

等等,你以为就样就可以了呢?我们运行程序看看就知道了:

果不其然又出错了,看一下具体的信息:

将 FOREIGN KEY 约束 'FK_dbo.Students_dbo.Standards_ForeignKeyPrevious' 引入表 'Students' 可能会导致循环或多重级联路径。请指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。
无法创建约束。请参阅前面的错误消息。

百度了一下:http://www.cnblogs.com/chear/archive/2012/11/09/2762145.html

改一下我们的上下文类的代码:

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EF3
{
   public class DbContextClass:DbContext
    {
       public DbContextClass():base("ConStr") { }

     public  DbSet<Student> Studnets { get; set; }

     public DbSet<Standard> Standards { get; set; }

     protected override void OnModelCreating(DbModelBuilder modelBuilder)
     {
         Database.SetInitializer(new DropCreateDatabaseIfModelChanges<DbContextClass>());
//加上这句代码,就OK了,取消级联删除。(这里其实可以两句代码,只写一句也是可以的。亲测过!!)
         modelBuilder.Entity<Standard>().HasMany(t => t.CurrentStudent).WithRequired(p=>p.CurrentStandard).WillCascadeOnDelete(false);

modelBuilder.Entity<Standard>().HasMany(t => t.PreviousStudents).WithRequired(p => p.PriviousStandard).WillCascadeOnDelete(false);

base.OnModelCreating(modelBuilder);
     }
    }
}

然后再运行程序就可以了。

Thus, you can use InverseProperty and ForeignKey attribute for multiple relationships between the same classes.

所以,当有多重关系的时候,你可以使用InverseProperty特性和外键特性。

当我们运行的时候,保存报错,提示主外键冲突什么的,那就是主键表Standard里面没有数据,我们插入两条数据进去,就可以了。

运行之后;

7.11 数据注解特性--InverseProperty的更多相关文章

  1. 9.7 翻译系列:EF数据注解特性之--InverseProperty【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/inverseproperty-dataannotations-attribute-in ...

  2. 9.11 翻译系列:数据注解特性之--Timestamp【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/TimeStamp-dataannotations-attribute-in-code- ...

  3. 9.10 翻译系列:EF数据注解特性之StringLength【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/stringlength-dataannotations-attribute-in-co ...

  4. 9.9 翻译系列:数据注解特性之--MaxLength 【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/maxlength-minlength-dataannotations-attribut ...

  5. 9.3 翻译系列:数据注解特性之Key【EF 6 Code-First 系列】

    原文链接:http://www.entityframeworktutorial.net/code-first/key-dataannotations-attribute-in-code-first.a ...

  6. 9.2 翻译系列:数据注解特性之---Column【EF 6 Code First系列】

    原文链接:http://www.entityframeworktutorial.net/code-first/column-dataannotations-attribute-in-code-firs ...

  7. 9.翻译系列:EF 6以及EF Core中的数据注解特性(EF 6 Code-First系列)

    原文地址:http://www.entityframeworktutorial.net/code-first/dataannotation-in-code-first.aspx EF 6 Code-F ...

  8. 9.1 翻译系列:数据注解特性之----Table【EF 6 Code-First 系列】

    原文地址:http://www.entityframeworktutorial.net/code-first/table-dataannotations-attribute-in-code-first ...

  9. 9.8 翻译系列:数据注解特性之--Required 【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/required-attribute-dataannotations-in-code-f ...

随机推荐

  1. PostgreSQL 杂志

    pgmag 团队刚发布了头两期 PostgreSQL 杂志,还有中文版http://pgmag.org/download,推荐广大 PostgreSQL 数据库管理员及开发者阅读: Issue #01 ...

  2. 【腾讯Bugly干货分享】Android ImageView 正确使用姿势

    本文来自于腾讯bugly开发者社区,未经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5832602d7196970d65901d76 导语 本文主要介绍了ImageV ...

  3. Some practices to write better C#/.NET code(译)

    C#(.NET)中有关编码的一些建议,原文地址:http://www.codeproject.com/Articles/539179/Some-practices-to-write-better-Cs ...

  4. [ASP.NET MVC 小牛之路]17 - 捆绑(Bundle)

    本文介绍 MVC 4 提供的一个新特性:捆绑(Bundle),一个在  View 和 Layout 中用于组织优化浏览器请求的 CSS 和 JavaScript 文件的技术. 本文目录 了解VS默认加 ...

  5. 分析nuget源码,用nuget + nuget.server实现winform程序的自动更新

    源起 (个人理解)包管理最开始应该是从java平台下的maven开始吧,因为java的开发大多数是基于开源组件开发的,一个开源包在使用时很可能要去依赖其他的开源包,而且必须是特定的版本才可以.以往在找 ...

  6. C#学习系列-文章导航

    C#学习系列-.NET体系结构 C#学习系列-类与结构的区别 C#学习系列-String与string的区别 C#学习系列-抽象方法与虚拟方法的区别 C#学习系列-out与ref的区别 C#学习系列- ...

  7. mybatis的一些小总结

    好长时间没用mybatis了,现在项目忽然用mybatis,用的过程中出现了些问题,虽然解决了,不过这花的时间有些长了.总结用的过程中出现的一些问题 1.mapper.xml 之前一直用的自动生成,现 ...

  8. Over:窗口函数(滑动聚合)

    Over 窗口函数在Select 子句中,对查询的结果集进行“滑动-聚合”运算:如果使用count,那么基于滑动窗口的聚合语义同 base+1 累加:如果使用sum,那么基于滑动窗口的聚合语义等同于数 ...

  9. 利用typescript使backbone强类型智能提示

    模型类一旦多了没有强类型和智能提示是相当痛苦的,所以. 仅仅用ts定义一个模型类: class Person extends Backbone.Model { defaults = { Name:&q ...

  10. py2exe使用中遇到的几个问题

    问题: 在使用py2exe对所写的python脚本打包成.exe可执行程序时,遇到两个问题: 问题1: RuntimeError: maximum recursion depth exceeded w ...