Как получить доступ к свойствам объекта вне контекста, используя Entity Framework? - PullRequest
2 голосов
/ 05 июля 2011

Я новичок в Entity Framework (раньше работал в основном с NHibernate с ActiveRecord), и я застрял с чем-то, что я думаю, должно быть легко ...

У меня есть User Entity,и создал частичный 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);

некажется хорошим вариантом ...

Я читал о шаблоне репозитория, но я думаю, что это слишком большой пистолет для такой задачи.Пожалуйста, объясните мне, что я делаю не так.Спасибо заранее!

РЕДАКТИРОВАТЬ

Чтобы изобразить, что я хотел бы сделать:

//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 без контекста ...

Ответы [ 2 ]

1 голос
/ 05 июля 2011

Вы закрываете контекст объекта и затем пытаетесь добавить журнал для отсоединенного пользователя. Вам необходимо присоединить пользователя, чтобы 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();

Примечание: если LoginLogs - это другая таблица, вам нужно будет использовать Include.

public static User GetByID(int userID)
{
    using (var context = new MyEntities())
    {
       return context.Users.Include("LoginLogs").Where(qq => qq.UserID == userID).FirstOrDefault();
    }
}
0 голосов
/ 06 июля 2011

Если вы открыты для использования хранимых процедур (и они прекрасно работают с EF), вы можете вернуть пользовательский объект и одновременно добавить в таблицу журналов один вызов в базу данных.

Раньше я делал все с SP в мои дни до EF / ORM, когда я перешел на EF, я очень старался избегать использования хранимых процедур, чтобы не вернуться к своим старым привычкам, но теперь я обнаружил, что избирательное При использовании хранимых процедур вы можете получить преимущества как от способа работы EF, так и от супер функциональности / производительности, которую может обеспечить хорошо написанный SP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...