简体   繁体   中英

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:

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:

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. EF doesn't like inheritance classes. 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

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

This is my code to get data from the stored procedure using 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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