C# 实体框架6代码优先和可选外键问题
我目前正在使用WPF、EF6和SQLServer2012开发一个小型应用程序。我有两个实体Region和bctgouvernoras与可选的一对多关系相关联 我的问题是:当我从关系中删除子BctGouvernorat时,它仍然出现在与父区域相关的集合中。代码如下:C# 实体框架6代码优先和可选外键问题,c#,sql-server,wpf,entity-framework-6,C#,Sql Server,Wpf,Entity Framework 6,我目前正在使用WPF、EF6和SQLServer2012开发一个小型应用程序。我有两个实体Region和bctgouvernoras与可选的一对多关系相关联 我的问题是:当我从关系中删除子BctGouvernorat时,它仍然出现在与父区域相关的集合中。代码如下: //Entities public partial class BctGouvernorat { public long GovId { get; set; } public string Libelle { get;
//Entities
public partial class BctGouvernorat
{
public long GovId { get; set; }
public string Libelle { get; set; }
public long UserId { get; set; }
public Nullable<long> RegionId { get; set; }
public virtual Region Region { get; set; }
}
public partial class Region
{
public long RegionId { get; set; }
public string Libelle { get; set; }
public long GroupeNumber { get; set; }
public byte Bonus { get; set; }
public long UserId { get; set; }
public virtual RegionsGroupes GroupeRegions { get; set; }
public virtual ICollection<BctGouvernorat> Gouvernorats { get; set; }
public Region()
{
Libelle = "New region";
GroupeNumber = 0;
this. Gouvernorats = new HashSet<BctGouvernorat>() ;
}
//Mapping of BctGouvernorat entity
public BctGouvernoratMapping()
{
this.ToTable("BctGouvernorat");
this.HasKey(t => t.GovId);
this.Property(t => t.GovId);
this.HasOptional(t => t.Region)
.WithMany(t => t.Gouvernorats)
.HasForeignKey(d => d.RegionId)
.WillCascadeOnDelete(false);
}
//Mapping of Region entity
public RegionMapping()
{
this.ToTable("Region");
this.HasKey(t => t.RegionId);
this.Property(t => t.RegionId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
//C# code for "Modify" Method
public void Modify(Region r, List<BctGouvernorat> _ToUnlink, List<BctGouvernorat> _ToLink)
{
//Below the code for unlink child from parent
if (_ToUnlink.Count > 0)
{
r.Gouvernorats.ToList().All(xx =>
{
if (_ToUnlink.Contains(xx))
{
xx.RegionId = null;
xx.Region = null;
}
return true;
}
);
}
//Here the code for link child to the parent
_ToLink.All(xx =>
{
xx.RegionId = r.RegionId;
xx.Region = r;
r.Gouvernorats.Add(xx);
return true;
});
//Mark Childs collection as modified
r.Gouvernorats.All(xx =>
{
_uow.GetEntry<BctGouvernorat>(xx).State = EntityState.Modified;
return true;
});
base.Modify(r);
}
而Modify方法使用工作单元的服务将数据保存到sqlserver数据库。代码如下:
//***************************
//_uow is a unit of work
//*****************************
public void RegisterChanged<T>(T item) where T : class
{
base.Entry<T>(item).State = System.Data.Entity.EntityState.Modified;
}
public void Commit()
{
try
{
base.SaveChanges();
}
catch (DbUpdateException e)
{
var innerEx = e.InnerException;
while (innerEx.InnerException != null)
innerEx = innerEx.InnerException;
throw new Exception(innerEx.Message);
}
catch (DbEntityValidationException e)
{
var sb = new StringBuilder();
foreach (var entry in e.EntityValidationErrors)
{
foreach (var error in entry.ValidationErrors)
{
sb.AppendLine(string.Format("{0}-{1}-{2}",
entry.Entry.Entity,
error.PropertyName,
error.ErrorMessage
));
}
}
throw new Exception(sb.ToString());
}
}
抱歉,我应该将调用前面代码的ViewModel代码放在下面:
private void SaveRegion()
{
List<BctGouvernorat> _GovToLink = null;
//The following method checks and returns (Added, Deleted, Modified BctGouvernorat)
List<BctGouvernorat> _GovToUnlink = CheckGouvernoratsListStatus(out _GovToLink);
ILogger _currentLog = (Application.Current as App).GetCurrentLogger();
using (UnitOfWork cx = new UnitOfWork(_currentLog))
{
RegionRepository _regionRepository = new RegionRepository(cx, _currentLog);
IRegionManagementService rms = new RegionManagementService(_currentLog, _regionRepository);
if (CurrentRegion.RegionId == 0)
{
CurrentRegion.UserId = Session.GetConnectedUser().UserId;
rms.AddRegion(CurrentRegion);
}
else
rms.ModifyRegion(CurrentRegion, _GovToUnlink,_GovToLink);
}
}
private List<BctGouvernorat> CheckGouvernoratsListStatus(out List<BctGouvernorat> _ToLink)
{
List<BctGouvernorat> AddedGouvernorats = GouvernoratsRegion.Except<BctGouvernorat>(CurrentRegion.Gouvernorats,
new GouvernoratComparer()).ToList();
_ToLink = AddedGouvernorats;
List<BctGouvernorat> DeletedGouvernorats = CurrentRegion.Gouvernorats.Except<BctGouvernorat>(GouvernoratsRegion,
new GouvernoratComparer()).ToList();
return DeletedGouvernorats;
}
GoUvernorasRegion是绑定到数据网格的observablecollection,我通过编辑该数据网格向该区域添加或删除BCTgouvernorat行
public void ModifyRegion(Region r, List<BctGouvernorat> _ToUnlik, List<BctGouvernorat> _ToLink)
{
_regionRepository.Modify(r, _ToUnlik, _ToLink);
}
您说过删除实体时会出现问题,但此处没有列出执行任何删除的代码,除非我遗漏了什么?我说过关系是可选的,所以我不想从数据库中删除子实体,我只想将其与父实体解除链接。RegionId=nullright,好的,您需要告诉区域BctGouvernorat已被删除,或者需要获取一个新的DbContext对象,该对象将在访问该区域时从数据库中提取该区域的当前状态。如果重新使用上下文,它仍将显示旧的数据库值。很抱歉,迟到了。我编辑了我的问题,所以我添加了mvvm代码,在每次需要数据库访问时使用新的dbcontext。这是断开连接模式。在我看来,您正在创建一个新的DbContext,然后尝试使用以前DbContext中的实体来添加和删除。您是否确认区域实际上被设置为空?
public void ModifyRegion(Region r, List<BctGouvernorat> _ToUnlik, List<BctGouvernorat> _ToLink)
{
_regionRepository.Modify(r, _ToUnlik, _ToLink);
}