Entity Framework直接执行SQL语句

本文介绍了如何在EntityFramework中执行SQL语句进行数据操作,特别针对产品与类别关联的增删操作进行了详细说明,并解释了使用ExecuteStoreQuery<T>和ExecuteStoreCommand方法的具体应用与注意事项。

一般来说linq在EF中满足了绝大部分的查询需求,而插入、删除则需要根据实体来操作,在一些情况下会造成一些麻烦。

比如现在有这样的关系:

它在数据库中生成的表:

 

  那么在实体对象上下文如果想直接操作某些Product与Category的关联时将麻烦不少,因为不能在EF下直接操作ProductCategory中间表。那么这时直接执行SQL语句来添加、删除两者之间关系会好上不少。我便是这样写的:

复制代码
复制代码
 1         /// <summary>
 2         /// 添加产品到小类
 3         /// </summary>
 4         /// <param name="proID">产品ID</param>
 5         /// <param name="catIDs">小类ID列表</param>
 6         public bool AddProductToCategory(int proID, IList<int> catIDs)
 7         {
 8             bool result = true;
 9             foreach (var catID in catIDs)
10             {
11                 try
12                 {
13                     string sql = "Insert Into [ProductCategory] Values (@proID,@catID)";
14                     var args = new DbParameter[] { 
15                                      new SqlParameter { ParameterName = "proID", Value = proID},
16                                      new SqlParameter("catID",catID)
17                                   };
18                     _DataModelEntity.ExecuteStoreCommand(sql, args);
19                 }
20                 catch (System.Exception ex)
21                 {
22                     LogHelper.WriteLog(ex);
23                     result = false;
24                 }
25             }
26             return result;
27         }
28 
29         /// <summary>
30         /// 删除小类产品关系
31         /// </summary>
32         /// <param name="proID">产品ID</param>
33         /// <param name="catIDs">小类ID</param>
34         public bool DeleteProductToCategory(int proID,IEnumerable<int> catIDs)
35         {
36             bool result = true;
37             foreach (var catID in catIDs)
38             {
39                 try
40                 {
41                     string sql = "Delete From [ProductCategory] Where [Product_ID] = @proID And [Category_ID] = @catID";
42                     var args = new DbParameter[] { 
43                                      new SqlParameter { ParameterName = "proID", Value = proID},
44                                      new SqlParameter("catID",catID)
45                                   };
46                     _DataModelEntity.ExecuteStoreCommand(sql, args);
47                 }
48                 catch (System.Exception ex)
49                 {
50                     LogHelper.WriteLog(ex);
51                     result = false;
52                 }
53             }
54             return result;
55         }
复制代码
执行SQL
复制代码

  实际上已经有不少博文中提到了这些使用方法,这里我只是强调它的使用条件,大部分环境下,LINQ和EF的配合已经趋于完美了。

  转载请注明原址: http://www.cnblogs.com/lekko/archive/2013/05/28/3103374.html

 

 

 

在Entity Framework 中执行T-sql语句

从Entity Framework 4开始在ObjectContext对象上提供了2个方法可以直接执行SQL语句:ExecuteStoreQuery<T>ExecuteStoreCommand。

1、使用ExecuteStoreQuery<T> :通过sql查询返回object实体,有有许多需要注意:

1.sql = "select * from Payment where Vendor= @vendor";之所以能写成select *是因为Payment对象的属性和表的字段命名完全一致,如果不一致的话,需要将表字段取别名,别名需是对象映射的属性名称。

2.如果sql语句返回的列少于(具体化)实体的属性的个数,那么EF在具体化的时候将抛出一个异常如下图,因此将需要缺少的列补上一些没有意义的值,以保证在具体乎的时候不会报错:eg 如图1,如果sql=”select PaymentId ,Amount from Payment ” 这样使用context.ExecuteStoreQuery<Payment >(sql, args);那么会报异常,因此需要将Vendor 列补上 。正确的sql=”select PaymentId ,Amount, null as Vendor from Payment”。

3.如果sql 返回的列 多余具体化的实体属性的个数,那么EF将会忽视多出的列。

4.如果是你返回的表是映射到几个继承关系的实体类上,那么返回的行需要具体化到几个实体上,EF是无法根据识别列来将返回的行具体化到相应的继承类型上去,这是EF会抛出一个运行时的exception

5.如果实体有complex Type属性,那么实体对象的实例是无法用ExecuteStoreQuery()来返回的,因为ExcuteStoreQuery()是无法返回一个complex Type的集合的.返回单个complex type是支持的,但是返回的实体对象里包含complex type就不支持。

6.可以返回实体对象属性的子集,就是说如果对于Payment表,我们查询返回PaymentId和Amount字段,然后我们定义一个subPayment 实体包含PaymentId和Amount属性,然后使用ExcuteStoreQuery<subPayment>()

2、使用ExecuteStoreCommand:这个更加灵活,你可以执行Update,Insert,Delete语句。

using (SzmbEntities entity = new SzmbEntities())
{
var item = entity.Weatherwarnings.OrderByDescending(x=>x.Id)
.Where(x => x.PublishTime < now.AddDays(-14))
.FirstOrDefault();
if (item != null)
          {
string sql = "Delete FROM [Weatherwarning] where Id < @ID";
var args = new DbParameter[] {
new SqlParameter { ParameterName = "ID", Value = item.Id}
                 };
entity.ExecuteStoreCommand(sql,args);
           }
  }

ExecuteStoreCommand()返回一个int值,影响的行数。

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值