gpt4 book ai didi

c# - LINQ:从左联接填充对象

转载 作者:行者123 更新时间:2023-11-30 21:04:19 27 4
gpt4 key购买 nike

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

这是我的数据库查询:

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

这里是示例输出:

enter image description here

我有 3 个实体:

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

更新

这是我卡住的地方:

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

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

解决方案:

使用 AmyB 的回答,这就是填充我的对象的内容:

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

最佳答案

所以 - 如果我理解正确的话 - 你有一个你很满意的数据库查询,但你想要获取行-列形状的结果并将其投影到层次结构形状的结果中。


假设结果在 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;}
}

然后你会分组两次,并将每个顶级组变成一个 Type , 每个子级组都变成一个 Attribute每一行变成一个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();

关于c# - LINQ:从左联接填充对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12496809/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com