开发者

How to access entity's properties outside context using Entity Framework?

开发者 https://www.devze.com 2023-03-17 06:10 出处:网络
I\'m new to Entity Framework (working mostly with NHibernate with ActiveRecord before) and I\'m stuck with something, that I think should be easy...

I'm new to Entity Framework (working mostly with NHibernate with ActiveRecord before) and I'm stuck with something, that I think should be easy...

I have a User Entity, and created partial User class so I can add some methods (like with NHibernate). I added GetByID to make getting user easier:

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

Now in the same class I want to log moment of logging in, and I try to do:

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();
    }
}

The problem is I can't access user.LoginLogs because user's context is already disposed... Most likely I'm missing something obvious here, but creating always full queries like:

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

doesn't seem like a good option...

I've read about Repository pattern but I think it's too big gun for such task. Please explain me what am I doing wrong. Thanks in advance!

EDIT

To picture what I'd like to do:

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

Normally I'm not allowed to do this because I can't get post.Answers开发者_运维技巧 without context...


You are closing the object context and then trying to add a log to the user that is detached. You need to attach the user so the objectContext know what has been changed or added.

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();
    }
}

Update
You can also attach the object.

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();
    }
}

Update

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

NB if LoginLogs is a different table you will need to use Include.

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


If you are open to using stored procedures (and they work nicely with EF), you can return the user object and simultaneously add to the log table with a single call to the database.

I used to do everything with SP's in my pre-EF/ORM days, when I went to EF I tried very hard to avoid using stored procedures to avoid falling back into my old habits, but now I have found that the selective use of stored procedures you can have the benefits of both -the EF way of doing things, and the super functionality/performance that a well written SP can provide.

0

精彩评论

暂无评论...
验证码 换一张
取 消