我在旧项目中无法使用 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
我已针对数据库手动运行查询,它确实返回了一些值。而上面只返回 null
和 0
。
最佳答案
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 withrecord
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/