在此注释之后,如何执行一个ServiceStack OrmLite查询,该查询将两个或多个表连接在一起并从每个表中返回一些列?
以OrmLiteDoes_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);
上面没有像我期望的那样返回包含名字,姓氏和名字的匿名类型的列表。它仍然返回DeptEmployee
对象列表(但仅填充FirstName和LastName)。
在OrmLite中要注意的重要事项是查询的构造和执行方式与结果的映射方式无关。查询是原始的自定义SQL还是类型化的SQL表达式都无关紧要,OrmLite仅查看返回锻炼的数据集应如何映射结果。
因此,在使用Select<T>(SqlExpression<T>)
API时,OrmLite将始终尝试将结果映射到主要的SqlExpression Type中db.From<DeptEmployee>()
,这不是您想要的类型,因为您选择的自定义列与DeptEmployee
POCO的形状不匹配。
有几种不同的方式来读取自定义架构,它们都可以在同一个查询中运行(因为它独立于您选择的映射结果的方式):
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
},
]
主要的好处是您可以在中获得对自定义结果的Typed访问List<Custom>
。
如果您不想创建自定义类型,则可以选择OrmLite的动态结果API,例如:
如果您很高兴知道不同字段的位置,则可以选择一个List<object>
,它将按照选定字段的顺序返回选定的字段,例如:
db.Select<List<object>>(q).PrintDump();
印刷:
[
[
First 1,
Last 1,
Dept 1
],
]
否则,如果您还希望返回名称,则可以选择一个字符串对象字典,例如:
db.Select<Dictionary<string,object>>(q).PrintDump();
该命令的打印结果类似于“自定义POCO”,但名称和相应的值保留在一个松散类型的对象Dictionary中:
[
{
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的便捷数据访问API,使您可以在中选择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仅查看其映射到您希望返回结果的方式的结果集。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句