c# - 如何将命名元组与 Entity Framework 原始 SQL 'SqlQuery' 方法一起使用?

标签 c# entity-framework

我在旧项目中无法使用 EF5。在其中,我希望使用一些自定义的“原始”Sql 和 EF 从数据库返回两个字段。当我尝试将值返回到命名元组时,这些值始终是值类型的“默认值”。因此它不会将数据库值映射到命名元组。

EF5 支持这个概念吗?如果是的话,有人可以解释一下我做错了什么吗?

const string userQuery = @"
SELECT Top 1 ThirdPartyIdentifier, ThemeId 
FROM Users
WHERE ThirdPartyIdentifier IS NOT NULL AND ThemeId > 0";

var (thirdPartyIdentifier, themeId) = SqlServerContext
    .Database
    .SqlQuery<(string ThirdPartyIdentifier, int ThemeId)>(userQuery)
    .Single();


#region Assembly EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// C:\Users\pewpew\.nuget\packages\entityframework\5.0.0\lib\net45\EntityFramework.dll
// Decompiled with ICSharpCode.Decompiler 7.1.0.6543
#endregion

我已针对数据库手动运行查询,它确实返回了一些值。而上面只返回 null0

最佳答案

Does EF5 support this concept?

  • 不,事实并非如此。
  • 据我所知,Entity Framework 以及 Entity Framework Core 1.x 和 2.0 的所有版本仅支持将查询结果列绑定(bind)到必须具有无参数构造函数的 class 类型 and mutable property setters (尽管它们不需要公开)。
  • Entity Framework Core 2.1 added support for "convention-based" entity class constructors ,但是(截至 2022 年 8 月,在 EF Core 6 中)仍然没有提供任何方法来配置构造函数的映射方式。
  • 但至关重要的是:您无法映射到字段,甚至是公开的和可变的字段。
    • 并且 ValueTuple 有字段。喜悦。

Entity Framework 使用其内部ObjectContext.Translate的功能将查询结果映射到注册/配置的实体类类型,并将非表查询结果映射到复杂类型 (DbContext 中没有嵌入实体类型的魔力,但仍然有用)。

  • 可以在 Linq-to-EF 查询的 .Select 投影中使用“匿名类型”,但由于其他原因,匿名类型非常糟糕 - 但是这通常是 EF 的唯一选择。
  • 在有人说“使用记录类!”之前,不幸的是OP没有使用C# 9.0,并且there's still open issues with record types .

因此,您需要使用 .Database.SqlQuery有点冗长,但这还不算太糟糕:带有属性 setter 的简单可变 POCO 就可以工作 -如果您对 EF 5 不顾构造函数而保持警惕 (*grumble*):

public class UserQueryResult
{
    public String ThirdPartyIdentifier { get; internal set; }
    public Int32  ThemeId              { get; internal set; }
}

const string userQuery = @"
SELECT
    TOP 1
    ThirdPartyIdentifier,
    ThemeId 
FROM
    Users
WHERE
    ThirdPartyIdentifier IS NOT NULL
    AND
    ThemeId > 0;
";

UserQueryResult result = await SqlServerContext
    .Database
    .SqlQuery<UserQueryResult>( userQuery )
    .SingleAsync( cancellationToken )
    .ConfigureAwait(false);

关于c# - 如何将命名元组与 Entity Framework 原始 SQL 'SqlQuery' 方法一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73314865/

相关文章:

c# - 加载任何表单时运行事件

c# - 带有 Oracle 表/ View 的 Entity Framework 5 不存在不一致?

.net - Entity Framework 架构中的有界 (Db) 上下文

c# - 我应该为域和 EF 使用单独的模型吗?

c# - 避免在 ASP.NET 上打印 HTML 标记

c# - 长时间停顿的并行任务

c# - 让所有线程休眠

c# - Entity Framework : Model for Categories/Products relation

c# - 异常抛出 : The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects

entity-framework - "only parameterless constructors are support in Linq to Entites"有哪些可能的解决方法