7.1数据注解属性--Key【Code-First系列】
Key特性可以被用到类的属性中,Code-First默认约定,创建一个主键,是以属性的名字“Id”,或者是类名+Id来的。
Key特性重写了这个默认的约定,你可以应用Key特性到一个类的属性上面,不管这个属性的名字是什么,你都可以创建一个主键。
让我们看看下面的代码吧:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EF2
{
[Table("StudentInfo")]
public class Student
{
[Key]
public int StudentKey { get; set; }
[Column("Name",TypeName="ntext")]
[MaxLength()]
public string StudentName { get; set; }
[NotMapped()]
public int? Age { get; set; }
public int StdId { get; set; }
[ForeignKey("StdId")]
public virtual Standard Standard { get; set; }
}
}
在上面的例子中,Key属性应用到了Student实体的StudnetKey属性上面,那么下面将会得到这个主键:

当然你还可以创建复合主键,使用Key特性和Column特性,使2个列同时作为主键,看看下面的代码吧:
注意:我这里先让大家看看一个错误的例子。创建复合主键的时候,我只用Key特性,看可以不可以呢???
看我的代码:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EF2
{
[Table("StudentInfo")]
public class Student
{
[Key]
public int StudentKey1 { get; set; }
[Key]
public int StudentKey2 { get; set; }
[Column("Name",TypeName="ntext")]
[MaxLength()]
public string StudentName { get; set; }
[NotMapped()]
public int? Age { get; set; }
public int StdId { get; set; }
[ForeignKey("StdId")]
public virtual Standard Standard { get; set; }
}
}
当然我们需要,改一下Main函数的调用代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EF2
{
class Program
{
static void Main(string[] args)
{
Student stuModel = new Student() { StudentKey1 = 1,StudentKey2=1, StudentName = "cfs", StdId = 1 };
using (var db = new DbContextClass())
{
db.Students.Add(stuModel);
db.SaveChanges();
}
Console.WriteLine("Add Success");
Console.ReadKey();
}
}
}
运行程序:

