过滤连接表会混淆sql查询

时间:2017-09-04 17:56:13

标签: c# linq entity-framework-core

我在使用过滤器构建查询时遇到问题。

我的表格结构是日志标题,其中驱动程序卡车创建者表格相关,子表格日志详细信息

然后有一种方法可以获取这些相关数据,其中包含用于过滤日志标题日期的选项,以及基于相关表格(驱动程序或卡车)的过滤器。

现在,当用户仅在标题表上过滤数据时,数据已正确加载,但是当用户过滤相关的卡车或驱动程序时,我发现一个奇怪的错误,即sql无法找到列名。

所以我决定运行探查器并检测Ef正在发送的查询,我发现了一个有趣的结果,ef包括错误表格上的列!。

所以这是c#代码

var h = db.LogHeader.AsQueryable();

        if (OrderNumber == null)
        {
            if (fromDate != DateTime.MinValue) { h = h.Where(l => l.DateTime >= fromDate); }
            if (toDate != DateTime.MinValue) { h = h.Where(l => l.DateTime <= toDate); }
            if (LogID != null) { h = h.Where(l => l.LogHeaderID == LogID); }
            if (Driver != "0") { h = h.Where(l => l.Driver.DriverID.ToString() == Driver); }
            if (Truck != "0") { h = h.Where(l => l.Truck.TruckID.ToString() == Truck); }
            if (Shipped != "") { h = h.Where(l => l.Shipped == Convert.ToBoolean(Shipped)); }

            h = h.Take(rowCount ?? 25);
        }
        else
        {
            h = h.Where(d => d.LogDetails.Any(o => o.OrderNumber == OrderNumber));
        }

        var list = from lh in h
                   select new TruckHistoryViewModel
                   {
                       id = lh.LogHeaderID,
                       DateValue = lh.DateTime.ToString("M/d/yy"),
                       Time = lh.DateTime.ToString("h:mm tt"),
                       Driver = lh.Driver.FullName,
                       DriverID = lh.Driver.DriverID,
                       Truck = lh.Truck.TruckDescription,
                       Stops = lh.Stops,
                       DateAndTime = lh.DateTime,
                       LoaderName = lh.LoaderName,
                       Notes = lh.Notes,
                       CreatedBy = lh.CreatedBy.FullName,
                       Shipped = lh.Shipped == true ? "Yes" : "No",
                       OrderList = lh.LogDetails.Select(d => new LogDetailsViewModel
                       {
                           LogHeaderID = d.LogHeaderID ,
                           OrderNumber = d.OrderNumber,
                           StopNumber = d.StopNumber,
                           WorkComplete = d.Order.WorkComplete,
                           FollowUp = d.Order.FollowUp,
                           IsDouble = d.DubledOrderID != 0 ? true : false
                       })
                   };

sql查询Ef send&#39; s工作(不过滤相关数据时)是:

exec sp_executesql N'SELECT [lh.CreatedBy].[CreateByNameID], [lh.CreatedBy].[Creater], [lh.CreatedBy].[Disabled], [lh.CreatedBy].[FullName], [lh.CreatedBy].[Loader], [lh.CreatedBy].[Picker], [lh.Truck].[TruckID], [lh.Truck].[Disabled], [lh.Truck].[TruckDescription], [lh.Truck].[TruckNumber], [lh.Driver].[DriverID], [lh.Driver].[Disabled], [lh.Driver].[FirstName], [lh.Driver].[LastName], [lh.Driver].[Notes], [lh.Driver].[PhoneNumber], [t].[LogHeaderID], [t].[DateTime], [lh.Driver].[DriverID], [t].[Stops], [t].[LoaderName], [t].[Notes], CASE
WHEN [t].[Shipped] = 1
THEN N''Yes'' ELSE N''No''
END
FROM (
    SELECT TOP(@__p_3) [l0].*
    FROM [LogHeader] AS [l0]
    WHERE (([l0].[DateTime] >= @__fromDate_0) AND ([l0].[DateTime] <= @__toDate_1)) AND ([l0].[Shipped] = @__ToBoolean_2)
) AS [t]
LEFT JOIN [CreatedByName] AS [lh.CreatedBy] ON [t].[CreatedByCreateByNameID] = [lh.CreatedBy].[CreateByNameID]
LEFT JOIN [Trucks] AS [lh.Truck] ON [t].[TruckID] = [lh.Truck].[TruckID]
LEFT JOIN [Drivers] AS [lh.Driver] ON [t].[DriverID] = [lh.Driver].[DriverID]
ORDER BY [t].[CreatedByCreateByNameID], [t].[TruckID], [t].[DriverID]',N'@__p_3 int,@__fromDate_0 datetime2(7),@__toDate_1 datetime2(7),@__ToBoolean_2 bit',@__p_3=30,@__fromDate_0='2017-08-15 00:00:00',@__toDate_1='2017-08-17 00:00:00',@__ToBoolean_2=0

