首页 > 解决方案 > 如何在 C# 查询中链接嵌套关系表中的数据

问题描述

我有一个模拟设计时 IList 静态数据结构,镜像将存储在生产数据库中的内容。该模型具有一对多的关系(读数包含许多测量),但也具有链接的多对一(测量属于 MeasurementType)。我需要返回一个读取的 IEnumerable,其中每个条目都包含其测量值的列表,而且每个测量值都需要 MeasurementType 对象以包含来自 MeasurementTypes 列表的相关对象。

模型类中的 Measurements 和 Type 属性不会保留在数据库中。

我可以看到如何将读数列表返回到我的应用程序,其中测量列表属性填充了测量列表中的匹配对象,但我正在努力寻找在每个测量中填充 Type 属性的最佳方法,以便使用来自相关对象的读数measureTypes 列表基于 id 属性,因此我还可以过滤掉 measementType 未设置为可见的测量对象。

下面的查询失败,因为 Type 属性为空,如何通过 Id 从measurementTypes 列表中加入 Type 对象,以便可以在查询中使用?还是有更好的方法来做到这一点,而不是在 foreach 循环中进行查询?

foreach (var reading in readings)
{
    reading.Measurements = measurements.Where(m => (m.ReadingId == reading.Id) && (m.Type.Visible)).ToList();
}

return readings;

(为清楚起见,简化了类)

public class Reading
{
    public DateTime DateTime { get; set; }
    public int Id { get; set; }
    public IList<Measurement>? Measurements { get; set; }
}

public class Measurement
{
    public int MeasurementTypeId { get; set; }
    public int ReadingId { get; set; }
    public MeasurementType? Type { get; set; }
    public int Value { get; set; }
}  

public class MeasurementType
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public bool Visible { get; set; }
}

measurementTypes = new List<MeasurementType>()
{
    new MeasurementType { Id = 1, Name = "A name", Visible = true }
    ...
};

measurements = new List<Measurement>()
{
    new Measurement { ReadingId = 1, MeasurementTypeId = 1, Value = 100 }
    ...
};

readings = new List<Reading>()
{
    new Reading { Id = 1, DateTime = DateTime.Today.AddDays(-366) }
...
};

标签: c#linqnon-relational-database

解决方案


Measurement 和 MeasurementType 之间的关系必须手动建立。您需要从 MeasurementType 列表中的相关值之一分配给Type字段。您可以尝试的一种方法如下:

在Measurement中引入构造函数

    public class Measurement
    {
        // for mock tests
        public Measurement(int measurementTypeId, int readingId, int value, IEnumerable<MeasurementType> measurementTypes)
        {
            MeasurementTypeId = measurementTypeId;
            ReadingId = readingId;
            Type = measurementTypes.Single(mt=>mt.Id==measurementTypeId),
            Value = value;
        }

        public int MeasurementTypeId { get; set; }
        public int ReadingId { get; set; }
        public MeasurementType Type { get; set; }
        public int Value { get; set; }
    }

然后在建立测量列表时:

measurementTypes = new List<MeasurementType>()
{
    new MeasurementType { Id = 1, Name = "A name", Visible = true }
...
};

measurements = new List<Measurement>()
{
    new Measurement (1,  1,  100, measurementTypes) 
 ....
};

推荐阅读