从 DataContext.ExecuteQuery() 中检索关系表作为 IEnumera

本文关键字:关系 检索 IEnumera ExecuteQuery DataContext customobject | 更新日期: 2023-09-27 18:36:55

首先读取:这是应用程序的一部分,它不控制它正在访问的数据库,因此实体框架是不可能的。这是一个非基于Web的工具,它将现有数据拉入内存,但数据库已经建立并且不受我们控制。

我有一个类,它表示要从多个表中检索的数据分组(ClassA)

public class ClassA
{
   public int ID;
   public string Detail;
   public List<string> Objects
}

表格如下所示:

表1

THISID(int)  | SOMETHING1(nvarchar)| SOMETHING2(nvarchar) | OTHERID(int)
1            | foo1                | bar1                 | 99
2            | foo2                | bar2                 | 98

表2

TABLE2ID(int) | OTHERID(int) | SOMETHING3(nvarchar)
100           | 99           | somethingA
101           | 99           | somethingB
102           | 99           | somethingC
103           | 98           | somethingA
104           | 98           | something D

我正在使用这样的数据上下文

string connectionString = (user passed in connection string)
string query = @"SELECT t1.THISID AS ID, t1.SOMETHING1 AS Detail, t2.SOMETHING3 AS Objects
                 FROM Table1 AS t1
                 JOIN Table2 AS t2
                 ON t1.OTHERID = t2.OTHERID";
using(DataContext dc = new DataContext(connectionString))
{
   List<ClassA> aClasses = dc.ExecuteQuery<ClassA>(query);
}

这显然是行不通的,但我不确定是否有办法让 DataContext 或 LINQtoSQL 将查询返回的外部值视为列表(或集合或可枚举)。我知道当您像典型的ORM一样使用它时,实体框架会为您执行此操作,但是在这里我们将结果集映射到对象中,我不确定是否有一种机制可以将联接数据视为结果映射对象中的列表。

关于如何在一次访问数据库时执行此操作的任何想法?或者是否有必要从 Table1 获取第一部分并实例化对象,然后迭代它们并填写其列表并额外访问 Table2?

从 DataContext.ExecuteQuery<customobject>() 中检索关系表作为 IEnumera

我很想使用实体框架。我知道你特别说你不能,但听起来你的推理只是你不控制数据库,这只是意味着你不能先使用代码。但无论如何,这并不重要。

您可以在一次访问数据库的行程中完成此操作,但是(当然)需要提取更多的数据。

无论如何,您都必须添加一个类。

class FlatRow
{
    public int Id { get; set; }
    public string Something1 { get; set; }
    public string Something3 { get; set; }
}
string connectionString = (user passed in connection string)
string query = @"SELECT t1.THISID AS ID, t1.SOMETHING1 AS Detail, t2.SOMETHING3 AS Objects
                 FROM Table1 AS t1
                 JOIN Table2 AS t2
                 ON t1.OTHERID = t2.OTHERID";
using(DataContext dc = new DataContext(connectionString))
{
    List<FlatRow> flat = dc.ExecuteQuery<FlatRow>(query);
    var aClasses = flat
                       .GroupBy(c => new { c.Id, c.Something1 })
                       .Select(c => new ClassA
                                    {
                                        ID = c.Key.Id,
                                        Detail = c.Key.Something1,
                                        Objects = c.Select(x => x.Something3).ToList()
                                    })
                       .ToList();
}

基本上,将其拉平,然后将其分组到内存中。这就是 EF 会做的,它只会为你做。但这还不错,如果这是你需要的。

不过,我很想对单独拉入每个表进行性能测试,然后将它们合并到内存中。您将切换到使用 GroupJoin ,并且您需要一个额外的逻辑点,但这样您就不会为具有多个Something3的实体冗余地拉取所有Something1数据。