【问题标题】:EF Removing from junction table connecting 3 tablesEF 从连接 3 个表的联结表中移除
【发布时间】:2017-03-14 17:53:17
【问题描述】:

我目前正在尝试实现连接 3 个表的联结表。我坚持从这张桌子上移除物品。

连接表由表的键和相关实体的导航属性组成。 (我对此进行了简化,在完整代码中它具有支持字段的实现)

[Table("SeasonHasBroadcast")]
public partial class SeasonHasBroadcastModel : BaseModel
{
    [Key]
    [Column(Order = 0)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int SeasonShow {get; set;}

    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int SeasonNumber {get; set;}

    [Key]
    [Column(Order = 2)]
    [StringLength(45)]
    public string AirtimeDay {get; set;}

    [Key]
    [Column(Order = 3)]
    public TimeSpan AirtimeTime {get; set;}     

    [Key]
    [Column(Order = 4)]
    [StringLength(45)]
    public string NetworkName {get; set;}

    public virtual AirtimeModel AirtimeLink {get; set;}

    public virtual NetworkModel NetworkLink {get; set;}

    public virtual SeasonModel SeasonLink {get; set;}
}

已连接的表具有public virtual ICollection<SeasonHasBroadcastModel> SeasonHasBroadcasts { get; set; }

当我向此关系添加新实体时,我只是向此表添加新实体。问题是,当我尝试删除实体时。

我尝试使用SeasonViewModel.Season.SeasonHasBroadcasts.Remove(selected); 删除。这样我就可以从其他仅连接 2 个表的联结表中删除。这些表只是没有单独的表,并且仅通过集合存在。其他尝试是通过导航属性,我从每个集合中删除了selected 实体。

这两个都给我这个错误:

“SeasonShow”属性是对象关键信息的一部分,不能修改。

当我调试并查看 DBContext 时,它会在节目、通话时间和网络实体上显示此错误,但不会在交汇点上显示此错误。

如何从这样的表中删除?

编辑

public class BaseModel : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

数据库上下文:

modelBuilder.Entity<AirtimeModel>()
    .HasMany(e => e.SeasonHasBroadcasts)
    .WithRequired(e => e.AirtimeLink)
    .HasForeignKey(e => new { e.AirtimeDay, e.AirtimeTime })
    .WillCascadeOnDelete(false);

modelBuilder.Entity<NetworkModel>()
    .HasMany(e => e.SeasonHasBroadcasts)
    .WithRequired(e => e.NetworkLink)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<SeasonModel>()
    .HasMany(e => e.SeasonHasBroadcasts)
    .WithRequired(e => e.SeasonLink)
    .HasForeignKey(e => new { e.SeasonShow, e.SeasonNumber })
    .WillCascadeOnDelete(false);

modelBuilder.Entity<SeasonHasBroadcastModel>()
    .Property(e => e.AirtimeDay)
    .IsUnicode(false);

modelBuilder.Entity<SeasonHasBroadcastModel>()
    .Property(e => e.NetworkName)
    .IsUnicode(false);

编辑 2 删除广播的命令 公共覆盖无效执行(对象参数) { var parrentViewModel = (SeasonViewModel) ParrentViewModel; var selected = parrentViewModel.SelectedBroadcast;

    if (selected == null) return;

    if (parrentViewModel.Season.SeasonHasBroadcasts.Contains(selected))
    {
        //selected.SeasonLink.SeasonHasBroadcasts.Remove(selected);
        //selected.AirtimeLink.SeasonHasBroadcasts.Remove(selected);
        //selected.NetworkLink.SeasonHasBroadcasts.Remove(selected);

        parrentViewModel.BroadcastsViewModel.Service.DeleteData(selected);

        //parrentViewModel.Service.Context.SeasonHasBroadcasts.Remove(selected);
        //parrentViewModel.Season.SeasonHasBroadcasts.Remove(selected);

    }

    parrentViewModel.SelectedBroadcast = null;
}

添加广播命令:

public override void Execute(object parameter)
{
    var parrentViewModel = (SeasonViewModel)ParrentViewModel;

    parrentViewModel.NewBroadcast.SeasonLink = parrentViewModel.Season;

    if (!parrentViewModel.Season.SeasonHasBroadcasts.Contains(parrentViewModel.NewBroadcast))
    {
        parrentViewModel.Season.SeasonHasBroadcasts.Add(parrentViewModel.NewBroadcast);
    }

    parrentViewModel.NewBroadcast = new SeasonHasBroadcastModel();
}

Service for:(这是今天的尝试,还是没有解决,同样的错误)

public override void DeleteData(SeasonHasBroadcastModel toDelete)
{
    if (toDelete.AirtimeLink != null && Context.Entry(toDelete.AirtimeLink).State == EntityState.Detached)
        Context.Airtimes.Attach(toDelete.AirtimeLink);

    if (toDelete.NetworkLink != null && Context.Entry(toDelete.NetworkLink).State == EntityState.Detached)
        Context.Networks.Attach(toDelete.NetworkLink);

    if (toDelete.SeasonLink != null && Context.Entry(toDelete.SeasonLink).State == EntityState.Detached)
        Context.Seasons.Attach(toDelete.SeasonLink);

    base.DeleteData(toDelete);
}

Base.DeleteData:

public virtual void DeleteData(TModel toDelete)
{
    _context.Set<TModel>().Remove(toDelete);
}

【问题讨论】:

  • 您使用的是哪个版本的实体框架?另外抛出的异常类型是什么?此外,您还提到了系统中没有显示代码的许多其他对象。我觉得很难全面了解您的代码中发生了什么。
  • 它抛出 InvalistOperationException,消息在 OP 中。 EF 是 6.1.3 版
  • 您是否在 DbContext 类上设置了任何 FluentApi 配置?很高兴看到这一点。您的表的相关部分也连接到您的连接表SeasonHasBroadcastModel 以及您的BaseModel
  • 现在将StringTimeSpan 等类型标记为表主键的一部分是否有效?
  • @我知道吗,我不想修改,我想删除实体,但我不能。该表只是添加/删除实体,没有任何修改。

标签: c# entity-framework


【解决方案1】:

所以,在咨询了我大学的教授之后,我们得出“最简单”的解决方案可能是 SQL 服务器上的存储过程。它不是最好的解决方案,但它的工作原理。仍然想知道,如何在没有存储过程的情况下做到这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-24
    • 1970-01-01
    • 2016-12-18
    • 1970-01-01
    相关资源
    最近更新 更多