简体   繁体   English

EF Core 使用空引用执行存储过程

[英]EF Core executing stored procedure with null reference

Executing a stored procedure creates this error with EF Core 2.0.使用 EF Core 2.0 执行存储过程会产生此错误。 I am beside myself with this error.这个错误让我很不自在。 Any pointers?任何指针?

public class SalesDTO :  BaseEntity
{
    public int SalesID { get; set; }
    [Display(Name = "User")]
    public string SalesRep { get; set; }
    [Display(Name = "Sales Date")]
    public DateTime OrderDate { get; set; }
    public string CustomerName { get; set; }
    public int? CustomerID { get; set; }
    [Display(Name = "Sale Center")]
    public string CenterName { get; set; }
    public int CenterID { get; set; }
    public decimal TotalAmount { get; set; }
    public SalesType SalesType { get; set; }
}

Model class for the stored procedure.存储过程的模型类。

This is my implementation class这是我的实现类

public IEnumerable<SalesDTO> GetSales(int centerID, string user)
{
        string salesRep = user ?? "";

        List<SqlParameter> parms = new List<SqlParameter>
        {
            new SqlParameter("@CenterID", centerID),
            new SqlParameter("@SalesRep", salesRep)
        };

        return DataContext.Set<SalesDTO>().FromSql("spSalesList @CenterID, @SalesRep", parms.ToArray())
                 .Select(x => new SalesDTO
                 {
                     Id = x.SalesID,
                     SalesID = x.SalesID,
                     CustomerID = x.CustomerID,
                     CustomerName = x.CustomerName,
                     SalesType = x.SalesType,
                     TotalAmount = x.TotalAmount,
                     SalesRep = x.SalesRep,
                     CenterName = x.CenterName,
                     OrderDate = x.OrderDate,
                     CenterID = x.CenterID
                 }).AsNoTracking().ToList();
    }

This code throws:此代码抛出:

NullReferenceException: Object reference not set to an instance of an object. NullReferenceException:未将对象引用设置为对象的实例。

with this stack trace使用此堆栈跟踪

堆栈跟踪

However, if I use SQL Server profiler, I can see that the stored procedure successfully executes when I copy what was executed back to SQL Server Management Studio and execute it.但是,如果我使用 SQL Server Profiler,当我将执行的内容复制回 SQL Server Management Studio 并执行它时,我可以看到存储过程成功执行。

Can you try below code, please.你能试试下面的代码吗?

return DataContext.Set<SalesDTO>().FromSql($"EXECUTE spSalesList {centerID} {salesRep}")
             .Select(x => new SalesDTO
             {
                 Id = x.SalesID,
                 SalesID = x.SalesID,
                 CustomerID = x.CustomerID,
                 CustomerName = x.CustomerName,
                 SalesType = x.SalesType,
                 TotalAmount = x.TotalAmount,
                 SalesRep = x.SalesRep,
                 CenterName = x.CenterName,
                 OrderDate = x.OrderDate,
                 CenterID = x.CenterID
             }).AsNoTracking().ToList();

Meanwhile, it's worthwhile to know the limitations: https://docs.microsoft.com/en-us/ef/core/querying/raw-sql#limitations同时,了解这些限制是值得的: https : //docs.microsoft.com/en-us/ef/core/querying/raw-sql#limitations

I just realized that the repository works alright it's just the data resolution.我刚刚意识到存储库工作正常,这只是数据解析。

If you use one property in the .Select to match to 2 different properties, the NULL Reference error is generated.如果您使用 .Select 中的一个属性来匹配 2 个不同的属性,则会生成 NULL 引用错误。 So this所以这

return DataContext.Set<SalesDTO>().FromSql("spSalesList @CenterID, @SalesRep, @DateFrom, @DateTo", parms.ToArray())
                 .Select(x => new SalesDTO
                 {
                     Id = x.SalesID,
                     SalesID = x.SalesID,
                     CustomerID = x.CustomerID,
                     CustomerName = x.CustomerName,
                     SalesType = x.SalesType,
                     TotalAmount = x.TotalAmount,
                     SalesRep = x.SalesRep,
                     CenterName = x.CenterName,
                     OrderDate = x.OrderDate,
                     CenterID = x.CenterID
                 }).AsNoTracking().ToList();

will give a Null Reference error because the SalesID is matched to both the SalesID column as well as the Id Column, though it may be the same field.将给出空引用错误,因为 SalesID 与 SalesID 列和 Id 列都匹配,尽管它可能是相同的字段。 When you however change the code to但是,当您将代码更改为

return DataContext.Set<SalesDTO>().FromSql("spSalesList @CenterID, @SalesRep, @DateFrom, @DateTo", parms.ToArray())
                 .Select(x => new SalesDTO
                 {
                     Id = x.Id,
                     SalesID = x.SalesID,
                     CustomerID = x.CustomerID,
                     CustomerName = x.CustomerName,
                     SalesType = x.SalesType,
                     TotalAmount = x.TotalAmount,
                     SalesRep = x.SalesRep,
                     CenterName = x.CenterName,
                     OrderDate = x.OrderDate,
                     CenterID = x.CenterID
                 }).AsNoTracking().ToList();

Then it works correctly since the Id and SalesID matches to different fields.然后它可以正常工作,因为 Id 和 SalesID 匹配不同的字段。 I am yet to understand why that is so.我还不明白为什么会这样。 I will add a comment when i get to understand.当我理解时,我会添加评论。

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

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