Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 添加到多对多关系表会在db中生成重复的值_C#_Asp.net Mvc_Database_Entity Framework - Fatal编程技术网

C# 添加到多对多关系表会在db中生成重复的值

C# 添加到多对多关系表会在db中生成重复的值,c#,asp.net-mvc,database,entity-framework,C#,Asp.net Mvc,Database,Entity Framework,我有三个表zRequest、zFacility和一个表,用于两个表之间的多对多关系,每个表的id都是。我的目标是添加一个包含许多设施的请求。但是,每当我添加带有某些设施的新请求时,它都会将所选设施添加到zFacility以及关系表中 这是控制器中的相关代码: foreach (var facility in Facilities) { var facName = facility.Replace(".", " "); var facQry = from fac in db.zFa

我有三个表zRequest、zFacility和一个表,用于两个表之间的多对多关系,每个表的id都是。我的目标是添加一个包含许多设施的请求。但是,每当我添加带有某些设施的新请求时,它都会将所选设施添加到zFacility以及关系表中

这是控制器中的相关代码:

foreach (var facility in Facilities)
{
    var facName = facility.Replace(".", " ");
    var facQry = from fac in db.zFacilities where fac.FacilityName == facName select fac;
    var facList = facQry.ToList();
    var item = new zFacility();
    item.FacilityId = facList.FirstOrDefault().FacilityId;
    item.FacilityName = facList.FirstOrDefault().FacilityName;
    //db.zFacility.Attach(item);
    zrequest.zFacility.Add(item);
}
zrequestRepository.InsertOrUpdate(zrequest);
zrequestRepository.Save();
我做了一些研究,并尝试通过注释行将每个工具连接到数据库,但这给了我另一个错误,因为相同类型的另一个实体已经具有相同的主键值

这是zRequestRepository中的代码:

public void InsertOrUpdate(zRequest zrequest)
    {
        if (zrequest.RequestId == default(int)) {
            // New entity
            context.zRequests.Add(zrequest);
        } else {
            // Existing entity
            context.Entry(zrequest).State = System.Data.Entity.EntityState.Modified;
        }
    }
我能做些什么来解决这个问题?如果我需要提供更多信息,请告诉我

编辑,按要求提供相关模型。 zFacility:

using System;
using System.Collections.Generic;

public partial class zFacility
{
    public zFacility()
    {
        this.zRequest = new HashSet<zRequest>();
        this.zRoom = new HashSet<zRoom>();
    }

    public short FacilityId { get; set; }
    public string FacilityName { get; set; }

    public virtual ICollection<zRequest> zRequest { get; set; }
    public virtual ICollection<zRoom> zRoom { get; set; }
}
使用系统;
使用System.Collections.Generic;
公共部分类zFacility
{
公共设施
{
this.zRequest=new HashSet();
this.zRoom=new HashSet();
}
公共短设施ID{get;set;}
公共字符串设施名称{get;set;}
公共虚拟ICollection zRequest{get;set;}
公共虚拟ICollection zRoom{get;set;}
}
zRequest:

using System;
using System.Collections.Generic;

public partial class zRequest
{
    public zRequest()
    {
        this.zFacility = new HashSet<zFacility>();
        this.zRoom = new HashSet<zRoom>();
    }

    public int RequestId { get; set; }
    public string ModCode { get; set; }
    public short StatusId { get; set; }
    public int WeekId { get; set; }
    public short DayId { get; set; }
    public short PeriodId { get; set; }
    public short SessionLength { get; set; }
    public short Semester { get; set; }
    public short RoundNo { get; set; }
    public string SpecialRequirement { get; set; }
    public short UserId { get; set; }

