数据注解特性--InverseProperty

我们已经知道了,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里面没有数据,我们插入两条数据进去,就可以了。

运行之后;

时间: 2024-08-28 21:55:51

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

EF CodeFirst数据注解特性详解

数据注解特性是.NET特性,可以在EF或者EF Core中,应用于实体类上或者属性上,以重写默认的约定规则. 在EF 6和EF Core中,数据注解特性包含在System.ComponentModel.DataAnnotations命名空间和System.ComponentModel.DataAnnotations.Schema命名空间下. 这些特性不仅仅适用于EF,同样适用于ASP.NET MVC以及数据控件. System.ComponentModel.DataAnnotations.Sch

数据注解特性--Table

大家可能注意到,有几个特性,我没有翻译,因为实在是太简单了,看一下就知道,之前也学过,现在只是系统学一下,所以就粗略的看一下就行了. 现在学习数据注解特性的--Table特性. Table 特性可以被用到类中,Code--First默认的约定是使用类名称为我们创建表名,Table特性可以重写这个约定,只要我们指定名字,EF就会根据Table属性里面的名字,为我们创建数据表名称. 我们看一下下面的代码吧: using System; using System.Collections.Generic

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

9.11 翻译系列:数据注解特性之--Timestamp[EF 6 Code-First系列] 原文链接:https://www.entityframeworktutorial.net/code-first/TimeStamp-dataannotations-attribute-in-code-first.aspx EF 6和EF Core都包含TimeStamp数据注解特性.它只能用在实体的byte数组类型的属性上,并且只能用在一个byte数组类型的属性上.然后在数据库中,创建timestam

数据注解特性--ForeignKey

外键特性,可以应用到类的属性中.Code-First默认的约定,对外键属性来说,假定外键属性的名称和主键属性是匹配的. 我们看一下,下面的代码: using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.

数据注解特性之ConcurrencyCheck特性【Code-First系列】

ConcurrencyCheck特性可以应用到领域类的属性中.当EF执行更新操作的时候,Code-First将列的值放在where条件语句中,你可以使用这个CurrencyCheck特性,使用已经存在的列做并发检查,而不是使用单独的TimeStamp列来做并发检查. 看下面的代码: using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Co

数据注解特性--StringLength

StringLength attribute can be applied to a string type property of a class. EF Code-First will set the size of a column as specified in StringLength attribute. Note that it can also be used with ASP.Net MVC as a validation attribute. Consider the fol

数据注解特性--MaxLength&amp;&amp;MinLength

MaxLength attribute can be applied to a string or array type property of a domain class. EF Code First will set the size of a column as specified in MaxLength attribute. Note that it can also be used with ASP.Net MVC as a validation attribute. Consid

Asp.net MVC 数据注解与验证

数据注解特性定义在名称空间System.ComponentModel.DataAnnotations中(有些特性定义在其他名称空间中),它们提供了服务器端验证的功能,当在模型的属性上使用这些特性时,框架也支持客户端验证. 常用特性 1.Required --必填字段示例:[Required]2.StringLength --字符长度限制示例:[StringLength(16,MinimumLength=3)]3.RegularExpression --正则表达式验证示例:[RegularExpr

数据注解和验证 &ndash; ASP.NET MVC 4 系列

       不仅在客户端浏览器中需要执行验证逻辑,在服务器端也需要执行.客户端验证能即时给出一个错误反馈(阻止请求发送至服务器),是时下 Web 应用程序所期望的特性.服务器端验证,主要是因为来自网络的信息都是不可信任的.        当在 ASP.NET MVC 设计模式上下文中谈论验证时,主要关注的是验证模型的值.ASP.NET MVC 验证特性可以帮助我们验证模型值,且这样验证特性是可扩展的,所以我们可以采用任意想要的方式构建验证模式,默认方法是一种声明式验证,即数据注解特性.