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>
在 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>