ApplicationDbContext 中的空 dbSet

Empty dbSet in ApplicationDbContext

在 mvc5 应用程序中,我在文件夹 "Models" 中创建 class:

public class Code
{
    [Key]
    public Guid Id { get; set; }
    public string UserId { get; set; }
}

并进行迁移。

我还得到 class(上下文,自动生成):

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
    public DbSet<Code> Codes { get; set; }
}

在我的一个控制器中我写了方法:

using (var db = new ApplicationDbContext())
{
    var manager =
        new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));
    var user = manager.FindById(User.Identity.GetUserId());
    Code codeD = new Code();
    codeD.Id = Guid.NewGuid();
    codeD.UserId = user.Id;
    db.Codes.Add(codeD);
    db.SaveChanges();
}

但每次我这样做时,db.Codes 得到 0 个项目。

但是在我的数据库中保存了更改并且我得到了这些项目:

有谁知道造成这种现象的原因吗?我无法访问数据库中的项目,但我可以自由保存新项目。有人知道吗,如何从我的数据库中获取所有 "Codes"?

我使用生成的 mvc5 项目,所以 ApplicationUserDbContext 自动生成。

亲切的问候。

开始为未来的搜索者回答:

在 Entity Famework 中看到查询结果之前,您必须具体化视图。 EF returns IQueryable 来自它的大部分方法。 IQueryable 实际上是一种允许 EF 继续构建从数据库中获取所需数据所需的 sql 的机制。这就是为什么在调试视图中查看 DbSet 时它会显示类似 Select [Columns] From [table] as Extent1 的原因。只是 SQL 还没有被执行。当您实际尝试访问 属性 或集合中的对象时,EF 会将查询发送到数据库并具体化结果。

在大多数情况下,将结果具体化应该是自然而然的事情。如果您需要一个用户列表,您应该调用 ToList() 方法来实现结果。如果你只想要一条记录,你应该使用 FirstOrDefault() 方法来实现一条记录或者 null 如果没有找到。

示例:

//Materializing a collection of users
public ActionResult Users() 
{
    //The DbContext has been initialized elsewhere
    var users = _db.Users.Where(user => user.IsActive).ToList();

    return View(users);
}

//Materializing a single record
public ActionResult User(int userId)
{
    var user = _db.Users.FirstOrDefault(user => user.Id == userId && user.IsActive);
    if (user == null) return HttpNotFound();

    return View(user);
}

请务必注意,如果您处理上下文然后尝试访问视图中的结果,EF 仅在请求时才加载实体可能会导致问题。这将导致异常,因为没有可以为您加载结果的上下文。

您可能需要检查 连接字符串 在您的 Web.config 文件中是否正确。这当然会有所不同,但你应该有一些类似的东西:

<connectionStrings>
  <add name="DefaultConnection" connectionString="Data Source=.\;Initial Catalog=MyDatabaseName;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>