gpt4 book ai didi

ormlite-servicestack - OrmLite 查询从 2 个连接表中的每一个中选择一些列

转载 作者:行者123 更新时间:2023-12-04 18:03:34 30 4
gpt4 key购买 nike

this comment ,如何执行 ServiceStack OrmLite 查询来连接两个或多个表并从每个表中返回一些列?

使用 OrmLite Does_only_populate_Select_fields_wildcard以单元测试为例,我想做这样的事情:

public class DeptEmployee
{
[PrimaryKey]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[References(typeof(Department2))]
public int DepartmentId { get; set; }

[Reference]
public Department2 Department { get; set; }
}

public class Department2
{
[PrimaryKey]
public int Id { get; set; }
public string Name { get; set; }
}

var q = db.From<DeptEmployee>()
.Join<Department2>()
.Select<DeptEmployee, Department2>((de, d2) => new[] { de.FirstName, de.LastName, d2.Name });
var results = db.Select(q);

如我所料,上面没有返回包含 FirstName、LastName 和 Name 的匿名类型列表。它仍然返回一个列表 DeptEmployee对象(但只填充了 FirstName 和 LastName)。

最佳答案

OrmLite 中需要注意的一个重要事项是查询的构造和执行方式与结果的映射方式无关。无论查询是原始自定义 SQL 还是类型化 SQL 表达式都没有关系,OrmLite 只查看返回的数据集来计算结果应该如何映射。

所以当使用 Select<T>(SqlExpression<T>) API,OrmLite 将始终尝试将结果映射到 db.From<DeptEmployee>() 中的主要 SqlExpression 类型。这不是您想要的,因为您选择的自定义列与 DeptEmployee 的形状不匹配波科。

有几种不同的方法可以读取自定义架构,它们都适用于相同的查询(因为它与您选择映射结果的方式无关):

var q = db.From<DeptEmployee>()
.Join<Department2>()
.Select<DeptEmployee, Department2>(
(de, d2) => new { de.FirstName, de.LastName, d2.Name });

我们的建议,尤其是。对于像 OrmLite 这样的类型化代码优先 ORM 是创建一个类型化自定义 POCO 并选择它,例如:
class Custom
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Name { get; set; }
}

db.Select<Custom>(q).PrintDump();

这将打印出一个不错的:
[
{
FirstName: First 1,
LastName: Last 1,
Name: Dept 1
},
]

主要好处是您可以在 List<Custom> 中对自定义结果进行类型化访问。 .

如果您不想创建自定义类型,您可以选择 OrmLite 的 Dynamic Result APIs ,例如:

如果您很高兴知道不同字段的位置,您可以选择 List<object>这将按照它们被选择的顺序返回选定的字段,例如:
db.Select<List<object>>(q).PrintDump();

打印:
[
[
First 1,
Last 1,
Dept 1
],
]

否则,如果您还想要返回名称,您可以选择一个字符串对象字典,例如:
db.Select<Dictionary<string,object>>(q).PrintDump();

其打印结果类似于自定义 POCO,但名称和相应的值保存在一个松散类型的对象字典中:
[
{
FirstName: First 1,
LastName: Last 1,
Name: Dept 1
},
]

如果您只选择 2 列,例如:
var q = db.From<DeptEmployee>()
.Join<Department2>()
.Select<DeptEmployee, Department2>(
(de, d2) => new { de.LastName, d2.Name });

您可以使用 OrmLite 的 convenient data access APIs这将让您选择 2 列到 Dictionary<string,string> ,例如:
db.Dictionary<string,string>(q).PrintDump();

哪个打印:
{
Last 1: Dept 1,
Last 2: Dept 2,
Last 3: Dept 3
}

请注意,这与上面的字符串对象字典非常不同,因为它在单个 Dictionary<string,string> 中返回结果。 所有行 而不是 List<Dictionary<string,object>> ,其中有一个字典 每行 .

同样,如果您只选择 1 个字段,例如:
var q = db.From<DeptEmployee>()
.Join<Department2>()
.Select(x => x.LastName);

然后您可以在 List<string> 中选择单个结果列,例如:
db.Column<string>(q).PrintDump();

哪个打印:
[
Last 1,
Last 2,
Last 3
]

如果你想要不同的结果,你可以在 HashSet<string> 中返回它们。和:
db.ColumnDistinct<string>(q).PrintDump();

回到最初的重点,查询的构造方式无关紧要(它只控制生成的 SQL),OrmLite 只看返回的结果集 映射结果,它试图 映射到目标 API 您已指定要将结果映射到其中,因此执行自定义 SQL:
db.Column<string>("SELECT LastName FROM DeptEmployee").PrintDump();

或者,如果您执行了存储过程:
db.Column<string>("EXEC GetLastNamesFromDeptEmployees").PrintDump();

如果您使用类型化的 SQL 表达式,则以完全相同的方式映射,即 OrmLite 只查看它映射到您希望返回结果的方式的结果集。

关于ormlite-servicestack - OrmLite 查询从 2 个连接表中的每一个中选择一些列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37442401/

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