在EntityFramework, Version=6.0.0.0,维护一个现有项目,修改代码后,编译正常。但运行系统,竟然报发生异常,加断点跟踪发现抛出“One or more validation errors were detected during model generation”
由于对EF不够熟悉。所以网上搜索了一番,提示:原因是因为我在写实体类的时候没有为实体类中的属性声明一个主键,即用[key]特性标注在属性上,这样DbContext才能为我们在数据库上找到对应的主键。由于是现有项目进行的修改,我找到自己的实体类,和之前的类对比,并没有这个属性。
又查了一些资料如下:
主键:在数据表中是指记录的唯一标识符。
而在EF模型中的主键有如下规则:
- 明确指定某个字段为模型的主键(通过注解和Fluent API)
- 如果没有明确指定,那么按照约定将名为
Id
或者类名Id
这个属性设置为主键。 - 如果上述都没有满足,EF执行时会报错。
在EF中指定主键的映射关系,有以下几种方法:
2.通过Fluent API设置主键(重写DbContext的
-
约定
Id
和类名Id
约定例子:
class Car { public string CarId { get; set; }//主键 public string Make { get; set; } public string Model { get; set; } }
-
显式设置
1.通过注解设置主键
class Car { [Key] public string LicensePlate { get; set; } public string Make { get; set; } public string Model { get; set; } }
2.通过Fluent API设置主键(重写DbContext的OnModelCreating方法
)
class MyContext : DbContext
{
public DbSet<Car> Cars { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.HasKey(c => c.LicensePlate);
}
}
class Car
{
public string LicensePlate { get; set; }
public string Make { get; set; }
public string Model { get; set; }
}
-
显式设置联合主键(重写DbContext的
OnModelCreating方法
)
class MyContext : DbContext
{
public DbSet<Car> Cars { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.HasKey(c => new { c.State, c.LicensePlate });
}
}
class Car
{
public string State { get; set; }
public string LicensePlate { get; set; }
public string Make { get; set; }
public string Model { get; set; }
}
-
单独的类来管理配置,继承EntityTypeConfiguration<TEntity>类实现
在OnModelCreating方法中,如果有很多实体的话,OnModelCreating方法管理很麻烦,可以通过继承System.Data.Entity.ModelConfiguration命名空间中的
EntityTypeConfiguration<TEntity>类来实现
public class xxx: EntityTypeConfiguration<Student> { public xxx() { this.ToTable("StudentInfo"); this.HasKey<int>(s => s.StudentKey); } }