我已经查看并找不到什么接缝是一个简单的事情的解决方案,我有3个实体当我尝试删除城市或区我得到这个例外:
System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.Entity.Core.UpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlServerCe.SqlCeException: The primary key value cannot be deleted because references to this key still exist. [ Foreign key constraint name = FK_dbo.User_dbo.District_DistrictId ]
我想要达到的目标是: 当我删除一个城市时,所有儿童区都要删除,而不是用户。 当我删除一个区时,只删除该区。 当我删除用户时,仅删除用户。
实体用户
public class User
{
public Guid UserId { get; set; }
public virtual District District { get; set; }
public Guid? DistrictId { get; set; }
}
实体城市
public class City
{
public Guid CityId { get; set; }
public virtual ICollection<District> Districts { get; set; }
}
实体区
public class District
{
public Guid DistrictId { get; set; }
public City City { get; set; }
public Guid CityId { get; set; }
public virtual ICollection<User> Users { get; set; }
}
//EntityTypeConfiguration
HasRequired(d => d.City)
.WithMany(c => c.Districts)
.HasForeignKey(d => d.CityId)
.WillCascadeOnDelete(true);
HasMany(d=> d.Users)
.WithOptional(u=> u.District)
.HasForeignKey(u=> u.DistrictId)
.WillCascadeOnDelete(false);
我尝试在用户映射中放置此配置,但没有任何更改相同的错误
HasOptional(u => u.District)
.WithMany(d => d.Users)
.HasForeignKey(u => u.DistrictId)
.WillCascadeOnDelete(false);
我也在使用Sqlce4和EF6以及Generic Unit of Work & Repositories Framework
感谢您的帮助
此致
答案 0 :(得分:1)
您必须将DistrictId
的{{1}}外键设置为User
,以避免在尝试删除null
或{时违反约束条件{1}}。如果相关的City
未加载到上下文中,EF将不会自动执行此操作。
要删除区域,您可以这样做:
District
删除城市:
Users
Cacsading delete会关注在这里删除这些区域。但是,我不确定在这种情况下,加载用户的// "Include" because you need the users to nullify their FKs to the district
var district = context.Districts.Include(d => d.Users)
.SingleOrDefault(d => d.DistrictId == someDistrictId);
if (district != null)
{
// "Remove" will set the FKs of the LOADED users to null
context.Districts.Remove(district);
context.SaveChanges();
}
是否会设置为var city = context.Cities.Include(c => c.Districts.Select(d => d.Users))
.SingleOrDefault(c => c.CityId == someCityId);
if (city != null)
{
context.Cities.Remove(city);
context.SaveChanges();
}
。如果它不起作用,你必须手动完成:
DistrictId
答案 1 :(得分:1)
谢谢大家,以为EF足够聪明,可以处理像这样的简单任务。 所以不仅要清除区域,不仅仅是城市,这里是我最终使用这个存储库来工作的方式
var city = _unitOfWork.Repository<City>().Query()
.Include(c => c.Districts.Select(d => d.Users))
.Filter(c => c.CityName.Equals(cityName, StringComparison.InvariantCultureIgnoreCase))
.Get().FirstOrDefault();
if (city != null)
{
var districts = city.Districts.ToList();
for (var i = districts.Count - 1; i >= 0; i--)
{
var users = districts[i].Users.ToList();
for (var j = users.Count - 1; j >= 0; j--)
{
users[j].DistrictId = null;
users[j].ObjectState = ObjectState.Modified;
_unitOfWork.Repository<User>().Update(users[j]);
}
districts[i].Users.Clear();
_unitOfWork.Repository<District>().Delete(districts[i]);
}
_unitOfWork.Repository<City>().Delete(city);
很糟糕但是很有效