LINQ:填充物体左连接 [英] LINQ: Fill objects from left join

查看:146
本文介绍了LINQ:填充物体左连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的LINQ。我如何使用LINQ从左连接数据库查询(PostGIS的)加载我的对象



这是我的数据库查询:



<预类=郎-SQL prettyprint-覆盖> SELECT
dt.id,
dt.type,
dta.id为AttId,
dta.label,
dtav.id为AttValueId,
dtav.value

从公众。数据类型DT,
公众。dataTypeAttributes DTA
LEFT JOIN公众。dataTypeAttributeValues​​dtav
关于dta.id =dataTypeAttributeId
其中dt.id = DTA。dataTypeId
ORDER BY dt.type, dta.label,dtav.value

这是一个输出示例:





我有3个实体:



<预类=郎-C#prettyprint-覆盖> 公共类TypeData
{
公众诠释ID {搞定;组; }
公共字符串类型{搞定;组; }
公共TypeDataAttribute [] {属性获得;组; }

}
公共类TypeDataAttribute
{
公众诠释ID {搞定;组; }
公共字符串标签{搞定;组; }
公共TypeDataAttributeValue []值{搞定;组; }
}

公共类TypeDataAttributeValue
{
公众诠释ID {搞定;组; }
公共字符串值{获得;组; }
}



更新



这是我卡住:



<预类=郎-C#prettyprint-覆盖> ...
使用(NpgsqlDataReader读者= Command.ExecuteReader却())
{

如果(reader.HasRows)
{
IEnumerable的< TypeData> typeData = reader.Cast< System.Data.Common.DbDataRecord>()
.GroupJoin(//< - 困在这里
}
...



解决方案:



使用@DavidB的答案,这是充满了我对象:



<预类=郎-C#prettyprint-覆盖> 使用(NpgsqlDataReader读卡器= Command.ExecuteReader却())
$ { b
$ b如果(reader.HasRows)
{

组VAR = reader.Cast< System.Data.Common.DbDataRecord>()
.GroupBy(博士=>新建{ID =(INT)博士[ID],AttID =(INT)博士[AttId]})
.GroupBy(G => g.Key.ID); $从typeGroup b
$ b typeDataList =(
组中的
让typeRow = typeGroup.First()。首先()
选择新TypeData()
{
ID =(int)的typeRow [ID],
类型=(字符串)typeRow [型],
属性=

从attGroup在typeGroup
让attRow = attGroup.First()
选择新TypeDataAttribute()
{
ID =(int)的attRow [AttId],
标签=(字符串) attRow [标签],
PossibleValues​​ =
从行(
在attGroup
,其中!DBNull.Value.Equals(attRow [AttValueId])
选择新TypeDataAttributeValue(){ID =(int)的行[AttValueId],值=(字符串)行[价值]}
).ToArray()
}
).ToArray ()
}
);
}
}


解决方案

所以, - 如果我理解正确的 - 你有一个数据库查询,你是高兴,但你要采取行柱状结果,并投射到一个分层形的结果。



< HR>

假设结果是在列表<行>

 公共类行
{
公众诠释ID {获取;集;}
公共字符串类型{获取;集;}
公众诠释attid {获取;设置;}
公共字符串标签{获取;集;}
公众诠释? attvalueid {获取;设置;}
公共字符串值{获得;设置;}
}

那么你就组了两次,并把每个顶级组成键入,每个子级组到属性,每行插入(如果该行不为空值)。

 列表<行> QueryResult中= GetQueryResult(); 

//使我们的层次结构。
组VAR = QueryResult中
.GroupBy(行=>新建{row.id,row.attid})
.GroupBy(G => g.Key.id);

//现在塑造每个级别
名单,LT;类型>回答=
从typeGroup(
组中的
让typeRow = typeGroup.First()。首先()
选择新类型()
{
ID = typeRow.id,
型= ty​​peRow.type,
属性=

从attGroup在typeGroup
让attRow = attGroup.First()
选择新的属性()
{
ID = attRow.attid,
标签= attRow.label
值=
($ b $从b行中attRow
,其中row.attvalueid.HasValue //如果没有价值,那么我们得到一个空数组
选择新的值(){ID = row.attvalueid,值= row.value}
).ToArray( )
}
).ToArray()
}
).ToList();


