c# – EF Code First通用检查没有公共ID属性的对象的存在?
编辑:在这个问题的底部回答
好的,所以我有一些通用的EF功能(我从这里得到了大部分功能),但它们似乎没有用. 我有3节课: public class Group : Entity { public Guid Id { get; set; } public string Name { get; set; } public string Description { get; set; } public virtual GroupType GroupType { get; set; } public virtual ICollection<User> Users { get; set; } } public class GroupType: Entity { public Guid Id { get; set; } public string Name { get; set; } public string Description { get; set; } } public class User: Entity { public Guid Id { get; set; } public string FirstName { get; set; } public string MiddleName { get; set; } public string LastName { get; set; } public string UserName { get; set; } public virtual ICollection<Group> Groups { get; set; } } 我的CRUD操作: public void Insert(TClass entity) { if (_context.Entry(entity).State == EntityState.Detached) { _context.Set<TClass>().Attach(entity); } _context.Set<TClass>().Add(entity); _context.SaveChanges(); } public void Update(TClass entity) { DbEntityEntry<TClass> oldEntry = _context.Entry(entity); if (oldEntry.State == EntityState.Detached) { _context.Set<TClass>().Attach(oldEntry.Entity); } oldEntry.CurrentValues.SetValues(entity); //oldEntry.State = EntityState.Modified; _context.SaveChanges(); } public bool Exists(TClass entity) { bool exists = false; if(entity != null) { DbEntityEntry<TClass> entry = _repository.GetDbEntry(entity); exists = entry != null; } return exists; } public void Save(TClass entity) { if (entity != null) { if (Exists(entity)) _repository.Update(entity); else _repository.Insert(entity); } } 最后我用以下方法调用此代码: public string TestCRUD() { UserService userService = UserServiceFactory.GetService(); User user = new User("Test","Test","TestUser") { Groups = new Collection<Group>() }; userService.Save(user); User testUser = userService.GetOne(x => x.UserName == "TestUser"); GroupTypeService groupTypeService = GroupTypeServiceFactory.GetService(); GroupType groupType = new GroupType("TestGroupType2",null); groupTypeService.Save(groupType); GroupService groupService = GroupServiceFactory.GetService(); Group group = new Group("TestGroup2",null) { GroupType = groupType }; groupService.Save(group); user.Groups.Add(group); userService.Save(user); return output; } 当我到达: user.Groups.Add(group); userService.Save(user); 我收到以下错误:
具有以下内部异常:
问题: 1)Exists总是返回true,即使实体刚刚在内存中创建,因此insert实际上永远不会被调用Save方法中的Update,我想这是因为我完全不了解DbEntityEntry因为它本身和Entry.Entity都是永远不会.我如何检查存在? 2)即使所有代码都在TestCRUD中运行直到最后,这些实体实际上都没有保存到数据库中.我很肯定我的数据库设置正确,因为我的自定义初始化程序正在丢弃并始终重新创建数据库并每次都插入种子数据.这可能是因为更新始终按照编号1中的说明进行调用. 任何想法如何解决? 编辑:答案 假设,问题是存在总是返回true,因此插入从未被调用.我通过使用反射来获取主键并将其插入到find方法中来修复此问题,以便像这样存在: public bool Exists(TClass entity) { bool exists = false; PropertyInfo info = entity.GetType().GetProperty(GetKeyName()); if (_context.Set<TClass>().Find(info.GetValue(entity,null)) != null) exists = true; return exists; } 所有其他方法开始按预期工作.但是,我在同一行上遇到了不同的错误: user.Groups.Add(group); userService.Save(user); 这是:
我将把它作为一个新问题发布,因为它是一个新错误,但它确实解决了第一个问题. 解决方法
我通常看到人们检查实体是否已经存在的方式是检查其Id属性是否大于零.您应该能够使用带有Id属性的接口,或者(如果您希望实体具有多个键属性),您可以让每个实体覆盖一个抽象基类,覆盖Exists属性以检查其自己的ID属性非默认值.或者您可以使用反射自动查找ID属性,as explained here. 我怀疑,如果您正确插入新项目而不是尝试更新它们,其余问题将会消失. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |