1.异常查看
可以通过添加下面的变量到watch里面,来查看具体的异常信息。

((System.Data.Entity.Validation.DbEntityValidationException)$exception)

也可以在立即执行窗口执行下面的代码

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors.First().ValidationErrors.First()

2.EF小数点的问题
对于decimal数据类型,EF默认保留2位小数,可以这么进行自定义小数位数:

modelBuilder.Entity<MyClass>().Property(x => x.SnachCount).HasPrecision(16, 3);

3.一对一关系
对于一对一关系 ,EF要求依赖段的主键和外键是同一个字段。

4.AsNoTracking方法
有时候可能为了性能考虑,会对查询语句加上AsNoTracking()方法,这个方法提高性能的方式是EF不去跟踪查询结果的状态,这也导致了一个问题:后续对查询结果进行任何的更新、删除操作,即使调用了SaveChanges()方法,也不保存到数据库,最关键的是,不会报错,就这么默默的不保存。

5.枚举支持
EF4不支持枚举,EF5、EF6支持枚举。所以在升级到EF6的时候,原来在实体中给枚举定义的公共属性,就要加上[NotMapped]属性。

//OrderBusinessStatus是一个枚举,里面包含订单的各种状态

//在EF4我们这么处理枚举:
public OrderBusinessStatus OrderBusinessStatus
{
    get { return (OrderBusinessStatus)InternalOrderStatus; }
    set { InternalOrderStatus = (Int16)value; }
}

[Column("OrderStatus")]
public short InternalOrderStatus { get; set; }

//在EF5、EF6里面,可以直接一个属性就行了
public OrderBusinessStatus OrderStatus { get; set; }

6.查询方法中,对Nullable字段使用Contains方法
不使用Where()方法,使用linq语句查询:

from i in db
where i.SalesOrderItemId != null && salesOrderItemIdList.Contains(i.SalesOrderItemId.Value)
select i

7.EF自动在Where条件中Cast as int,导致索引不能命中
我们通常会把枚举设置为short类型,那么在数据库就是对应的smallint类型。当我们在linq查询的where条件里面写==enum.value的时候,EF生成的sql语句会自动把与枚举值匹配的字段转换成int类型进行查询,导致where条件里面使用了cast函数,从而使得索引失效。

m.LicensedLevel == EccnLicensedLevel.Licensed

EF生成的SQL语句如下,会带有Cast类型转换,这样导致索引使用不上:

AND (1 = CAST( [Extent2].[LicensedLevel] AS int)

解决办法是将==号改成Contains方法:

var licensedLevel = new short[] {1}; 

licensedLevel.Contains(m.LicensedLevel)

生成的SQL语句如下,这样就去掉了Cast,得到了我们想要的SQL语句:

AND (1 = [Extent2].[LicensedLevel])

发表评论

电子邮件地址不会被公开。 必填项已用*标注