Entity Framework 6 查询时上下文重复
Posted
技术标签:
【中文标题】Entity Framework 6 查询时上下文重复【英文标题】:Entity Framework 6 Context duplicate while query 【发布时间】:2015-05-27 09:21:23 【问题描述】:我有一些我无法解决的问题。在我的项目中,我首先使用 EF6 Code。我创建了一些模型,但它们的头部是用户模型:
public class User
[Required]
public Guid Id get; set;
[Required, MaxLength(20), MinLength(5), UniqProp]
public string Login get; set;
[Required, MaxLength(20), MinLength(8)]
public string Password get; set;
[Required]
public Role Role get; set;
[Required]
public string FirstName get; set;
[Required]
public string LastName get; set;
[Required, UniqProp]
public string Email get; set;
[Required]
public string City get; set;
public virtual List<Ticket> Tickets get; set;
我还创建了自己的上下文,如下所示:
public class TheatreContext : DbContext
public DbSet<User> Users get; set;
public DbSet<Role> Roles get; set;
public DbSet<Ticket> Tickets get; set;
public DbSet<Play> Plays get; set;
在此之后,我以这种方式初始化我的数据库:
using (var db = new TheatreContext())
Adding objects to db and save changes.
那时一切正常。所有数据都添加到数据库中。然后我决定创建我的Repository
类来使用 db 进行一些操作:
public class TheatreRepository<T> : IRepository<T> where T: class
private readonly TheatreContext _context;
private readonly DbSet<T> _dbSet;
public TheatreRepository()
_context = new TheatreContext();
_dbSet = _context.Set<T>();
public void Add(T entity)
_dbSet.Add(entity);
public DbSet<T> GetAll()
return this._dbSet;
public void Commit()
_context.SaveChanges();
当我尝试以这种方式添加新用户时:
var repo = new TheatreRepository<User>();
var roleRepo = new TheatreRepository<Role>();
var newUser = new User
Id = Guid.NewGuid(),
Login = "Lionqweq",
City = "Minsk",
Role = roleRepo.GetAll().First(role => role.RoleType == RoleType.User),
FirstName = "Alex",
Email = "AlexDanger@gmail.com",
Password = "dsas1qsqda",
LastName = "Ivanov"
;
repo.Add(newUser);
repo.Commit();
在调用Commit
(数据库中的SaveChanges
)时,它会抛出DbUpdateException
,因为我尝试使用现有ID 添加到Role
表对象。这对我来说没有意义!实际上我没有添加任何角色,我尝试仅添加User
。
我的Role
表在本地包含的内容:
我在本地的Users
表中拥有的内容:
请有任何建议和想法!我很困惑
【问题讨论】:
【参考方案1】:你应该尝试而不是
[Required]
public Role Role get; set;
要使用也使用对 FK 的引用:
[Required]
public Guid RoleId get; set;
public virtual Role Role get; set;
当你创建一个新用户时,只设置 RoleId
这是一个例子: EF first code
【讨论】:
亲爱的丹妮,谢谢!你对我帮助很大!我以这种方式解决了它: public Guid RoleId get;放; [ForeignKey("RoleId")] public virtual Role Role get;放; 【参考方案2】:你的问题来了
public TheatreRepository()
_context = new TheatreContext();
_dbSet = _context.Set<T>();
如果您正在实现存储库模式,那么您的存储库类必须在构造函数中获取上下文,即 DI,所以它必须是这样的
public TheatreRepository(TheatreContext context)
_context = context;
_dbSet = _context.Set<T>();
解释:
存储库必须使用相同的上下文来跟踪发生的更改和加载的(本地)实体,因此请考虑在存储库之前声明您的上下文,如下所示:
var db = new TheatreContext();
var repo = new TheatreRepository<User>(db);
var roleRepo = new TheatreRepository<Role>(db);
var newUser = new User
Id = Guid.NewGuid(),
Login = "Lionqweq",
City = "Minsk",
Role = roleRepo.GetAll().First(role => role.RoleType == RoleType.User),
FirstName = "Alex",
Email = "AlexDanger@gmail.com",
Password = "dsas1qsqda",
LastName = "Ivanov"
;
repo.Add(newUser);
repo.Commit();
【讨论】:
你是说他们都应该使用相同的 TheatreContext 实例吗? (“必须注入依赖项”并不完全暗示) 所以这意味着我只能为所有存储库创建一个上下文?如果我是对的,这意味着对于每个表,我也会将我的数据存储在本地,并且我会占用大量资源以上是关于Entity Framework 6 查询时上下文重复的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework 6 - . 创建新对象,保存更改,根据新 id 重新查询对象,返回 null
Entity Framework Core - 在尝试运行第二个查询时释放
为啥要使用 Attach 来更新 Entity Framework 6?