【问题标题】:Creating a queryable property for a linq to sql entity为 linq to sql 实体创建可查询属性
【发布时间】:2010-10-29 05:25:27
【问题描述】:

我在 SQL Server 中有一个简单的表结构:

一个表存储自行车 (Bikes) 列表,第二个表存储自行车所有者 (Owners) 的历史列表。

使用 Linq 2 SQL,我生成了一个模型,该模型为我提供了一个与“所有者”具有一对多关系的“自行车”实体,称为“HistoricalOwners”。

到目前为止一切都很好......

现在我有很多对当前所有者感兴趣的问题。当前所有者是所有者表中的最新条目。

repo.Bikes().Where(b => b.HistoricalOwners.OrderByDescending(o => o.Date).First().Name == "Joe")

这可行,但有点难看,并没有真正说出我的要求。最好在我的 Bike 实体上创建一个“CurrentOwner”属性并对其进行查询。

public Owner CurrentOwner
{
    get
    {
        return HistoricalOwners.OrderByDescending(o => o.Date).First();
    }
}    

然后我可以这样查询:

repo.Bikes().Where(b => b.CurrentOwner.Name == "Joe")

这会编译,但在运行时它会失败:

成员“CurrentOwner”没有支持的 SQL 转换。

这完全有道理。

有谁知道我如何能够创建一个 CurrentOwner 以让这个查询工作?

我做了一些研究,让 CurrentOwner 返回一个表达式树而不是一个实例,但我从来没有得到任何我真正满意的地方。

然后我想知道是否可以为 CurrentOwner 添加一个额外的关系到我的 linq 2 sql 存储库并将其限制为一对一。但我似乎无法用 linq 2 sql 做到这一点。我想我可以用 Linq 2 实体做到这一点,但目前这不是一个选项。

有人知道我应该如何完成这项工作吗?

提前致谢,

rmk

【问题讨论】:

    标签: .net linq-to-sql lambda iqueryable


    【解决方案1】:

    你试过了吗:

    public Owner CurrentOwner
    {
        get
        {
            return HistoricalOwners.OrderByDescending(o => o.Date).FirstOrDefault();
        }
    }  
    

    看看这是否转化为 SQL?

    【讨论】:

    • 这行不通,它与 First() 没有什么不同,它仍然不知道如何将 CurrentOwner 转换为 SQL,因为 CurrentOwner 是一个属性,因此不能转换为表达
    【解决方案2】:

    我不认为你真的可以按照你想要的方式做到这一点。

    我的建议:

    Bike 表上创建一个新的数据库列CurrentOwnerID,它是Owner 表上OwnerID 的FK。将此映射为模型中的关联,然后您可以按照自己的方式查询CurrentOwner

    缺点是您必须按照任何其他映射属性来管理 CurrentOwner 的值 - 您无法使用原始示例中的其他查询来派生它,因此它可能不适合您的应用程序。

    不过,这是我过去解决此类问题的方式,它为您的模型提供了更大的灵活性 - 您可以选择当前所有者是谁,而不是依赖派生结果,而且很容易理解.

    【讨论】:

    • 我曾想过,但我真的希望这不是答案。我不愿意介绍管理额外属性的开销 + 对数据库的外部更改也必须更新这种新关系。
    • 我支持你 RMK。 必须有一种方法可以对现有模型执行此操作。您真正要做的就是要求 L2S 建立 @Sam 建议手动添加的关系,但在查询中。 L2S 肯定可以做到这一点吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 2013-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多