查询结果
LINQ to Entities 查询在转换为命令目录树并执行之后,通常以下列形式之一返回查询结果:
概念模型中零个或多个类型化实体对象的集合或复杂类型的投影。
概念模型支持的 CLR 类型。
内联集合。
匿名类型。
对数据源执行查询时,结果将具体化为 CLR 类型并返回客户端。 所有对象具体化均由实体框架执行。 由于无法在实体框架与 CLR 之间进行映射而导致的任何错误都将导致在对象具体化过程中引发异常。
如果查询执行返回基元概念模型类型,则结果由独立的且与实体框架断开连接的 CLR 类型组成。 但如果查询返回 ObjectQuery<T> 所表示的类型化实体对象的集合,则这些类型由对象上下文进行跟踪。 所有对象行为(如父/子集合、更改跟踪、多态性等)都在实体框架中定义。 此功能可按照实体框架中的定义使用。 有关详细信息,请参阅使用对象。
从查询返回的结构类型(如匿名类型和可以为 null 的复杂类型)可以是 null
值。 返回的实体的 EntityCollection<TEntity> 属性也可以是 null
值。 投影值为 null
的实体的集合属性会导致这种情况,例如,调用没有任何元素的 FirstOrDefault 的 ObjectQuery<T>。
在某些情况下,某个查询在其执行期间看似生成具体化结果,但该查询将在服务器上执行,实体对象绝不会在 CLR 中具体化。 如果对象具体化的副作用对您有很大影响,这可能会导致问题。
下面的示例包含一个自定义类 MyContact
,该类有一个 LastName
属性。 如果设置 LastName
属性,count
变量就会递增。 如果执行以下两个查询,则第一个查询将使 count
递增,而第二个查询不会。 这是因为:在第二个查询中,将从结果中投影 LastName
属性,而绝不会创建 MyContact
类,因为这不是对存储区执行查询所必需的。
public static int count = 0;
static void Main(string[] args)
{
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
var query1 = AWEntities
.Contacts
.Where(c => c.LastName == "Jones")
.Select(c => new MyContact { LastName = c.LastName });
// Execute the first query and print the count.
query1.ToList();
Console.WriteLine("Count: " + count);
//Reset the count variable.
count = 0;
var query2 = AWEntities
.Contacts
.Where(c => c.LastName == "Jones")
.Select(c => new MyContact { LastName = c.LastName })
.Select(my => my.LastName);
// Execute the second query and print the count.
query2.ToList();
Console.WriteLine("Count: " + count);
}
Console.WriteLine("Hit enter...");
Console.Read();
}
Public count As Integer = 0
Sub Main()
Using AWEntities As New AdventureWorksEntities()
Dim query1 = AWEntities.Contacts _
.Where(Function(c) c.LastName = "Jones") _
.Select(Function(c) New MyContact With {.LastName = c.LastName})
' Execute the first query and print the count.
query1.ToList()
Console.WriteLine("Count: " & count)
' Reset the count variable.
count = 0
Dim query2 = AWEntities _
.Contacts() _
.Where(Function(c) c.LastName = "Jones") _
.Select(Function(c) New MyContact With {.LastName = c.LastName}) _
.Select(Function(x) x.LastName)
' Execute the second query and print the count.
query2.ToList()
Console.WriteLine("Count: " & count)
End Using
End Sub
public class MyContact
{
String _lastName;
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
count++;
}
}
}
Public Class MyContact
Private _lastName As String
Public Property LastName() As String
Get
Return _lastName
End Get
Set(ByVal value As String)
_lastName = value
count += 1
End Set
End Property
End Class