I'm new to linq. How do I load my objects using LINQ from a left join database query (PostGIS).

This is my database query:

SELECT          
                dt.id, 
                dt.type, 
                dta.id as "AttId",
                dta.label,
                dtav.id as "AttValueId",
                dtav.value

FROM            public."dataTypes" dt, 
                public."dataTypeAttributes" dta
LEFT JOIN       public."dataTypeAttributeValues" dtav
ON              dta.id = "dataTypeAttributeId"        
WHERE           dt.id = dta."dataTypeId"
ORDER BY        dt.type, dta.label, dtav.value

And here is example output:

I have 3 entities:

public class TypeData
{
    public int ID { get; set; }
    public string Type { get; set; }
    public TypeDataAttribute[] Attributes { get; set; }

}
public class TypeDataAttribute
{
    public int ID { get; set; }
    public string Label { get; set; }
    public TypeDataAttributeValue[] Values { get; set; }
}

public class TypeDataAttributeValue
{
    public int ID { get; set; }
    public string Value { get; set; }
}

Update

Here is where I get stuck:

...
using (NpgsqlDataReader reader = command.ExecuteReader())
{

    if (reader.HasRows)
    {
        IEnumerable<TypeData> typeData = reader.Cast<System.Data.Common.DbDataRecord>()
            .GroupJoin( //<--stuck here.
    }
...

SOLUTION:

using @DavidB answer, this is what filled my objects:

using (NpgsqlDataReader reader = command.ExecuteReader())
{

    if (reader.HasRows)
    {

        var groups = reader.Cast<System.Data.Common.DbDataRecord>()
            .GroupBy(dr => new { ID = (int)dr["id"], AttID = (int)dr["AttId"] })
            .GroupBy(g => g.Key.ID);

        typeDataList = (
            from typeGroup in groups
            let typeRow = typeGroup.First().First()
            select new TypeData()
            {
                ID = (int) typeRow["id"],
                Type = (string) typeRow["type"],
                Attributes = 
                (
                    from attGroup in typeGroup
                    let attRow = attGroup.First()
                    select new TypeDataAttribute()
                    {
                        ID = (int)attRow["AttId"],
                        Label = (string)attRow["label"],
                        PossibleValues =
                        (
                            from row in attGroup
                            where !DBNull.Value.Equals(attRow["AttValueId"])
                            select new TypeDataAttributeValue() { ID = (int)row["AttValueId"], Value = (string)row["value"] }
                        ).ToArray()
                    }
                ).ToArray()
            }
        );
    }
}

解决方案

So - if I understand right - you have a database query that you are happy with, but you want to take the row-column shaped result and project it into a hierarchically shaped result.


Suppose the results are in a List<Row>

public class Row
{
  public int id {get;set;}
  public string type {get;set;}
  public int attid {get;set;}
  public string label {get;set;}
  public int? attvalueid {get;set;}
  public string value {get;set;}
}

Then you would group twice, and turn each top-level group into a Type, each child-level group into an Attribute and each row into a Value (if the row is not an empty value).

List<Row> queryResult = GetQueryResult();

//make our hierarchies.
var groups = queryResult
  .GroupBy(row => new {row.id, row.attid})
  .GroupBy(g => g.Key.id);

//now shape each level
List<Type> answer =
(
  from typeGroup in groups
  let typeRow = typeGroup.First().First()
  select new Type()
  {
    id = typeRow.id,
    type = typeRow.type,
    Attributes =
    (
      from attGroup in typeGroup
      let attRow = attGroup.First()
      select new Attribute()
      {
        id = attRow.attid,
        label = attRow.label
        Values =
        (
          from row in attRow
          where row.attvalueid.HasValue  //if no values, then we get an empty array
          select new Value() {id = row.attvalueid, value = row.value }
        ).ToArray()
      }
    ).ToArray()
  }
).ToList();

这篇关于LINQ:填充物体左连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