    public virtual zDay zDay { get; set; }
    public virtual zPeriod zPeriod { get; set; }
    public virtual zRound zRound { get; set; }
    public virtual zStatus zStatus { get; set; }
    public virtual zWeek zWeek { get; set; }
    public virtual ICollection<zFacility> zFacility { get; set; }
    public virtual ICollection<zRoom> zRoom { get; set; }
    public virtual zUser zUser { get; set; }
}
使用系统;
使用System.Collections.Generic;
公共部分类zRequest
{
公共要求
{
this.zFacility=new HashSet();
this.zRoom=new HashSet();
}
public int RequestId{get;set;}
公共字符串ModCode{get;set;}
公共短状态ID{get;set;}
public int WeekId{get;set;}
公共短DayId{get;set;}
公共短周期ID{get;set;}
公共短会话长度{get;set;}
公共短学期{get;set;}
公共短循环号{get;set;}
公共字符串特殊要求{get;set;}
公共短用户标识{get;set;}
公共虚拟zDay zDay{get;set;}
公共虚拟zPeriod zPeriod{get;set;}
公共虚拟zRound{get;set;}
公共虚拟zStatus zStatus{get;set;}
公共虚拟zWeek zWeek{get;set;}
公共虚拟ICollection zFacility{get;set;}
公共虚拟ICollection zRoom{get;set;}
公共虚拟zUser zUser{get;set;}
}

它们都是首先通过数据库生成的。

您需要做的是从数据库中选择ZFactorys对象,而不是为它们中的每一个创建新对象,因为这使EF认为您想要创建一个全新的记录

因此: 选择zFactories 将它们添加到zRequest.zFacility中(如果它们尚未存在)
保存

回答这个问题有点困难,因为代码中有一些漏洞。根据使用情况,我假设
Facilities
是一个可枚举的字符串,并且是从post数据中的选定项创建的

我不知道为什么要创建一个新的
zFacility
,而不是使用已经从数据库中提取的工具。按照您现在的方式,如果没有匹配工具,您还引入了空引用异常的可能性

无论如何,我会更改代码,您必须:

// This is so you can run a single minimal query to select
// all the facilities you'll be working with
var facNames = Facilities.Select(m => m.Replace(".", " "));
var facList = db.zFacilities.Where(m => facNames.Contains(m.FacilityName)).ToList();

// Now add all facilities not currently attached
facList.Where(m => !zrequest.zFacility.Contains(m)).ToList()
    .ForEach(m => zrequest.zFacility.Add(m));
您可能还需要删除已取消选择的项目。最简单的方法是反向执行最后一位代码:

zrequest.zFacility.Where(m => !facList.Contains(m)).ToList()
    .ForEach(m => zrequest.zFacility.Remove(m));
编辑

实际上,删除取消选择的项目的更简洁的方法是:

zrequest.zFacility.RemoveAll(m => !factList.Contains(m));

默认情况下,EF假定所选设施(zFacility)是新的,并将其插入数据库

为了避免这种情况,您需要将zFacility的状态更改为
Unchanged

像这样的

public void InsertOrUpdate(zRequest zrequest)
    {
        if (zrequest.RequestId == default(int)) {
        context.zFacility.Attach(zrequest); // state Unchanged for zFacility  
        // New entity
       context.zRequests.Add(zrequest);
            } else {
            // Existing entity
            context.Entry(zrequest).State = System.Data.Entity.EntityState.Modified;
        }
    }

你能发布你的模型吗?@Alundrathedreamwalker,这些模型已经添加到原始帖子中。你在foreach的设施(设施中的var设施)来自哪里?您确定它们来自同一对象上下文吗?Facility是一个字符串数组,包含所选设施的FacilityName。这是从视图中获得的。我不确定你所说的“同一对象上下文”是什么意思……我认为这一个对解决我遇到的问题帮助最大。我不得不稍微修改你的代码,因为
context.zRequests.Add()
只接受zFacility类型的对象,所以我循环了zrequest中的工具,并将它们一个接一个地连接起来。我计划使用此代码来改进我的方法并使其更有效,但我不完全理解。。。你能解释一下最后两行吗?