EntityFramework 4.1 FAQ

最近用EntityFramework 4.1把Petshop4.0做了改写.替换掉Model和DAL层.

用的是Update Model From Database, 把碰到的问题列出来备忘:

1. 用Partial Class 把类分开,在db有对应字段的放在EDMX文件里;例如订单总额这种统计数据就放到单独的cs文件.

2. EF自带有缓冲,如果get By Primary Key的记录,用这样的写法会快些

 

             using  (var ctx  =   new  MSPetShop4Entities())
            {
                EntityKey key 
=   new  EntityKey( " MSPetShop4Entities.Categories " " CategoryId " , categoryId);
                
return  ctx.GetObjectByKey(key)  as  Category;
            }
 3. EF 默认打开LazyLoad, 所以要使用关联对象例如Order和LineItem,在linq就要加上Include(xxx),
也可以写成.Include(t => t.LineItems) 这个写法要EF4.1才支持,
并要引用C:\Program Files\Microsoft ADO.NET Entity Framework 4.1\Binaries\EntityFramework.dll

 

using  (var ctx  =   new  MSPetShop4OrdersEntities())
            {
                
return  ctx.Orders.Include( " LineItems " ).Where(t  =>  t.OrderId.Equals(orderId)).FirstOrDefault();
            }

 4.如何直接写sql?

    ObjectContext.ExecuteStoreCommand(...)和 ObjectContext.ExecuteStoreQuery<T>(...)。
    从函数名不难知道,前者是为了执行某一并无返回集的SQL 命令,例如UPDATE,DELETE操作;
    后者是执行某一个查询,并可以将返回集转换为某一对象(这个对象必须是EDMX文件里面定义的)

    如果是自己定义的view或class,就得用linq自己转换了.

 

                var qry  =  from t  in  ctx.Accounts.Include( " Profiles " )
                          
where  t.Profile.Username.Equals(userName)  &&  t.Profile.ApplicationName.Equals(appName)
                          select 
new  AddressInfo()
                          {
                              Email 
=  t.Email,
                              FirstName 
=  t.FirstName,
                              LastName 
=  t.LastName,
                              Address1 
=  t.Address1,
                              Address2 
=  t.Address2,
                              City 
=  t.City,
                              State 
=  t.State,
                              Zip 
=  t.Zip,
                              Country 
=  t.Country,
                              Phone 
=  t.Phone
                          };

 

 5. 如果db没有定义primary key,保存记录时就会出现错误

     Unable to update the EntitySet 'Cart' because it has a DefiningQuery and no <InsertFunction> element
     exists in the <ModificationFunctionMapping> element to support the current operation     
    解决办法如下:

     http://stackoverflow.com/questions/1589166/it-has-a-definingquery-but-no-insertfunction-element-err

 6. 如何跨数据库访问.

    先在其中一个数据库添加"同义词" synonym, 然后再新建一个View包含该synonym, 再在EDMX文件里定义该View.

 7.EF4.1新的API,DbSet<>.Find()

 

过去我们常常用Where或First(FirstOrDefault)方法来查找对应的实体,比如:

var people  =  from p  in  context.People
             
where  p.Name.StartsWith( " M " )
             select u;

var people = context.People.FirstOrDefault(p => p.Name == "Michael");  

这样查找的缺点是:即使我们相应的实体已经被ObjectContext缓存,EF还是会去执行数据库访问,而数据库访问是被普遍认为比较耗费性能的。

 

EF4.1为我们提供了一个新的API: DbSet<>.Find()。它可以帮助我们通过主键来查找对应的实体。并且如果相应的实体已经被ObjectContext缓存,EF会在缓存中直接返回对应的实体,而不会执行数据库访问。

 

比如我们查找主键PersonID为1的Person实体:

var person = context.People.Find(1);

 

也可用于联合主键(比如查找主键PersonID=1, PersonName="Michael"的实体):

 

var person  =  context.People.Find( 1 " Michael " );

 

注意:此处输入联合主键的次序需要按照我们定义改实体类时声明主键的次序。

 

和之前直接用Where或First的调用不同,Find函数对于刚刚新增的实体也能找到:

 

using  (var context  =  new  MyContext())
{
    context.People.Add(
new  People { PersonID  =  100  });
    var newPerson 
=  context.People.Find( 100 );
}

 

8. CodeFirst 的基类是DbContext, 和DB First/Model First 用的ObjectContext 区别比较大

 

 

9 EF 实用Tips http://www.cnblogs.com/lsxqw2004/category/266012.html

转载于:https://www.cnblogs.com/zitjubiz/archive/2011/07/13/Entity_Framework_4_1_FAQ.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值