简体   繁体   English

从DataContext.ExecuteQuery以IEnumerable检索关系表 <customobject> ()

[英]Retrieving relational tables as IEnumerable from DataContext.ExecuteQuery<customobject>()

Read first: This is part of an application that does not control the database it is accessing so Entity Framework is out of the question. 首先阅读:这是应用程序的一部分,该应用程序不控制正在访问的数据库,因此Entity Framework毫无疑问。 This is a non web based tool that is pulling existing data into memory, but the database is already made and not controlled by us. 这是一个非基于Web的工具,它将现有数据提取到内存中,但是数据库已经建立,不受我们的控制。

I have a class that represents a grouping of data that I want to retrieve from multiple tables (ClassA) 我有一个类,代表要从多个表中检索的一组数据(ClassA)

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

The tables look something like this: 这些表如下所示:

Table1 表格1

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

Table 2 表2

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

I am using a datacontext like this 我正在使用这样的数据上下文

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);
}

This is obviously not working, but I'm not sure if there is a way to get DataContext or LINQtoSQL to treat the foreign values returned from the query like a list (or collection or enumerable). 显然这是行不通的,但是我不确定是否有办法让DataContext或LINQtoSQL将查询返回的外部值当作列表(或集合或可枚举)来对待。 I know Entity Framework does this for you when you use it like a typical ORM, but here we are mapping a result set into an object and I'm not sure if there is a mechanism to have joined data be treated as a list in the resulting mapped object. 我知道Entity Framework像典型的ORM一样为您使用时,但是在这里我们将结果集映射到对象中,并且我不确定是否有一种机制可以将连接数据视为列表中的列表。生成的映射对象。

Any ideas on how to do this in one trip to the database? 关于如何一次访问数据库的任何想法? Or is it necessary to get first part from Table1 and instantiate objects, then iterate over them and fill in their Lists with an additional trip to Table2? 还是有必要从Table1中获取第一部分并实例化对象,然后遍历它们并通过一次额外的Table2行程来填充它们的List?

I'd be tempted to use Entity Framework. 我很想使用实体框架。 I know you specifically said you couldn't, but it sounds like your reasoning is only that you don't control the database, which just means you can't use code first. 我知道您专门说过您不能,但是听起来您的理由仅仅是您不控制数据库,这意味着您不能先使用代码。 But in any event, it doesn't really matter. 但是无论如何,这并不重要。

You could do it in one trip to the database, but it'll (of course) require pulling back significantly more data. 您可以在一次访问数据库的过程中完成此操作,但是(当然)需要撤回更多数据。

In any event, you'll have to add a class. 无论如何,您都必须添加一个类。

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();
}

Basically, pull it in flat, then group it in-memory. 基本上,将其拉平,然后在内存中分组。 This is what EF would do, it would just do it for you. 这就是EF会做的,只会为您做。 But this isn't so bad, if it's what you need. 但是,如果您需要的话,还算不错。

I'd be tempted to perf-test pulling each table in individually, though, then merging them in-memory. 我很想对每个表进行性能测试,然后将它们合并到内存中。 You'll switch to use a GroupJoin , and you'll need one spot of extra logic, but then you won't be pulling all the Something1 data redundantly for entities with multiple Something3 s. 您将切换为使用GroupJoin ,并且需要一点额外的逻辑,但是对于具有多个Something3的实体,您将不会冗余地提取所有Something1数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM