2011-07-05 25 views
2

我新的實體框架(與NHibernate用ActiveRecord之前大部分的工作),我被卡住的東西,我認爲應該很容易......如何使用Entity Framework訪問上下文之外的實體屬性?

我有一個User實體,創造局部User類所以我可以添加一些方法(比如NHibernate)。我加GetByID,使用戶獲得更輕鬆:

public static User GetByID(int userID) 
{ 
    using (var context = new MyEntities()) 
    { 
     return context.Users.Where(qq => qq.UserID == userID).Single(); 
    } 
} 

現在在同一個班我想登錄登錄的時刻,我嘗試做:

public static void LogLoginInfo(int userID) 
{ 
    using (var context = new MyEntities()) 
    { 
     var user = User.GetByID(userID); 
     var log = new LoginLog { Date = DateTime.Now }; 
     user.LoginLogs.Add(log); 
     context.SaveChanges(); 
    } 
} 

的問題是我不能訪問user.LoginLogs因爲user's上下文已經佈置......最有可能的,我缺少明顯的東西在這裏,但創造總是充滿查詢:

context.Users.Where(qq => qq.UserID == userID).Single().LoginLogs.Add(log); 

d似乎不是一個好選擇...

我已經閱讀了關於Repository模式,但我認爲這對於這樣的任務來說太大了。請解釋我做錯了什麼。提前致謝!

編輯

要想象我想做什麼:

//somewhere in business logic 
var user = User.GetByID(userID); 
var posts = user.GetAllPostsForThisMonth(); 
foreach(var post in posts) 
{ 
    Console.WriteLine(post.Answers.Count); 
} 

通常情況下我不能這樣做,因爲我不能讓post.Answers沒有上下文...

+0

請注意,如果找不到記錄,GetByID將引發異常。而是使用FirstOrDefault(); – Jethro

回答

1

您正在關閉對象上下文,然後嘗試向分離的用戶添加日誌。您需要附加用戶,以便objectContext知道已更改或添加了哪些內容。

public static void LogLoginInfo(int userID) 
{ 
    using (var context = new MyEntities()) 
    { 
     var user = context.User.Where(p=>p.UserID == userID); //<= The Context now knows about the User, and can track changes. 
     var log = new LoginLog { Date = DateTime.Now }; 
     user.LoginLogs.Add(log); 
     context.SaveChanges(); 
    } 
} 

更新
您還可以附加的對象。

public static void LogLoginInfo(int userID) 
{ 
    using (var context = new MyEntities()) 
    { 
     var user = User.GetByID(userID); 
     var log = new LoginLog { Date = DateTime.Now }; 
     user.LoginLogs.Add(log); 
     context.User.Attach(user); 
     context.SaveChanges(); 
    } 
} 

更新

var getFirstLogin = from p in User.GetUserById(userId) 
        select p.LoginLogs.FirstOrDefault(); 

NB如果LoginLogs是一個不同的表,你將需要使用包含。

public static User GetByID(int userID) 
{ 
    using (var context = new MyEntities()) 
    { 
     return context.Users.Include("LoginLogs").Where(qq => qq.UserID == userID).FirstOrDefault(); 
    } 
} 
+0

那麼沒有其他辦法了?這是我想要避免的,因爲這只是最簡單的例子,我將多次使用這些查詢並且不想在方法中關閉它們。這在NHibernate中是完全可能的,所以我希望它能在這裏類似... – Episodex

+0

@Episodex,請參閱我上面更新的示例。 – Jethro

+0

謝謝,附加在這種情況下做的工作:)。但請回答我的最後一個問題,是否有可能以某種方式在外部環境之外做這樣的事情:'var firstLog = User.GetByID(userID).LoginLogs.First();'? – Episodex

0

如果你是開放的使用存儲過程(以及他們與EF很好地工作),你可以回報用戶對象,同時對數據庫的單次調用添加到日誌表。

我以前在EF/ORM前的日子裏用SP做了所有的事情,當我去EF時,我非常努力地避免使用存儲過程來避免回到我的舊習慣,但是現在我發現有選擇地使用存儲過程,您可以享受到EF方式的優勢,以及SP可以提供的超級功能/性能。

+0

問題是日誌記錄只是示例。我試圖找到一種方法來訪問我的實體的完整屬性,而無需在任何地方創建上下文(當我使用任何快捷方法選擇實體時,結果仍然不起作用)。也許我在我的問題上太不清楚了:)。簡而言之,我希望像NHibernate中解決的那樣管理實體。 – Episodex

相關問題