7.11 数据注解特性--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里面没有数据,我们插入两条数据进去,就可以了。

运行之后;

7.11 数据注解特性--InverseProperty的更多相关文章
- 9.7 翻译系列:EF数据注解特性之--InverseProperty【EF 6 Code-First系列】
原文链接:https://www.entityframeworktutorial.net/code-first/inverseproperty-dataannotations-attribute-in ...
- 9.11 翻译系列:数据注解特性之--Timestamp【EF 6 Code-First系列】
原文链接:https://www.entityframeworktutorial.net/code-first/TimeStamp-dataannotations-attribute-in-code- ...
- 9.10 翻译系列:EF数据注解特性之StringLength【EF 6 Code-First系列】
原文链接:https://www.entityframeworktutorial.net/code-first/stringlength-dataannotations-attribute-in-co ...
- 9.9 翻译系列:数据注解特性之--MaxLength 【EF 6 Code-First系列】
原文链接:https://www.entityframeworktutorial.net/code-first/maxlength-minlength-dataannotations-attribut ...
- 9.3 翻译系列:数据注解特性之Key【EF 6 Code-First 系列】
原文链接:http://www.entityframeworktutorial.net/code-first/key-dataannotations-attribute-in-code-first.a ...
- 9.2 翻译系列:数据注解特性之---Column【EF 6 Code First系列】
原文链接:http://www.entityframeworktutorial.net/code-first/column-dataannotations-attribute-in-code-firs ...
- 9.翻译系列:EF 6以及EF Core中的数据注解特性(EF 6 Code-First系列)
原文地址:http://www.entityframeworktutorial.net/code-first/dataannotation-in-code-first.aspx EF 6 Code-F ...
- 9.1 翻译系列:数据注解特性之----Table【EF 6 Code-First 系列】
原文地址:http://www.entityframeworktutorial.net/code-first/table-dataannotations-attribute-in-code-first ...
- 9.8 翻译系列:数据注解特性之--Required 【EF 6 Code-First系列】
原文链接:https://www.entityframeworktutorial.net/code-first/required-attribute-dataannotations-in-code-f ...
随机推荐
- 谈asch系统的共识机制与容错性
本文章出自:http://blog.asch.so/,转载请注明出处. 0 前言 我曾分析了DPOS算法的漏洞并且模拟了一个简单的攻击的方法,然后实现了一个简化的PBFT算法模型试图去修复该漏洞,并且 ...
- .NET Core中合并Expression<Func<T,bool>>的正确姿势
这是在昨天的 .NET Core 迁移中遇到的问题,之前在 .NET Framework 中是这样合并 Expression<Func<T,bool>> 的: public s ...
- 《代码的未来》读书笔记:内存管理与GC那点事儿
一.内存是有限的 近年来,我们的电脑内存都有好几个GB,也许你的电脑是4G,他的电脑是8G,公司服务器内存是32G或者64G.但是,无论内存容量有多大,总归不是无限的.实际上,随着内存容量的增加,软件 ...
- ASP.NET MVC 防止 CSRF 的方法
MVC中的Html.AntiForgeryToken()是用来防止跨站请求伪造(CSRF:Cross-site request forgery)攻击的一个措施,它跟XSS(XSS又叫CSS:Cross ...
- 使用ViewPager+Fragment实现选项卡切换效果
实现效果 本实例主要实现用ViewPage和Fragment实现选项卡切换效果,选项卡个数为3个,点击选项卡或滑动屏幕会切换Fragment并实现选项卡下方下边框条跟随移动效果. 本程序用androi ...
- 【VC++技术杂谈007】使用GDI+进行图片格式转换
本文主要介绍如何使用GDI+对图片进行格式转换,可以转换的图片格式为bmp.jpg.png. 1.加载GDI+库 GDI+是GDI图形库的一个增强版本,提供了一系列Visual C++ API.为了使 ...
- Stored Procedure 里的 WITH RECOMPILE 到底是干麻的?
在 SQL Server 创建或修改「存储过程(stored procedure)」时,可加上 WITH RECOMPILE 选项,但多数文档或书籍都写得语焉不详,或只解释为「每次执行此存储过程时,都 ...
- TODO:小程序的用户身份
TODO:小程序的用户身份 小程序的用户身份有三种,一个管理员,二十个开发者,四十个体验者 1.管理员,可设置风险操作保护.风险操作提醒等操作. a)修改管理员,需要用到原管理员,新管理员的身份证号码 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (25) ------ 第五章 加载实体和导航属性之加载完整的对象图和派生类型上的导航属性
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-5 加载完整的对象图 问题 你有一个包含许多关联实体的模型,你想在一次查询中, ...
- 《深入浅出Nodejs》—— 读后总结
这一个月过去了三分之二,加上之前看过这本书三分之一,这才算是看完. 虽然看完一遍,但是这本书内容很深,以后肯定是还要继续翻阅的..... 什么是Nodejs Nodejs有几个特性:异步IO,事件驱动 ...