【问题标题】:Convert SQL request to LINQ将 SQL 请求转换为 LINQ
【发布时间】:2020-05-22 23:05:59
【问题描述】:

我有一个这样的对象:

public partial class Invoice
{
        public string DocumentNumber { get; set; }
        public DateTime? DocumentDate { get; set; }
        public string DocumentReference { get; set; }
        public string SerialNumber { get; set; }
        public string ProductCode { get; set; }
        public string Description { get; set; }
        public string Certificate { get; set; }
        public string Email { get; set; }
        public string Language { get; set; }
}

我还有一个返回一些结果的数据库 SQL 查询(上述对象的表):

SELECT 
    DocumentNumber, DocumentDate, DocumentReference,
    SerialNumber, ProductCode, Description, Certificate
FROM 
    vInvoice
WHERE 
    CHECKSUM(DocumentNumber + DocumentReference + CAST(DocumentDate AS VARCHAR)) 
        IN (SELECT CHECKSUM(DocumentNumber + DocumentReference + CAST(DocumentDate AS VARCHAR))
            FROM vInvoice
            WHERE Email = 'somemail@gmail.com' AND Language = 'FR'
            GROUP BY DocumentNumber, DocumentDate, DocumentReference
            ORDER BY DocumentDate 
                OFFSET 0 ROWS
                FETCH NEXT 4 ROWS ONLY)

我可以编写与上述 SQL 语句相同的 LINQ 请求吗?

【问题讨论】:

  • 您的 Linq 查询是直接与数据库对话,还是针对已从数据库中检索到的内存集合执行?
  • 如果您希望它直接从数据库中检索结果,为什么不直接执行查询,因为您已经拥有 SQL 并且您已经知道它可以工作?见docs.microsoft.com/en-us/ef/core/querying/raw-sql
  • @RobertHarvey,事实是这个 SQL 请求返​​回了一个修改过的对象Invoice(没有字段EmailLangage),我得到一个错误。见stackoverflow.com/questions/60101749/sql-query-fails-in-ef-core
  • @РоманТимохов 您可以尝试将EmailLanguage 作为空值添加到sql 选择中,因为它们是字符串,您可以查看是否是问题所在。我不这么认为。您是否尝试直接映射到 invoice 对象?您还为 sql 使用哪个连接器?是SqlServer还是MySQL;对于这个奇怪的查询/错误,它可能很重要。
  • 怎么用github.com/linq2db/linq2db语法很像

标签: c# sql linq entity-framework-core


【解决方案1】:

好的,所以我在这种情况下要做的是将视图放入 DBML 或 EDMX,然后在函数中使用 linq 来构建匹配发票的列表。代码本身非常简单,但是看着您的查询,我不得不问:CHECKSUM 的目的是什么?

在我看来,您似乎只是获取了与电子邮件和语言匹配的所有发票,并且您的查询可能只是:

SELECT TOP 4
    [DocumentNumber], 
    [DocumentDate], 
    [DocumentReference],
    [SerialNumber], 
    [ProductCode], 
    [Description], 
    [Certificate]
FROM 
    [vInvoice]
WHERE [Email] = 'somemail@gmail.com' AND [Language] = 'FR'
GROUP BY [DocumentNumber], [DocumentDate], [DocumentReference]
ORDER BY [DocumentDate] 

我会为 C# 函数做的事情类似于以下内容:

public IList<Invoice> GetInvoices(string email, string language)
{
    Using (EntityContext context = new EntityContext(ConnectionStrings.Connection))
    {
        IList<Invoice> results;
        results = context.vInvoices
            .Where(x => x.Email == email && x.Language == language)
            .Select(x => new Invoice
            {
                DocumentNumber = x.DocumentNumber, 
                DocumentDate = x.DocumentDate, 
                DocumentReference = x.DocumentReference,
                SerialNumber = x.SerialNumber, 
                ProductCode = x.ProductCode, 
                Description = x.Description, 
                Certificate = x.Certificate,
                Email = x.Email,
                Language = x.Language
            })
            .OrderBy(x => x.DocumentDate)
            .ToList();

        return results;
    }
}

【讨论】:

    猜你喜欢
    • 2017-11-03
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 2018-11-04
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多