实体框架6 Code First和可选的外键问题

时间:2015-02-13 11:06:59

标签: c# sql-server wpf entity-framework-6

我目前正在使用WPF,EF6和SqlServer 2012开发一个小应用程序。我有两个实体“Region”和“BctGouvernorats”与可选的一对多关系相关联。

我的问题是:当我从关系中删除一个孩子(BctGouvernorat)时,它仍然出现在与父(Region)相关的集合中。这是代码:

//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);

   }

实际上,前面的方法包含在一个«RegionRepository»中,它继承自基类Repository。 base.Modify()的代码如下:

//Method Modify from RegionRepository
 public  void Modify(T item)
   {
      _uow.RegisterChanged(item);
      _uow.Commit();
  }     

并且Modify Method使用将数据保存到sqlserver数据库的工作单元“_uow”的服务。代码如下:

//***************************
//_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;
    }

“GouvernoratsRegion”是一个observablecollection,绑定到我编辑的数据网格,以添加或删除BCTgouvernorat Rows到该区域

  public void ModifyRegion(Region r, List<BctGouvernorat> _ToUnlik, List<BctGouvernorat> _ToLink)
    {
        _regionRepository.Modify(r, _ToUnlik, _ToLink);
    }

0 个答案:

没有答案