如何在 EF.core 中使用 FromSqlRaw 指定列

Posted

技术标签:

【中文标题】如何在 EF.core 中使用 FromSqlRaw 指定列【英文标题】:How can I specific columns using FromSqlRaw in EF.core 【发布时间】:2021-06-12 19:41:59 【问题描述】:

我刚刚使用了 FromSqlRaw。在 Microsoft 教程enter link description here 中,使用 FromSqlRaw 必须选择所有列(请注意,我也没有看到一些好的示例)。但我想要的是在连接多个表时选择一些特定的列。

首先,我加入了两个表,如下所示(RequestMaterial 有 Request's Key 作为外键):

var requestVm = CurrentDbContext.PmrRequest
                .FromSqlRaw("Select [r].[RequestName] from [Request] as [r] " +
                            "LEFT JOIN [RequestMaterial] as [m] On [r].RequestId = [m].RequestId " +
                            "where [r].[InitiatorUserId] = 'xxxx'")
                            .ToList();

错误消息是“底层阅读器没有预期的那么多字段”。

当我尝试选择一列而不加入表格时:

var requestVm = CurrentDbContext.PmrRequest
                .FromSqlRaw("Select [r].[RequestName] from [Request] as [r] " +
                            "where [r].[InitiatorUserId] = 'xxxx'")
                            .ToList();

报告了同样的错误。到目前为止,只有当我选择所有列时才能解决此问题。但问题是,当我使用连接表执行此操作时,选择了重复的列 (RequestId) 并报告了错误(“已添加具有相同键的项目。键:RequestId'”)。

有人有类似经历吗?或上述情况的任何解决方案?

【问题讨论】:

创建一个与查询结果集匹配的数据库集。您根本不会将它用于插入、更新和删除 - 仅用于 SELECT。 感谢您的回答。实际上,我使用原始 SQL 来根据搜索参数动态生成 sql 查询。也就是说,我需要对不同实体的许多字段(例如请求、请求材料和请求产品)建立约束,但只从提及的实体中选择有限的字段。你有什么办法解决这种情况吗? 你应该更加确定你的问题,并发布相同的例子你有什么和你需要什么。 【参考方案1】:

创建一个特殊的类来从 sp 中获取数据。此类应具有存储过程选择所具有的所有属性。你不需要选择everytning。只需选择您需要的。

public class ResultData

public string RequestName get;set;
public string RequestMaterial get;set;
.....
.....

在此之后添加到 dbContext DbSet 并配置没有这样的键

modelBuilder.Entity<ResultData>(e =>
        
            e.HasNoKey();
        );

这是一个使用存储过程获取数据的示例函数


public async Task<IEnumerable<ResultData>> GetDetailsData(int id, string name)

    var pId = new SqlParameter("@InitiatorUserId", id);
 
    return await _context.Set<ResultData>()
             .FromSqlRaw("Execute sp_GetData  @Id ", parameters: new[]  pId )
            .ToArrayAsync();

如果你使用低于 3.0 的 ef core,使用 .FromSql 而不是 .FromSqlRaw

【讨论】:

对不起,我使用原始 sql 是因为我想将动态搜索查询加入到请求、请求材料和其他实体中。所以我更喜欢根据C#中的搜索查询生成一个sql字符串,用forsqlraw运行sql查询。我的情况有什么解决办法吗? FromSqlRaw 和 FromSql 没有区别。只是语法不同。正如我所解释的,所选属性的名称应与类的属性名称相同。您可以按照自己喜欢的方式更改搜索条件,只需使用相同的名称进行最终选择。你也可以使用一些虚假的属性。【参考方案2】:

抱歉,我在阅读官方教程时发现了这个

使用原始 SQL 查询时需要注意一些限制:

SQL 查询必须返回实体类型的所有属性的数据。

因此,目前我们不允许在 EF.core 2.0+ 中使用 FromSqlRaw 指定列。

【讨论】:

表示dbcontext类的属性应该与存储过程选择查询的选择列同名。但是您可以根据需要选择尽可能多的列。

以上是关于如何在 EF.core 中使用 FromSqlRaw 指定列的主要内容,如果未能解决你的问题,请参考以下文章

如何在 EF Core 中使用 DbFunction 翻译?

如何在 EF Core Like 函数中使用通配符

EF Core中的多对多映射如何实现?

如何在 EF Core 中实例化 DbContext

如何在 EF Core 中将内部联接与计算列一起使用?

ASP.Net Core 如何在 EF Core 和 Identity 中获取用户角色