报错了,看一下具体的错误消息:
Unable to determine composite primary key ordering for type 'EF2.Student'. Use the ColumnAttribute (see http://go.microsoft.com/fwlink/?LinkId=386388) or the HasKey method (see http://go.microsoft.com/fwlink/?LinkId=386387) to specify an order for composite primary keys.
大意是:不能创建复合主键,因为没有使用Column特性或者HasKey方法,来指定主键的序列。
然后我们再修改一下代码:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EF2
{
[Table("StudentInfo")]
public class Student
{
[Key]
[Column]
public int StudentKey1 { get; set; }
[Key]
[Column]
public int StudentKey2 { get; set; }
[Column("Name",TypeName="ntext")]
[MaxLength()]
public string StudentName { get; set; }
[NotMapped()]
public int? Age { get; set; }
public int StdId { get; set; }
[ForeignKey("StdId")]
public virtual Standard Standard { get; set; }
}
}
看现在我们加了Column特性了吧,现在我们再运行程序:
还是抱上面的错误,然后我们再修改代码:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EF2
{
[Table("StudentInfo")]
public class Student
{
[Key]
[Column("one")]
public int StudentKey1 { get; set; }
[Key]
[Column("two")]
public int StudentKey2 { get; set; }
[Column("Name",TypeName="ntext")]
[MaxLength()]
public string StudentName { get; set; }
[NotMapped()]
public int? Age { get; set; }
public int StdId { get; set; }
[ForeignKey("StdId")]
public virtual Standard Standard { get; set; }
}
}
这样还是不行,哈哈,因为没有指定列的顺序,算了,不折腾了,上正确的代码:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EF2
{
[Table("StudentInfo")]
public class Student
{
[Key]
[Column(Order=1)]
public int StudentKey1 { get; set; }
[Key]
[Column(Order=2)]
public int StudentKey2 { get; set; }
[Column("Name",TypeName="ntext")]
[MaxLength()]
public string StudentName { get; set; }
[NotMapped()]
public int? Age { get; set; }
public int StdId { get; set; }
[ForeignKey("StdId")]
public virtual Standard Standard { get; set; }
}
}
运行程序之后,看下数据库:

请注意:单个主键,EF Code-First为我们创建的:主键是自动增长的,而复合主键,得到的主键不是自动增长的。
当然,key 属性不仅仅可以引用到int类型的属性上,还可以应用到字符串,日期类型等等。。

好了,这就是数据注解特性的Key特性了。
7.1数据注解属性--Key【Code-First系列】的更多相关文章
- 7.2 数据注解属性--TimeStamp特性【Code-First 系列】
TimeStamp特性可以应用到领域类中,只有一个字节数组的属性上面,这个特性,给列设定的是tiemStamp类型.在并发的检查中,Code-First会自动使用这个TimeStamp类型的字段. 下 ...
- 7.4 数据注解属性--Required
Required attribute can be applied to a property of a domain class. EF Code-First will create a NOT N ...
- 1.什么是Code First(EF Code First 系列)
EF4.1中开始支持Code First .这种方式在领域设计模式中非常有用.使用Code First模式,你可以专注于领域设计,根据需要,为你一个领域的对象创建类集合,而不是首先来设计数据库,然后来 ...
- 9.3 翻译系列:数据注解特性之Key【EF 6 Code-First 系列】
原文链接:http://www.entityframeworktutorial.net/code-first/key-dataannotations-attribute-in-code-first.a ...
- MVC5中Model层开发数据注解 EF Code First Migrations数据库迁移 C# 常用对象的的修饰符 C# 静态构造函数 MSSQL2005数据库自动备份问题(到同一个局域网上的另一台电脑上) MVC 的HTTP请求
MVC5中Model层开发数据注解 ASP.NET MVC5中Model层开发,使用的数据注解有三个作用: 数据映射(把Model层的类用EntityFramework映射成对应的表) 数据验证( ...
- 7.DataAnnotations(数据注解)【Code-First 系列】
EF Code-First提供了一系列的数据注解的特性,你可以将其应用到你的领域类和属性中,数据注解属性重写了EF默认的约定. System.ComponentModel.DataAnnotation ...
- MVC5中Model层开发数据注解
ASP.NET MVC5中Model层开发,使用的数据注解有三个作用: 数据映射(把Model层的类用EntityFramework映射成对应的表) 数据验证(在服务器端和客户端验证数据的有效性) 数 ...
- ASP.NET MVC5中的数据注解
ASP.NET MVC5中Model层开发,使用的数据注解有三个作用: 数据映射(把Model层的类用EntityFramework映射成对应的表) 数据验证(在服务器端和客户端验证数据的有效性) 数 ...
- ASP.NET MVC5中的数据注解(转载)
ASP.NET MVC5中Model层开发,使用的数据注解有三个作用: 数据映射(把Model层的类用EntityFramework映射成对应的表) 数据验证(在服务器端和客户端验证数据的有效性) 数 ...
随机推荐
- Powershell 字符串处理案例
有一张Excel表格收集了计算机名和IP地址,另外一张表有计算机名,需要找出这张表中计算机名对应的IP地址. #定义函数Get-LikeContentInfo function Get-LikeCon ...
- #IrrlichtEngine# Example1 HelloWorld
配置IDE环境来使用irrlicht引擎: (VS2012下)菜单栏项目 -> 项目属性窗口下 C/C++ -> 常规 -> 附加包含目录中添加irrlicnt引擎文件目录下incl ...
- 剑指Offer面试题:16.合并两个排序的链表
PS:这也是一道出镜率极高的面试题,我相信很多童鞋都会很眼熟,就像于千万人之中遇见不期而遇的人,没有别的话可说,唯有轻轻地问一声:“哦,原来你也在这里? ” 一.题目:合并两个排序的链表 题目:输入两 ...
- 如何在没有域的环境中搭建AlwaysOn(一)
对DBA而言,不需要域就可以搭建SQL Server AlwaysOn是Windows Server 2016中最令人兴奋的功能了,它不仅可以降低搭建的成本,而且还减少了部署和运维的工作量. 该特性可 ...
- quick-cocos2d-x 2.2.3 rc版本中 crypto.md5file() 的C++实现在ANDROID上有BUG
原来的版本是用fopen打开文件的,如果要从ANDROID的APK中取文件,直接就洗白了修改如下 void CCCrypto::MD5File(const char* path, unsigned c ...
- JavaScript面试时候的坑洼沟洄——逗号、冒号与括号
看完了javaScript数据类型和表达式与运算符相关知识后以为可以对JavaScript笔试题牛刀小试一把了,没想到有一次次的死在逗号,冒号和括号上,不得已再看看这几个符号吧. 逗号 逗号我们常见的 ...
- 让pv3d(papervision3D)支持单帧前进、后退(nextFrame)。
下载最新的源码,找到animationController. 修改如下: package org.papervision3d.core.controller { import flash.events ...
- sublime text 下的Markdown写作
sublime text 2(3)下的Markdown写作 什么是 Markdown wiki Markdown 是一种方便记忆.书写的纯文本标记语言,用户可以使用这些标记符号以最小的输入代价生成极富 ...
- [转] Android优秀开源项目
Android经典的开源项目其实非常多,但是国内的博客总是拿着N年前的一篇复制来复制去,实在是不利于新手学习.今天爬爬把自己熟悉的一些开源项目整理起来,希望能对Android开发同学们有所帮助.另外, ...
- Sql Server系列:多表连接查询
连接查询是关系数据中最主要的查询,包括内连接.外连接等.通过连接运算符可以实现多个表查询.内连接查询操作列出与连接条件匹配的数据行,它使用比较运算符比较被连接列的列值.SQL Server中的内连接有 ...