是否有任何簡單的方法來訪問linq2sql實體類中的DataContext
。訪問實體類中的LINQ-2-SQL DataContext
我試圖創建類似EntitySet
的東西,但我無法弄清楚EntitySet
如何訪問創建實體對象的上下文。
我想要一個常規的linq2sql實體類,以便類訪問創建它的DataContext
。我知道這是可能的,因爲當你有一個主鍵的實體類linq2sql給你的選項加載所有的孩子,而不會創建一個新的DataContext
。
是否有任何簡單的方法來訪問linq2sql實體類中的DataContext
。訪問實體類中的LINQ-2-SQL DataContext
我試圖創建類似EntitySet
的東西,但我無法弄清楚EntitySet
如何訪問創建實體對象的上下文。
我想要一個常規的linq2sql實體類,以便類訪問創建它的DataContext
。我知道這是可能的,因爲當你有一個主鍵的實體類linq2sql給你的選項加載所有的孩子,而不會創建一個新的DataContext
。
基本上沒有。
EntitySet<T>
類具有由數據上下文分配的內部Source
屬性,它是按照數據按需獲取的屬性。但是,數據類本身沒有任何相似之處。
但是,我相信實體框架有更多的訪問權限,這是以強制對象層次結構爲代價的。與實體框架不同,LINQ-to-SQL(按設計)可以與常規的持久性無關類一起使用 - 所以它並不假定它可以訪問這種類型的數據。
實體類不應該知道它的只是表,但數據上下文的映射數據上下文的具有所有實體的知識和連接屬性
您可以鏈接到子表通過父實體類,因爲實體關係而不是通過數據上下文
數據上下文類將用在實體消耗的最後,我沒有看到實體需要知道的情況下,
如果你可以告訴具體情況,我們可以嘗試其他方法。
我確切地知道你的意思。我們應該在實體的部分類中進行計算/驗證,但是如果實體無法訪問datacontext,那麼我們可以做多少?例如,在我的SalesOrder對象中,只要「寄送地址」地址發生變化,SalesOrder就需要查詢數據庫以確定是否適用於該州/郵政編碼。我一直在爭取這一段時間,但今天我失敗了,並採用了醜陋的方法,但目前爲止這麼好。基本上,我所做的只是在分部類中創建一個「Context」屬性,並在創建實體時將其設置爲datacontext。
Partial Class SalesOrder
Private moContext As L2S_SalesOrdersDataContext
Friend Property Context() As L2S_SalesOrdersDataContext
Get
Return moContext
End Get
Set(ByVal value As L2S_SalesOrdersDataContext)
moContext = value
End Set
End Property
...
YMMV,特別是如果你是分離你的實體。
基本上,你可以用一點黑客來做到這一點。 DataContext的附加一個StandardChangeTracker到你的實體:
DataContext context = null; object changeTracker = (from i in o1.GetInvocationList() where i.Target.GetType().FullName == "System.Data.Linq.ChangeTracker+StandardChangeTracker" select i.Target).FirstOrDefault(); if (changeTracker != null) // DataCOntext tracks our changes through StandardChangeTracker { object services = Reflector.GetFieldValue(changeTracker, "services"); context = (DataContext)Reflector.GetFieldValue(services, "context"); }
凡Reflector.GetFieldValue等於
public static object GetFieldValue(object instance, string propertyName) { return instance.GetType().GetField(propertyName, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(instance); }
我剛剛做同樣的事情。這是我的解決方案(儘管可能不是最好的方法,但至少相當優雅):
首先,爲所有實體創建一個接口,以實現從INotifyPropertyChanging繼承。這是用來連接一些擴展方法,並保持我們的實現很好獨立。在我的情況下,接口被稱爲ISandboxObject:
public interface ISandboxObject : INotifyPropertyChanging
{
// This is just a marker interface for Extension Methods
}
然後創建一個新的靜態類包含一個擴展方法獲得的DataContext。這是通過在連接到INotifyPropertyChanging.PropertyChanging事件的LINQ變更跟蹤器上查找事件處理程序來實現的。一旦我們發現變更跟蹤,我們可以從那裏獲得的DataContext:
/// <summary>
/// Obtain the DataContext providing this entity
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static DataContext GetContext(this ISandboxObject obj)
{
FieldInfo fEvent = obj.GetType().GetField("PropertyChanging", BindingFlags.NonPublic | BindingFlags.Instance);
MulticastDelegate dEvent = (MulticastDelegate)fEvent.GetValue(obj);
Delegate[] onChangingHandlers = dEvent.GetInvocationList();
// Obtain the ChangeTracker
foreach (Delegate handler in onChangingHandlers)
{
if (handler.Target.GetType().Name == "StandardChangeTracker")
{
// Obtain the 'services' private field of the 'tracker'
object tracker = handler.Target;
object services = tracker.GetType().GetField("services", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(tracker);
// Get the Context
DataContext context = services.GetType().GetProperty("Context").GetValue(services, null) as DataContext;
return context;
}
}
// Not found
throw new Exception("Error reflecting object");
}
現在你有一個很好的擴展方法,它會爲您提供從實施ISandboxObject任何對象一個DataContext。在憤怒中使用它之前,請確保在其中添加更多錯誤檢查!
我有同樣的問題,雖然我理解你的論點(相信我,我贊成它),但我對此有真實的需求。 在我們的一些實體部分類中,我們添加了一些必須根據實體的屬性來查詢數據庫的屬性,以獲取一些其他實體集合,這些實體並不直接與SQL Server關聯。這真的很難看,因爲我們在調用這些屬性時創建一個新的數據上下文(其中一些屬於循環)。 – 2010-04-18 04:02:31