简体   繁体   English

如何从 EF Core 中的存储过程获取对象列表?

[英]How to get a list of objects from a stored procedure in EF Core?

I have a stored procedure that gets several parameters and based on them it calls another stored procedure.我有一个存储过程,它获取多个参数,并基于它们调用另一个存储过程。 The returning columns may vary based on the stored procedure that will be actually called.返回的列可能因实际调用的存储过程而异。

So I built a base class that contains all the shared columns and extended it with different classes each with its own additional columns as models for the data to be returned from the stored procedures.因此,我构建了一个包含所有共享列的基类,并使用不同的类对其进行了扩展,每个类都有自己的附加列作为要从存储过程返回的数据的模型。

Here are the classes for example:以下是类:

public class SP_BaseModel
{
    public decimal? Sum { get; set; }
    public string Name { get; set; }
    public DateTime? BirthDate { get; set; }
}

public class SP_Extended1 : SP_BaseModel
{
    public int? Age { get; set; }
    public string Hobby { get; set; }
}

I'm registering the above models in the DbContext like this:我正在像这样在 DbContext 中注册上述模型:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<SP_BaseModel>().HasNoKey();
    modelBuilder.Entity<SP_Extended1>();
    ...
}

I've tried both of the following methods but neither works:我已经尝试了以下两种方法,但都不起作用:

public IQueryable<T> GetData<T>(string param1, int? patam2 = null, DateTime? param3 = null) where T : SP_BaseModel
{
    return Context.Set<T>()
                  .FromSqlInterpolated($"EXEC SP_GetData {param1},{param2 ?? null},{param3 ?? null}");
}


public async Task<List<T>> GetData<T>(string param1, int? patam2 = null, DateTime? param3 = null) where T : SP_BaseModel
{
    return Context.Set<T>()
                  .FromSqlInterpolated($"EXEC SP_GetData {param1},{param2 ?? null},{param3 ?? null}").ToListAsync();
}

I'm creating a Nuget from that and in the client, I'm consuming it like this:我正在从中创建一个 Nuget,并在客户端中使用它:

public List<SP_Extended1> GetData(DateTime? today = null)
{
    today ??= DateTime.Today;
    
    //This didn't work
    var list1 = unitOfWork.MyRepository.GetData<SP_Extended1>(...);
    
    //This didn't work as well
    var list2 = unitOfWork.GetData<SP_Extended1>(...).AsEnumerable();

    return ...
}

But I'm getting this error message:但我收到此错误消息:

'FromSqlRaw or FromSqlInterpolated was called with non-composable SQL and with a query composing over it.
Consider calling `AsEnumerable` after the FromSqlRaw or FromSqlInterpolated method to perform the composition on the client-side.'

Try not to use inheritance here.尽量不要在这里使用继承。 Merge SP_Extended1 with a base class.SP_Extended1与基类合并。 EF doesn't like inheritance classes. EF 不喜欢继承类。 It usually takes a lot of blood to make it working.通常需要大量的血液才能使其发挥作用。 Easier to use independent classes.更容易使用独立的类。 This is a sample:这是一个示例:

I wrote the special class to get data from stored procedure我写了一个特殊的类来从存储过程中获取数据

public class AccDef
{
    public string AccDefName { get; set; }
    public string InvoiceNumber { get; set; }
    public DateTime InvoiceDate { get; set; }
    public DateTime DeliveryDate { get; set; }
    public string ZoneName { get; set; }
    public double? Quantity { get; set; }
    public double HaulawayAmount { get; set; }
    public double FuelAmount { get; set; }
    public double SumAmount { get; set; }

    [NotMapped]
    public string StrQuantity
    {
        get { return Quantity == null || Quantity == 0 ? "-" : string.Format("{0:F0}", Quantity); }
    }

    [NotMapped]
    public string StrInvoiceDate
    {
        get { return InvoiceDate.ToString("dd/MM/yyyy"); }
    }

    [NotMapped]
    public string StrDeliveryDate
    {
        get { return DeliveryDate.ToString("dd/MM/yyyy"); }
    }
}

EF context EF上下文

        modelBuilder.Entity<AccDef>(e =>
        {
            e.HasNoKey();
        });

This is my code to get data from the stored procedure using EF:这是我使用 EF 从存储过程中获取数据的代码:

public async Task<IEnumerable<AccDef>> GetAccDefReportDetailsData(DateTime endDate)
{
    var pEndDate = new SqlParameter("@EndDate", endDate);

    return await _context.Set<AccDef>()
             .FromSqlRaw("Execute sp_GetAccDefReportDetails  @EndDate", parameters: new[] { pEndDate })
            .ToArrayAsync();
}

After this I converted this array to list of my EF model entities.在此之后,我将此数组转换为我的 EF 模型实体列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM