2011-07-05 15 views
2

私は(前のActiveRecordとNHibernateのとほとんど作業)Entity Frameworkのに新たなんだと私は簡単なはずだと思うことを何か、とこだわっている...Entity Frameworkを使用してコンテキスト外のエンティティのプロパティにアクセスする方法

私はUserエンティティを持っており、部分的Userクラスを作成しましたNHibernateのようないくつかのメソッドを追加することができます。

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

は今、同じクラスに私はログインの瞬間を記録したい、と私はやろう:私は、簡単にユーザーを取得するためにGetByIDを追加

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'sコンテキストがすでに配置されているアクセスuser.LoginLogsので...多分私はここで何かを明らかに不足しているが、同様に常にフルクエリを作成しています:

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

D私は良い選択肢のように見えません...

私はリポジトリのパターンについて読んだことがありますが、それはそのような仕事のためには大きすぎると思います。私が間違っていることを教えてください。前もって感謝します!私がやりたいものを画像に

EDIT

:私は、コンテキストなしでpost.Answersを取得することはできませんので

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

通常、私はこれを行うことは許されないよ...

+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とうまく動作する)ストアドプロシージャを使用する開いている場合は、ユーザーオブジェクトを返すと同時に、データベースへの1回の呼び出しでログテーブルに追加することができます。

以前のEF/ORMの日に私はSPですべてをやっていましたが、私はEFに行きましたが、私の古い習慣に落ちるのを避けるためにストアドプロシージャを避けようと非常に努力しましたが、ストアドプロシージャを選択的に使用すると、EFのやり方と、よく書かれたSPが提供できる優れた機能性/パフォーマンスの両方の利点を得ることができます。

+0

ロギングは単なる例に過ぎません。私はどこでもコンテキストを作成せずにエンティティの完全なプロパティにアクセスする方法を見つけようとします(エンティティを選択するためのショートカットメソッドを使用するとうまくいきません)。たぶん私は私の質問ではあまりにも不明です:)。要するに、NHibernateで解決されるように、エンティティを途中で管理したいと思います。 – Episodex

関連する問題