編輯:ANSWER AT BOTTOM這個問題EF代碼第一次通用檢查是否存在沒有公共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", "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在內存中,因此插入實際上只是Update
內部的Save
方法,我猜這是因爲我不理解DbE ntityEntry完全是因爲它本身和Entry.Entity都不爲null。我如何檢查存在? 2)即使所有代碼都在TestCRUD中運行,直到最後,這些實體都沒有實際保存到數據庫中。我很積極我的數據庫設置正確,因爲我的自定義初始化程序正在刪除並始終重新創建數據庫,並且每次都插入種子數據。這可能是因爲更新總是被稱爲編號1中提到的。
任何想法如何解決?
編輯:ANSWER
由於假定,問題是Exists
所以插入從來沒有被稱爲總是返回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.
我將發佈,作爲一個新的問題,因爲它是一個新的錯誤,但它確實解決了第一個問題。
將實體附加到上下文後,應將其狀態設置爲添加或修改。請參閱ObjectStateManager.ChangeObjectState方法。 但不能說爲什麼你的Exists方法在保存用戶之前給你的真實。 – ElDog
@ElDog我試過了(你可以看到它在更新中註釋掉了),並且拋出一個錯誤,說不能這樣做,因爲實體在操作之間被修改或刪除,或者出現這種情況。 – SventoryMang