好的,所以我有一些通用的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);
我收到以下错误:
An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.
具有以下内部异常:
The INSERT statement conflicted with the FOREIGN KEY constraint “User_Groups_Source”. The conflict occurred in database “dbnAME”,table “dbo.Users”,column ‘Id’.
问题:
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);
这是:
Violation of PRIMARY KEY constraint ‘PK_GroupTypes_00551192′. Cannot insert duplicate key in object ‘dbo.GroupTypes’.
The statement has been terminated.