[参考]或[忽略]?
我们有一个DTO - 员工 - 有许多(> 20)相关的DTO和DTO集合。 对于“返回的JSON大小”的原因,我们将这些关系标记为[忽略]。 然后由客户填充任何他们希望使用其他REST调用的相关DTO。
我们尝试了几件事来满足客户希望获得一些相关员工信息的愿望,但不是全部:
我们创建了一个新的DTO - EmployeeLite - 它具有使用“RelatedTableNameRelatedFieldName”方法定义的请求最多的字段,并使用QueryBase超载并且运行良好。
我们也尝试将一个属性添加到请求DTO - “参考” - 这是用户希望填充的相关DTO的逗号分隔列表。 然后,我们迭代响应并使用相关的DTO或列表填充每个员工。 迭代大型列表时,会出现性能问题。
我们想知道是否有建议的方法来处理我们想要做的事情?
感谢您的任何建议。
更新:
这是我们要求DTO的一部分:
[Route("/employees", "GET")]
public class FindEmployeesRequest : QueryDb<Employee> {
public int? ID { get; set; }
public int[] IDs { get; set; }
public string UserID { get; set; }
public string LastNameStartsWith { get; set; }
public DateTime[] DateOfBirthBetween { get; set; }
public DateTime[] HireDateBetween { get; set; }
public bool? IsActive { get; set; }
}
该服务没有代码(使用QueryDb自动生成),所以我添加了一些以尝试“合并”方法:
public object Get(FindEmployeesRequest request) {
var query = AutoQuery.CreateQuery(request, Request.GetRequestParams());
QueryResponse<Employee> response = AutoQuery.Execute(request, query);
if (response.Total > 0) {
List<Clerkship> clerkships = Db.Select<Clerkship>();
response.Results.Merge(clerkships);
}
return response;
}
这会失败,因为Could not find Child Reference for 'Clerkship' on Parent 'Employee'
因为在员工中我们有:
[Ignore]
public List<Clerkship> Clerkships { get; set; }
我们这样做是因为我们不希望每个请求都有“秘书”。 如果我将[Ignore]
更改为[Reference]
我不需要上述服务中的代码 - 列表会自动显示。 所以看起来.Merge
只适用于我们不想做的[Reference]
。
我不知道如何在AutoQuery服务中使用“自定义加载参考”方法。 而且,AFAIKT,“自定义字段”方法不能用于相关的DTO,只能用于基表中的字段。
更新2:
带有include[]
的LoadSelect
对我们来说工作得很好。 我们现在试图说明在查询字符串中使用?fields=
的情况,但客户端不请求相关DTO的ID字段:
public partial class Employee {
[PrimaryKey]
[AutoIncrement]
public int ID { get; set; }
.
.
.
[References(typeof(Department))]
public int DepartmentID { get; set; }
.
.
.
public class Department {
[PrimaryKey]
public int ID { get; set; }
public string Name { get; set; }
.
.
.
}
所以,请求
/employees?fields=id,departmentid
我们会得到该部门的答复。 但对于请求
/employees?fields=id
我们不会得到该部门的答复。
我们试图通过修改query.SelectExpression
并在执行Db.LoadSelect
之前在SELECT
添加, "Employee"."DepartmentID"
来为请求者“安静地修复”。 调试显示正在修改query.SelectExpression
,但根据SQL Profiler "Employee"."DepartmentID"
未被选中。
有什么我们应该做的,以获得"Employee"."DepartmentID"
添加到SELECT?
谢谢。
更新3:
Employee表有三种1:1关系 - EmployeeType,Department和Title:
public partial class Employee {
[PrimaryKey]
[AutoIncrement]
public int ID { get; set; }
[References(typeof(EmployeeType))]
public int EmployeeTypeID { get; set; }
[References(typeof(Department))]
public int DepartmentID { get; set; }
[References(typeof(Title))]
public int TitleID { get; set; }
.
.
.
}
public class EmployeeType {
[PrimaryKey]
public int ID { get; set; }
public string Name { get; set; }
}
public class Department {
[PrimaryKey]
public int ID { get; set; }
public string Name { get; set; }
[Reference]
public List<Title> Titles { get; set; }
}
public class Title {
[PrimaryKey]
public int ID { get; set; }
[References(typeof(Department))]
public int DepartmentID { get; set; }
public string Name { get; set; }
}
最新的4.0.55更新允许这样做:
/employees?fields=employeetype,department,title
我找回所有的Employee表字段加上三个相关的DTO-- 一个奇怪的事情 - Employee的ID字段填充了Employee的TitleID值(我想我们之前看到过这个?)。
这个请求修复了这个异常:
/employees?fields=id,employeetypeid,employeetype,departmentid,department,titleid,title
但我失去了所有其他员工领域。
这听起来像是“有你的蛋糕并且也吃了它”的要求,但是有没有办法让我可以得到所有员工领域和选择性相关的DTO? 就像是:
/employees?fields=*,employeetype,department,title
自动查询可定制字段
不确定这是否相关,但AutoQuery内置支持定制使用?fields=Field1,Field2
选项返回哪些字段。
合并断开的POCO结果
由于您尚未提供任何源代码,因此您不清楚您尝试实现的目标或现有解决方案效率低下的问题,但您不希望执行任何N+1
SELECT查询。 如果是,请查看如何将未连接的POCO结果合并到一起,这样可以根据使用OrmLite引用定义的关系合并单独查询的结果,例如下面的示例使用2个不同的查询与订单加入客户:
//Select Customers who've had orders with Quantities of 10 or more
List<Customer> customers = db.Select<Customer>(q =>
q.Join<Order>()
.Where<Order>(o => o.Qty >= 10)
.SelectDistinct());
//Select Orders with Quantities of 10 or more
List<Order> orders = db.Select<Order>(o => o.Qty >= 10);
customers.Merge(orders); // Merge disconnected Orders with their related Customers
自定义加载参考
当你调用OrmLite的Load*
API时,你可以选择控制哪些引用OrmLite应该加载,例如:
var customerWithAddress = db.LoadSingleById<Customer>(customer.Id,
include: new[] { "PrimaryAddress" });
在自动查询中使用自定义加载引用
您可以自定义自动查询请求, Db.LoadSelect
在您的自定义AutoQuery实现中不使用Db.Select
而不是Db.LoadSelect
返回任何引用,例如:
public object Get(FindEmployeesRequest request)
{
var q = AutoQuery.CreateQuery(request, Request);
var response = new QueryResponse<Employee>
{
Offset = q.Offset.GetValueOrDefault(0),
Results = Db.Select(q),
Total = (int)Db.Count(q),
};
return response;
}
同样,如果您只想选择加载1个或多个引用,则可以将LoadSelect更改为仅包含要包含的引用字段的include:
数组,例如:
public object Get(FindEmployeesRequest request)
{
var q = AutoQuery.CreateQuery(request, Request);
var response = new QueryResponse<Employee>
{
Offset = q.Offset.GetValueOrDefault(0),
Results = Db.LoadSelect(q, include:new []{ "Clerkships" }),
Total = (int)Db.Count(q),
};
return response;
}
链接地址: http://www.djcxy.com/p/65977.html