查詢結果
LINQ to Entities 查詢轉換成命令樹並且執行之後,查詢結果通常會傳回成為下列其中一種形式:
零個或多個具型別實體物件的集合,或是概念模型中複雜類型的投影。
概念模型支援的 CLR 型別。
內嵌集合。
匿名型別。
針對資料來源執行查詢之後,便會將結果具體化成為 CLR 型別,然後傳回用戶端。 所有物件具體化都是由 Entity Framework 執行。 因為無法在 Entity Framework 與 CLR 之間對應而產生的任何錯誤,都將導致物件具體化期間擲回例外狀況。
如果查詢執行傳回基本概念模型類型,結果將由獨立且從 Entity Framework 中斷連接的 CLR 類型構成。 但是,如果查詢傳回以 ObjectQuery<T> 表示的具型別實體物件集合,這些型別將會由此內容物件追蹤。 所有物件行為 (例如子/父集合、變更追蹤、多型等) 都會如 Entity Framework 中所定義。 這項功能可以依照 Entity Framework 中所定義的能力使用。 如需詳細資訊,請參閱使用物件。
從查詢傳回的結構型別 (例如匿名型別和可為 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