我现在负责公司一个项目的框架设计,老板要用vs2008开发(老板比较喜欢MS的新技术
),既然用vs2008,当然是用.Net Framework3.5里新的东西.Linq自然是被选中. 目前是用Linq to SQL实现一个轻量级的ORM. Linq to SQL的CRUD中,Delete功能很是BT,已用自己的方法实现了Delete操作了. 扯远了,现在来说一下主题.
刚开始设计时,返回Entity数据都是返回所有的列,有的业务操作自然是不需要Entity的所有列,所以我想当然的这样写:
var querys = from order in this.dataContext.Orders
where order.CustomerID == customerId
select new Orders
{
order.OrderID,
order.OrderDate,
order.ShipName
};
谁知竟然报错,到网上查了,才知MS没有供对Entity只返回某几列的功能,要不是公司开着空调,我可能要晕死了. 
但不能不提供只返回Entity某几列的方法啊,这是性能优化的必备条件之一,只能通过间接方法来实现了.
想到DataContext.ExecuteQuery()方法可以返回Entity,它接受sql语句,而DataContext.GetCommand()方法可以得到一个DbCommand对象,不就得到CommandText的sql语句吗?
而DataContext.GetCommand()方法的IQueryable参数不就是我们的查询表达式的结果吗?
实现的方法:
public IEnumerable<T> RetriveMultipleByQueryable1<T>(IQueryable query)
{
DbCommand dc = this.dataContext.GetCommand(query);

object[] prms = new object[dc.Parameters.Count];
string sql = dc.CommandText;
for (int i = 0; i < dc.Parameters.Count; i++)
{
sql = sql.Replace(dc.Parameters[i].ParameterName, "{" + i.ToString() + "}");
prms[i] = dc.Parameters[i].Value;
}

IEnumerable<T> result = this.dataContext.ExecuteQuery<T>(sql, prms);
return result;
}
在这里,因为ExecuteQuery()的需要,要将DbCommand.CommandText的各参数名替换为占位符,比如说DbCommand.CommandText的值形如:
"select .... from ... where field1=@p0 and field2=@p1"
则要替换为:
"select .... from ... where field1={0} and field2={1}"
调用方法:
public List<Orders> GetOrdersByCustomerId(string customerId)
{
var querys = from order in this.dataContext.Orders
where order.CustomerID == customerId
select new
{
order.OrderID,
order.OrderDate,
order.ShipName
};
IEnumerable<Orders> result = this.RetriveMultipleByQueryable1<Orders>(querys);

return result.ToList();
}
在这里,用到了匿名类的技术,所以用var来声明。我们并不会去产生匿名类的实例,用它只是为了达到选择Entity某几列的目的。
大功告成。
总的来说,Linq to SQL是很强的,但缺点也不少,希望MS对其完善一些。
刚开始设计时,返回Entity数据都是返回所有的列,有的业务操作自然是不需要Entity的所有列,所以我想当然的这样写:
var querys = from order in this.dataContext.Orders
where order.CustomerID == customerId
select new Orders
{
order.OrderID,
order.OrderDate,
order.ShipName
};
但不能不提供只返回Entity某几列的方法啊,这是性能优化的必备条件之一,只能通过间接方法来实现了.
想到DataContext.ExecuteQuery()方法可以返回Entity,它接受sql语句,而DataContext.GetCommand()方法可以得到一个DbCommand对象,不就得到CommandText的sql语句吗?
而DataContext.GetCommand()方法的IQueryable参数不就是我们的查询表达式的结果吗?
实现的方法:
public IEnumerable<T> RetriveMultipleByQueryable1<T>(IQueryable query)
{
DbCommand dc = this.dataContext.GetCommand(query);
object[] prms = new object[dc.Parameters.Count];
string sql = dc.CommandText;
for (int i = 0; i < dc.Parameters.Count; i++)
{
sql = sql.Replace(dc.Parameters[i].ParameterName, "{" + i.ToString() + "}");
prms[i] = dc.Parameters[i].Value;
}
IEnumerable<T> result = this.dataContext.ExecuteQuery<T>(sql, prms);
return result;
}
"select .... from ... where field1=@p0 and field2=@p1"
则要替换为:
"select .... from ... where field1={0} and field2={1}"
调用方法:
public List<Orders> GetOrdersByCustomerId(string customerId)
{
var querys = from order in this.dataContext.Orders
where order.CustomerID == customerId
select new
{
order.OrderID,
order.OrderDate,
order.ShipName
};
IEnumerable<Orders> result = this.RetriveMultipleByQueryable1<Orders>(querys);
return result.ToList();
}
大功告成。
总的来说,Linq to SQL是很强的,但缺点也不少,希望MS对其完善一些。

浙公网安备 33010602011771号