C# EF Core过滤出多对多关系中的重复实体

C# EF Core过滤出多对多关系中的重复实体,c#,many-to-many,ef-core-5.0,C#,Many To Many,Ef Core 5.0,我遇到了一个问题,EntityFrameworkCore5忽略了多对多关系中的重复条目。我的“设备”可以有任意数量的“传感器”(包括多个相同的传感器)。如果我尝试向设备添加2个相同的传感器,EF仅插入1。如果我将两个相同的传感器直接添加到DeviceSensorRelation表中,EF在Device.Sensors列表中仅显示其中一个传感器 我运行了SQL Server Profiler来检查正在运行的查询,它确实返回了EF未显示的所有条目。这是EF Core的一个限制,还是我缺少一个配置或什

我遇到了一个问题,EntityFrameworkCore5忽略了多对多关系中的重复条目。我的“设备”可以有任意数量的“传感器”(包括多个相同的传感器)。如果我尝试向设备添加2个相同的传感器,EF仅插入1。如果我将两个相同的传感器直接添加到
DeviceSensorRelation
表中,EF在
Device.Sensors
列表中仅显示其中一个传感器

我运行了SQL Server Profiler来检查正在运行的查询,它确实返回了EF未显示的所有条目。这是EF Core的一个限制,还是我缺少一个配置或什么?(我假设它注意到复制的Sensor.Id作为主键,只是没有真正意义,因为它们之间有一个表)

我有以下表格结构:

CREATE TABLE [Hardware].[Device]
(
    [Id] [int] IDENTITY(1,1) NOT NULL, --PK
    [Name] [varchar](200) NOT NULL,
    [BuildDate] [date] NOT NULL
)

CREATE TABLE [Hardware].[Sensor]
(
    [Id] [int] IDENTITY(1,1) NOT NULL, --PK
    [Name] [varchar](200) NOT NULL,
    [Cost] [money] NOT NULL
)

CREATE TABLE [Hardware].[DeviceSensorRelation]
(
    [Id] [int] IDENTITY(1,1) NOT NULL, --PK
    [DeviceId] [int] NOT NULL, --FK to Device.Id table
    [SensorId] [int] NOT NULL --FK to Sensor.Id table
)
这些是EF核心实体:

public class Device
{
    public int Id { get; }
    public string Name { get; private set; }
    public DateTime BuildDate { get; private set; }

    private List<Sensor> sensors = new List<Sensor>();
    public IReadOnlyCollection<Sensor> Sensors => this.sensors;
}

public class Sensor
{
    public int Id { get; }
    public string Name { get; private set; }
    public decimal Cost { get; private set; }

    private List<Device> devices = new List<Device>();
    public IReadOnlyCollection<Device> Devices => this.devices;
}
公共类设备
{
公共int Id{get;}
公共字符串名称{get;private set;}
public DateTime BuildDate{get;private set;}
私有列表传感器=新列表();
公共IReadOnlyCollection Sensors=>this.Sensors;
}
公共类传感器
{
公共int Id{get;}
公共字符串名称{get;private set;}
公共十进制成本{get;私有集;}
私有列表设备=新列表();
公共IReadOnlyCollection设备=>this.Devices;
}
这是在设备实体配置中设置关系的代码:

builder.HasMany(x => x.Sensors)
       .WithMany(x => x.Devices)
       .UsingEntity(b =>
       {
           b.ToTable("DeviceSensorRelation", "Hardware");
           b.Property<int>("Id").UseIdentityColumn();
           b.Property<int>("DeviceId");
           b.Property<int>("SensorId");
           b.HasKey("Id");
       })
builder.HasMany(x=>x.Sensors)
.具有多个(x=>x个设备)
.UsingEntity(b=>
{
b、 ToTable(“设备传感器相关”、“硬件”);
b、 属性(“Id”)。UseIdentityColumn();
b、 财产(“设备ID”);
b、 财产(“传感器ID”);
b、 HasKey(“Id”);
})

我认为EF core的操作是正确的,请记住EF core是db上的一个抽象,即使有两条记录EF core只考虑“关系”。 连接表中的一条记录满足了说明两个实体是否相关所需的信息,而第二条记录没有提供有关“实体是否链接?”问题的更多信息

您想要存储和检索更多信息,您想要知道传感器与设备“相关”的次数。 在这种情况下,我建议使用多对多with payload关系,并在连接实体中添加一个额外的列来存储额外的信息,可以是任何内容(因此由您来填充此信息):在这种情况下,TypeOfDevice和TypeOfSensor之间的关系存在的次数。我引用了您的实体名称,以关注这样一个事实:简单的多对多更适合于将具有唯一串行id(unique)的“具体”设备链接到具有唯一串行id的“具体”传感器


如果在获取您试图删除链接的实体后,这两条记录是否都被删除了,那么看看会发生什么是很有趣的?但仔细想想,我认为在deviceId和sensorId列的联接表上进行pk是一个好主意(因为多对多的性质),所以这种情况永远不会发生。

您的查询是什么?你们有并没有尝试过将列表更改为集合?EF Core肯定存在一些问题。请在他们的GitHub问题跟踪器@zolfaghari中检查/报告相同的结果,使用集合而不是列表(正在填充但删除重复项)。你所说的查询是指sql还是linq调用?我想知道多次添加相同的传感器记录是否有意义。实际上,您可能不会连接同一个传感器对象两次,而是连接同一类型的第二个传感器对象。如果是这样,这两个传感器对象也需要在数据库中进行区分。每个传感器对象都应该有自己的记录。如果不是,如果一个物理传感器实际连接到一个设备两次,那么这应该是连接记录
设备传感器相关
,类似于
连接数