如何访问实体';使用实体框架在上下文之外的属性

本文关键字:实体 框架 上下文 属性 何访问 访问 | 更新日期: 2023-09-27 18:01:07

我是实体框架的新手(以前主要使用带有ActiveRecord的NHibernate(,我遇到了一些问题,我认为这应该很容易。。。

我有一个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);

这似乎不是一个好的选择。。。

我读过关于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。。。

如何访问实体';使用实体框架在上下文之外的属性

您正在关闭对象上下文,然后尝试向分离的用户添加日志。您需要附加用户,以便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();

注意,如果登录日志是不同的表,则需要使用Include。

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

如果您对使用存储过程持开放态度(并且它们与EF配合得很好(,那么您可以返回用户对象,同时通过对数据库的一次调用将其添加到日志表中。

在EF/ORM之前的日子里,我曾经用SP做任何事情,当我去EF时,我非常努力地避免使用存储过程,以避免回到我的旧习惯,但现在我发现,选择性地使用存储过程可以同时受益-EF做事的方式,以及写得好的SP可以提供的超级功能/性能。