Entity Framework 代码先行之约定配置

时间:2023-03-08 21:27:53
Entity Framework 代码先行之约定配置

要更改EF中的默认配置有两个方法,一个是用Data Annotations(在命名空间System.ComponentModel.DataAnnotations;),直接作用于类的属性上面;还有一个就是Fluent API,通过新增相应的配置类来覆盖默认配置。

1、Key

Data Annotations:指定一个或多个要用作实体的唯一标识的实体属性。

[Key]
public int Id { get; set; }

Fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Resource>().HasKey(d => d.Id);
}

2、Required

Data Annotations:用Required来标识,还可以设置是否可允许空字符串,显示错误消息等。

[Required]
public string Name { get; set; }

Fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Resource>().Property(p => p.Name).IsRequired();
}

3、StringLength、MinLength、MaxLength

Data Annotations:通过StringLength(长度),MinLength(最小长度),MaxLength(最大长度)来设置数据库中字段的长度。

[MinLength(), MaxLength()]
public string Name { get; set; }
[StringLength()]
public string Controller { get; set; }

Fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Resource>().Property(p => p.Name).HasMaxLength();
modelBuilder.Entity<Resource>().Property(p => p.Controller).HasMaxLength();
}

4、ForeignKey

Data Annotations:用于指定外键列

[ForeignKey("ResourceId")]
public virtual Resource Resource { get; set; }

Fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<RoleResource>().HasRequired(p => p.Resource).WithMany().HasForeignKey(p => p.ResourceId);
}

5、Tabel

Data Annotations:用于指定生成表的表名、架构信息

[Table("Resource")]
public class Resource
{
public int Id { get; set; }
public string Name { get; set; }
public string Controller { get; set; }
public string Action { get; set; }
public string IconCls { get; set; }
public Nullable<int> ParentId { get; set; }
public int Sort { get; set; }
public int Category { get; set; }
}

Fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Resource>().ToTable("Resource");
}

6、Column

Data Annotations:用于指定生成数据表的列信息,如列名、数据类型、顺序等。

[Column("Name", Order = , TypeName = "ntext")]
public string Name { get; set; }

Fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Resource>().Property(n=>n.Name).HasColumnName("Name").HasColumnType("ntext");
}

7、NotMapped

Data Annotations:用户指定非映射列,标记此属性的列将不会在数据库中生成相应的列。

[NotMapped]
public string Url { get; set; }

Fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Resource>().Ignore(p => p.Url);
}

8、TimeStamp

Data Annotations:时间戳只对数据类型为byte[]的属性有效,并且一个类中只能有一个设置为时间戳的属性。

[Timestamp]
public Byte[] TimeStamp { get; set; }

Fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Resource>().Property(p => p.TimeStamp).IsRowVersion();
}

8、DatabaseGenerated

Data Annotations:用于指定数据库字段生成列,此类EF将不会直接更新。可以指定为计算列、标识列和非数据库生成列(例如给主键列指定此属性为“None”则不会生成标识列)。需要注意的是如果使用Code First字段生成数据库,那么此属性仅仅可以用于byte、timestamp列上,否则请应用在已经存在数据库的情况下,因为Code First无法判定生成具体计算列的公式(至少目前Code First还不支持公式配置)。

如果主键是int类型,EF为默认设置为增长。但如果是GUID类型,则要显示的设置自增长。

public class Person
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid SocialId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}

看看创建数据的脚本,会加一句

ALTER TABLE [dbo].[People] ADD  DEFAULT (newid()) FOR [SocialId]

Fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>().Property(p => p.SocialId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}

8、ComplexType

Data Annotations:用于标记复杂类型,对于包含复杂类型数据属性的类在生成数据表时复杂类型中每个属性都将作为其中一列。

[ComplexType]
public class Address
{
public string Country { get; set; }
public string City { get; set; }
}

Fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.ComplexType<Address>();
}

9、ConcurrencyCheck

Data Annotations:用于标记复杂类型,对于包含复杂类型数据属性的类在生成数据表时复杂类型中每个属性都将作为其中一列。用于进行并发检查,当一个用户A获得实体后通常会与数据库断开,此时如果另一个用户B也获得了实体并进行了修改,那么当A再进行更新时如果进行了“ConcurrencyCheck”标记则会进行并发检查,并根据原始值判断该实体是否存在,如果不存在则抛出异常。

[ConcurrencyCheck]
public string Address
{
get;
set;
}

10、InverseProperty

Data Annotations:用于定义多重外键关系约束。我们在EF中通过导航属性定义主外键关系,但是当主表中有两个外键约束时可能仅仅通过添加相应的导航属性就无法完成了。

[InverseProperty("DeliverPerson")]
public List<Order> DeliverOrder
{
get;
set;
} [InverseProperty("CheckPerson")]
public List<Order> CheckOrder
{
get;
set;
}

参照:http://www.cnblogs.com/Gyoung/archive/2013/01/17/2864150.html、http://blog.csdn.net/xingxing513234072/article/details/13294449、http://www.360doc.com/content/14/0222/16/1355383_354779828.shtml