【发布时间】:2010-02-16 03:56:48
【问题描述】:
我有一个简单的查询,如下所示
var trips = from t in ctx.Trips
select t;
问题是我在 Trip 对象上有一个额外的属性需要分配,最好不要遍历返回的 IQueryable。
有谁知道如何在查询期间设置值? (即选择t, t.property = "value")
【问题讨论】:
标签: c# asp.net linq-to-sql
我有一个简单的查询,如下所示
var trips = from t in ctx.Trips
select t;
问题是我在 Trip 对象上有一个额外的属性需要分配,最好不要遍历返回的 IQueryable。
有谁知道如何在查询期间设置值? (即选择t, t.property = "value")
【问题讨论】:
标签: c# asp.net linq-to-sql
首先,如果您从不遍历结果,您的代码将无法运行。 LINQ 是“惰性的”,这意味着它只在您请求时计算下一个结果。
但是,如果您确实需要按照您的要求做,请尝试以下操作:
Trip SetProperty(Trip t)
{
t.property = "value";
return t;
}
var trips = from t in ctx.Trips select SetProperty(t);
【讨论】:
这可行:
var trips = from t in ctx.Trips select new Trip
{
// db properties
t.ID,
t.Name,
t.Description,
// non-db properties
SomeValue = 45,
SomeOtherValue = GetValueFromSomewhereInCode(t.ID)
}
通过将数据库行投影到“新”Trip 对象中,您可以设置不由 LINQ to SQL 填充的属性,而无需任何额外的枚举。您还可以在投影中调用自定义代码,因为它在代码中执行,而不是作为发送到数据库的 SQL 语句的一部分。
但是,生成的 Trip 对象未启用更改跟踪,因此请记住这一点(您无法更改属性并通过 SubmitChanges() 自动更新它们,因为数据上下文不知道您的Trip 对象)。
如果您还需要跟踪更改,则需要在通过 LINQ to SQL 检索到跟踪的 Trip 对象后再次枚举它们。不过这并不是真正的问题,因为它应该是内存中的迭代。
【讨论】:
如果不想遍历 Trips 序列,最好使用存储过程或参数化查询直接更新数据库。
如果您担心 Trips 序列将包含太多项目并且处理速度很慢,您当然可以在 where 子句中添加更多过滤。
如果这是不可能的,这只是使用存储过程等在数据库上处理非常大的结果集的另一个原因。
否则,通常的 LINQ to SQL 方法类似于:
using (var context = new DefaultDataContext())
{
var defects = context.Defects.Where(d => d.Status==Status.Open);
foreach(Defect d in defects)
{
defect.Status = Status.Fixed;
defect.LastModified = DateTime.Now;
}
context.SubmitChanges();
}
【讨论】: