【问题标题】:SQLite Extentions inner joins on GetAllWithChildrenGetAllWithChildren 上的 SQLite 扩展内部连接
【发布时间】:2015-07-07 17:12:42
【问题描述】:

我们目前正在尝试将 SQLite 扩展 (PCL) 作为 ORM。

我们想知道,如果在实体中正确配置了子元素,映射是否应该构建一个带有 INNER JOIN 的 SELECT?

public class Project
{
    [PrimaryKey]
    public long Id { get; set; }

    [ForeignKey(typeof(EnterpriseClient))]
    public long EnterpriseClientId { get; set; }

    [ManyToOne]
    public EnterpriseClient EnterpriseClient { get; set; }

    [OneToMany(CascadeOperations = CascadeOperation.All)]
    public List<WorkOrderHead> WorkOrderHeads { get; set; }
}

如果我们使用 GetAllWithChildren 获取所有项目:

var x = _db.GetAllWithChildren<Project>(p => true);

我们的结果是对每个子项 (EnterpriseClient) 进行多项选择,我们希望它能够在一次选择和连接中一次收集所有数据。

我们的配置是错误的还是应该是这样的?

【问题讨论】:

    标签: c# orm xamarin.android sqlite-net sqlite-net-extensions


    【解决方案1】:

    现在 SQLite-Net Extensions 为每个要获取的属性执行 SELECT,并且在读取操作中也遇到了N+1 issue(它已经解决了写入操作)。它被实现为 SQLite.Net 上的一个非常薄的层,为您提供一些访问实体关系的便捷方法。目前,它按照您描述为预期行为的方式工作。通过主键或索引属性访问寄存器非常快,而且对于大多数移动项目中使用的小型数据库而言,性能不是问题。

    SQLite-Net Extensions 是一个不断发展的项目,因此总是欢迎功能请求(当然还有拉取请求)。但是,INNER JOIN 会破坏 SQLite.Net 映射,因此返回所有必需信息的单个 SELECT 将需要重新实现 SQLite.Net 映射机制。

    理论上可以解决 N+1 问题,为每个属性执行单个 SELECT,因此递归 TO-MANY 操作会看到性能提升。我创建了an issue 来跟踪这个请求。

    编码愉快!

    【讨论】:

    • 谢谢,这正是我所担心的。那么在移动世界中,我们是否应该忘记 ORM 并专注于在数据库上执行我们自己的 SELECT?
    • 好吧,我需要在极少数情况下执行手动选择。大多数情况下,性能改进可以忽略不计,易于使用和重构友好的方法使规模倾向于 SQLite-Net 扩展。使用异步操作可以进一步降低性能影响。所以我建议你在优化之前测量。
    • 在基准测试之后,我们自己的选择比使用框架的嵌套选择要快很多。我们构建了构建复杂查询的 EntityViews 构建器。使用子对象的默认解析要慢得多...
    猜你喜欢
    • 1970-01-01
    • 2011-10-06
    • 1970-01-01
    • 2020-10-03
    • 2014-06-19
    • 2013-08-15
    • 1970-01-01
    • 1970-01-01
    • 2021-03-24
    相关资源
    最近更新 更多