以前我们创建表的时候,通常表的字段会有相应的类型,比如int、nvarchar、float等等。那么我们知道数据库的列属性和实体的字段属性类型不一定是一样的,比如数据库中的nvarchar那么在实体中就是string。下面我们统计一下:
SQL Server 数据类型 → .NET类型:
| SQL Server 数据类型 | .NET类型 |
|---|---|
| Bigint | Int64 |
| binary, varbinary | Byte[] |
| Bit | Boolean |
| date, datetime, datetime2, smalldatetime | DateTime |
| Datetimeoffset | DateTimeOffset |
| decimal, money, smallmoney, numeric | Decimal |
| float | Double |
| int | Int32 |
| nchar, nvarchar, char, varchar | String |
| real | Single |
| rowversion, timestamp | Byte[] |
| smallint | Int16 |
| time | TimeSpan |
| tinyint | Byte |
| uniqueidentifier | Guid |
比如如果我希望数据表是日期字段,那么我定义的实体应该使用DateTime类型:
public DateTime Birthday { set; get; }
我需要数据库是Bit类型:
public Boolean Gender { set; get; }
验证:EF如何知道哪个作为主键?属性含有ID、id、Id、iD这样的字段?标注一个[Key]。
限制表字段的长度:
[MinLength(10), MaxLength(30)]
可以使用上面的两个标注,这样生成的表列会通过StringLength(长度)、MinLength(最小长度)、MaxLength(最大长度)。其中这个StringLength是直接限制长度,这样生成的列应该就是nvarchar(长度)这样的属性了。
非空限制:
[Required]
public string Email { get; set; }
[Required(ErrorMessage = "请输入介绍")]
public string Introduce { get; set; }
直接规定列的数据类型:
//将string映射成ntext,默认为nvarchar(max)
[Column(TypeName = "ntext")]
//规定是char类型的
[StringLength(1, MinimumLength = 1)]
[Column(TypeName = "char")]
public string MiddleName { get; set; }
规定表名,通常如果我们不配置表名的话,EF会自动拿实体类名作为表名,但是其实我们是可以人为规定表名的:
[Table("SystemLog")]
public class Log
{
public int LogId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public DateTime AddTime { get; set; }
}
例如上面的表,尽管我们的类名是Log但是当EF创建出来后就是SystemLog。
规定列名,同样的道理,我们也可以人为配置列名的:
[Column("BlogName")]
public string Name { get; set; }
自增长,通常EF会将我们的Int类型的主键,自动设为自增长的,但是有一些时候,我们的主键可能不一定是Int类型,有可能是Guid类型的。这种情况,我们就需要人为的给一个标注,这样才能使得列自增长:
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid OrderId { get; set; }
上面的表ID就是使用Guid类型的,这个时候如果需要它自增长,那就要给DatabaseGenerated的标注。
不映射某列,不一定所有的实体属性都和列对应的,这些属性不需要我们保存到列中,只是留个我们在代码中用到,比如会员的全名,通常我们保存了会员的姓和名,但是姓和名是分开的,这个时候我们可以使用NotMapped来标注这一列,这样在数据库中就不会有这一列:
[NotMapped]
public string FullName
{
get
{
return FirstName + " " + LastName;
}
}
其实这个NotMapped还可以用在实体名中,这样就可以直接整个实体都不映射到数据库中:
[NotMapped]
public class LoginAccount
{
public int Id { get; set; }
public string Name { get; set; }
public string Pwd { get; set; }
}
时间戳,时间戳只对数据类型为byte[]的属性有效,并且一个类中只能有一个设置为时间戳的属性:
[Timestamp]
public Byte[] TimeStamp { get; set; }
复杂类型:
[ComplexType]
public class Address
{
public string Country { get; set; }
public string City { get; set; }
}
复杂类型是一些在很多表中都出现的属性,我们可以抽取出来作为一个类,然后在其他的类中,使用上面的复杂类型的类作为一个属性。比如:
public class IdentityInfo
{
public int IdentityId { get; set; }
public string IdentityNumber { get; set; }
public Address Address { get; set; }
}
可空属性,如果有一些字段运行为空的话,可以在属性类型后面加上?:
public DateTime? BirthDay { set; get; }