如何在 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 指定列的主要内容,如果未能解决你的问题,请参考以下文章