[参考]或[忽略]?

我们有一个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

上一篇: [Reference] or [Ignore]?

下一篇: Curly brackets in OrmLite select query throws error