编辑实体

时间:2016-02-26 13:58:50

标签: c# entity-framework entity-framework-6

抱歉我的英语不好。 我有数据库的EF 6 codefirst模型。 3个模型通常是静态的,在程序启动时加载(使用最后一个表的外键)。 最后一个模型是动态的 - 数据也被加载,存储在c#集合中,但是用户可以添加,编辑行并保存添加/编辑到DB。 对于3个第一个模型,我有 selecteditem 绑定的复选框。 用户可以编辑最后一个表模型实体,从复选框中选择项目并保存到DB。 这是一个简单而又标准的解决方案。

没有垃圾字段的部分模型(从上表中引用)。

    [Table("Users")]
public partial class User
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ClientId { get; set; }
    [StringLength(160)]
    public string ClientName { get; set; }
    public virtual ICollection<Repair> Repairs { get; set; }
    public User()
    {
        Repairs = new List<Repair>();
    }
}
  [Table("RepairStatuses")]
public partial class RepairStatus
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    [StringLength(10)]
    public string Status { get; set; }
    public virtual ICollection<Repair> Repairs { get; set; }
    public RepairStatus()
    {
        Repairs = new List<Repair>();
    }
}
    [Table("CurrentStatuses")]
public partial class CurrentStatus
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int StatusId { get; set; }
    [StringLength(10)]
    public string Status { get; set; }
    public virtual ICollection<Repair> Repairs { get; set; }
    public CurrentStatus()
    {
        Repairs = new List<Repair>();
    }
}

主要的可编辑表格模型(部分太垃圾字段)。

    [Table("Repairs")]
public partial class Repair
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    [Column(TypeName = "date")]
    public DateTime Date { get; set; }
    [StringLength(255)]
    public string HardwareInfo { get; set; }
    public virtual User User { get; set; }
    public virtual RepairStatus RepairStatus { get; set; }
    public virtual CurrentStatus CurrentStatus { get; set; }
}

在我的 AddEntity 方法中全部工作(将未更改的项目从组合框附加到DbContext,添加新行,保存更改)。 急切加载。

  using (ServiceDBContext cntx = new ServiceDBContext())
       {
          cntx.Users.Attach(SelectedRepair.User);
          cntx.CurrentStatuses.Attach(SelectedRepair.CurrentStatus);
          cntx.RepairStatuses.Attach(SelectedRepair.RepairStatus);
          cntx.Entry(SelectedRepair.RepairStatus).State = EntityState.Modified;
          cntx.Entry(SelectedRepair.CurrentStatus).State = EntityState.Modified;
          cntx.Entry(SelectedRepair.User).State = EntityState.Modified;
          cntx.Repairs.Attach(SelectedRepair);
          cntx.Entry(SelectedRepair).State = EntityState.Added;
   ...
          cntx.SaveChanges();
   ...

但是使用 EditEntity 方法我有奇怪的行为(对不起愚蠢的代码......)

   using (ServiceDBContext wrk = new ServiceDBContext())
      {
       var tmp = (((((wrk.Repairs.Where(x => x.Id ==SelectedRepair.Id)).Include(y => y.CurrentStatus)).Include(y => y.RepairStatus)).Include(y => y.Engineer)).Include(y => y.User)).FirstOrDefault();
   if (tmp.User.ClientId != SelectedRepair.User.ClientId)
       {
          tmp.User = SelectedRepair.User;
          wrk.Users.Attach(tmp.User);
          wrk.Entry(tmp.User).State = EntityState.Modified;
       }
    if (tmp.RepairStatus.Id != SelectedRepair.RepairStatus.Id)
       {
          tmp.RepairStatus = SelectedRepair.RepairStatus;
          wrk.RepairStatuses.Attach(tmp.RepairStatus);
          wrk.Entry(tmp.RepairStatus).State = EntityState.Modified;
       }
    if (tmp.CurrentStatus.StatusId != SelectedRepair.CurrentStatus.StatusId)
       {
          tmp.CurrentStatus = SelectedRepair.CurrentStatus;
          wrk.CurrentStatuses.Attach(tmp.CurrentStatus);
          wrk.Entry(tmp.CurrentStatus).State = EntityState.Modified;
       }
     ...
     wrk.Entry(tmp).State = EntityState.Modified;
     wrk.SaveChanges();
     }

例如: CurrentStatuses 表有2个实体(&#34; 1.OK&#34;,&#34; 2.Bad&#34;)。 然后用户第一次更改所选行CurrentStatus外键中的 Repair 表(例如,id = 1到id = 2的外键)都可以。 在VS调试器中,我可以看到......

UPDATE [dbo].[CurrentStatuses] SET [Status] = @0 WHERE ([StatusId] = @1)
UPDATE [dbo].[Repairs] SET ... WHERE (([Id] = @12) AND ([CurrentStatus_StatusId] = @13))

如果用户想要第二次将此实体从id = 2更改为id = 1 (反向),则抛出错误&#34;保存不公开外键属性的实体时发生错误为了他们的关系...&#34;

在调试器中,我们可以通过&#34; Reader(INSERT)&#34;看到一些魔力。尝试所有数据库相关表o_O并尝试插入修复表的dublicate条目(已被选中进行编辑)。

一个INSERT示例(Repair,RepairStatus和User也有这样的INSERTS):

DECLARE @0 AS SQL_VARIANT;
SET @0 = NULL;
INSERT [dbo].[CurrentStatuses]([Status])
VALUES (@0)
SELECT [StatusId]
FROM [dbo].[CurrentStatuses]
WHERE @@ROWCOUNT > 0 AND [StatusId] = scope_identity()

程序重启后,我们可以正常将CurrentStatus外键从id = 2更改为id = 1 (但也只有1次)。 有人可以帮我解决这个问题吗? 谢谢!

0 个答案:

没有答案