但是当过滤相关表时,它会得到一个有趣的查询,其中包含一些不存在或存在于另一个表中的列名:

exec sp_executesql N'SELECT [l].[LogHeaderID], [l].[CreatedByCreateByNameID], [l].[CreatedDate], [l].[DateTime], [l].[DriverID], [l].[LoaderName], [l].[Notes], [l].[Shipped], [l].[Stops], [l].[TruckID], [l.Truck].[TruckID], [l.Truck].[Disabled], [l.Truck].[TruckDescription], [l.Truck].[TruckNumber], [l.Truck].[CreatedByCreateByNameID], [l.Truck].[DriverID], [l.Truck].[LogHeaderID], [l.Truck].[DateTime], [l.Truck].[Stops], [l.Truck].[LoaderName], [l.Truck].[Notes], [l.Truck].[Shipped]
FROM [LogHeader] AS [l]
LEFT JOIN [Trucks] AS [l.Truck] ON [l].[TruckID] = [l.Truck].[TruckID]
WHERE (([l].[DateTime] >= @__fromDate_0) AND ([l].[DateTime] <= @__toDate_1)) AND ([l].[Shipped] = @__ToBoolean_3)
ORDER BY [l].[TruckID]',N'@__fromDate_0 datetime2(7),@__toDate_1 datetime2(7),@__ToBoolean_3 bit',@__fromDate_0='2017-08-15 00:00:00',@__toDate_1='2017-08-17 00:00:00',@__ToBoolean_3=0

在ssms中返回错误:

Msg 207, Level 16, State 1, Line 1
Invalid column name 'CreatedByCreateByNameID'.
Msg 207, Level 16, State 1, Line 1
Invalid column name 'DriverID'.
Msg 207, Level 16, State 1, Line 1
Invalid column name 'LogHeaderID'.
Msg 207, Level 16, State 1, Line 1
Invalid column name 'DateTime'.
Msg 207, Level 16, State 1, Line 1
Invalid column name 'Stops'.
Msg 207, Level 16, State 1, Line 1
Invalid column name 'LoaderName'.
Msg 207, Level 16, State 1, Line 1
Invalid column name 'Notes'.
Msg 207, Level 16, State 1, Line 1
Invalid column name 'Shipped'.

为清楚起见,我将添加db上下文类

protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.Entity<LogHeader>().HasOne(t => t.Truck).WithMany(l => l.TruckLogs);
            builder.Entity<LogHeader>().HasOne(t => t.Driver).WithMany(l => l.DriverLogs);
            builder.Entity<LogHeader>().HasOne(t => t.CreatedBy).WithMany(l => l.LogHeaders);

            builder.Entity<LogDetails>().HasOne(o => o.Order).WithMany(o => o.LogDetails);

            builder.Entity<Order>().HasOne(o => o.Category).WithMany(c => c.Orders).HasForeignKey(c => c.CatagoryID);

            builder.Entity<CreatedBy>().ToTable("CreatedByName");
        }

        public DbSet<LogHeader> LogHeader { get; set;}
        public DbSet<LogDetails> LogDetails { get; set; }

        public DbSet<Truck> Trucks { get; set; }
        public DbSet<Driver> Drivers { get; set; }
        public DbSet<ApplicationUser> ApplicationUser { get; internal set; }
        public DbSet<Order> Order { get; set; }
        public DbSet<CreatedBy> Creaters { get; set; }
        public DbSet<Category> Categories { get; set; }

我的代码有什么问题吗? (或者不太可能是ef中的错误)

注意:我对EF很新,所以如果对代码有任何建议,我将非常感激。

0 个答案:

没有答案