Linq 按可为空的日期时间分组并使用它作为条件

发布于 2024-08-11 09:39:13 字数 1478 浏览 4 评论 0原文

我在使用 SubSonic3、Linq、MS SQL Server 2005 的 ASP.NET 应用程序中处理可空日期时间列 [DateInsp]。

当日期时间列 [DateInsp] 不允许空值时,我让这一切都正常工作。一项新要求迫使我将 [DateInsp] 列设置为允许空值,现在我正在努力让这项功能再次正常工作。

问题 1: 我需要首先呈现给定检查员的 7 个最近检查日期的下拉列表(这是检查员的 7 个最近日期的分组列表)。这是我需要转换为 Linq 语法的 TSQL:

declare @InspectorID varchar(5)
set @InspectorID = 'GPA'

select top 7 convert(nvarchar(30), [DateInsp], 101) InspectedDate
from [dbo].[IncomingInspection]
group by [InspectorID], convert(nvarchar(30), [DateInsp], 101)
having [InspectorID] = @InspectorID
order by convert(nvarchar(30), [DateInsp], 101) desc

如果我无法使用 Linq 正常工作,但我可以/可以构建一个存储过程来返回日期列表并将其放入下拉列表中。很公平。我一直在与 Linq 语法作斗争,因此非常感谢这方面的任何帮助。

问题2:我需要使用上面提到的下拉列表中选择的日期来提取该检查员的正确记录和正确的日期。同样,这是一个可为空的日期时间字段,这对我来说是真正的症结所在。

下面是原始的 Linq 语法,它在我必须更改日期时间字段以允许 Null 之前满足了要求:

    Dim query = (From i In db.IncomingInspections _
        Where i.InspectorID = User.Identity.Name _
        Group By Key = New With {i.DateInsp} Into Group _
        Order By Key.DateInsp Descending _
        Select Key = New With {.DateInsp = Key.DateInsp.ToShortDateString}).Take(7)

这个应用程序是用 VB.NET 编写的,并使用了一些 Linq 语法,这都让我头疼。如果您可以提供 C# 语法来完成此任务,我可以自己将其转换为 VB.NET。

编辑:

由于某种原因,我无法使用 .Value 属性;我得到:不支持成员“Value”

我得到:“'<'附近的语法不正确。” 如果我尝试将日期比较添加到 where 子句也。

编辑结束

非常感谢,

乔什

I am struggling with a nullable datetime column [DateInsp] in an ASP.NET app which uses SubSonic3, Linq, MS SQL Server 2005.

I had this all working when the datetime column [DateInsp] did not allow nulls. A new requirement forced me to set the [DateInsp] column to allow nulls and now I am struggling getting this piece of functionality to work properly again.

Problem 1:
I need to first render a dropdown list of the 7 most recent inspection dates for a given inspector (this is a grouped list of the 7 most recent dates for the inspector). Here is the TSQL that I need to convert to Linq syntax:

declare @InspectorID varchar(5)
set @InspectorID = 'GPA'

select top 7 convert(nvarchar(30), [DateInsp], 101) InspectedDate
from [dbo].[IncomingInspection]
group by [InspectorID], convert(nvarchar(30), [DateInsp], 101)
having [InspectorID] = @InspectorID
order by convert(nvarchar(30), [DateInsp], 101) desc

If I can't get this work properly using Linq, BUT I can/could build a stored proc to return the list of dates and throw that into a dropdown. Fair enough. I've been fighting with the Linq syntax so any help in this area is greatly appreciated.

Problem 2: I need to use the selected date in the dropdown mentioned above to pull the correct records for this inspector and the correct date. Again, this is a nullable datetime field and this is real sticking point for me.

Here was the original Linq syntax that accomplished the requirement before I had to change the datetime field to allow Nulls:

    Dim query = (From i In db.IncomingInspections _
        Where i.InspectorID = User.Identity.Name _
        Group By Key = New With {i.DateInsp} Into Group _
        Order By Key.DateInsp Descending _
        Select Key = New With {.DateInsp = Key.DateInsp.ToShortDateString}).Take(7)

This app is written in VB.NET and uses some Linq syntax which both make my head hurt. If you can offer C# syntax to accomplish this I can translate it to VB.NET myself.

EDIT:

For some reason I can't use the .Value property; I get: The member 'Value' is not supported

I get: "Incorrect syntax near '<'." if I try to add the date comparison to the where clause too.

END EDIT

Thanks Much,

Josh

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡淡の花香 2024-08-18 09:39:13

我继续使用 2 个存储过程来解决这个问题,从而消除了对 Linq 语法的需要:

这是我用来获取最后 7 个检查日期列表的 TSQL(仅包含日期时间字段的日期部分:

select top 7 convert(nvarchar(30), [DateInsp], 101) InspectedDate
from [dbo].[IncomingInspection]
group by [InspectorID], convert(nvarchar(30), [DateInsp], 101)
having [InspectorID] = @InspectorID
order by convert(nvarchar(30), [DateInsp], 101) desc

这里是我用来获取检查员检查记录的过滤列表以及在下拉列表中选择的检查日期的 tsql(仅使用标准语句中的日期部分):

select [ID]
,[InspectorID]
,[DateInsp]
-- (more fields here)
from [dbo].[IncomingInspection]
where [InspectorID] = @InspectorID and DATEADD(dd, 0, DATEDIFF(dd, 0, [DateInsp])) = DATEADD(dd, 0, DATEDIFF(dd, 0, @DateFilter))

有时我只需要使用作品而不是新的和有时我在 Linq 中最简单的事情上遇到了困难,我认为这既是因为 Linq 对我来说是新的,而且我对 VB.NET 语法感到困惑,尤其是在将它与 Linq 结合时。

I went ahead and used 2 stored procedures to solve this problem eliminating the need for Linq syntax here:

Here is the TSQL that I used to get a list of the last 7 Inspection Dates (w/ only date portion of the datetime field:

select top 7 convert(nvarchar(30), [DateInsp], 101) InspectedDate
from [dbo].[IncomingInspection]
group by [InspectorID], convert(nvarchar(30), [DateInsp], 101)
having [InspectorID] = @InspectorID
order by convert(nvarchar(30), [DateInsp], 101) desc

Here is the tsql that I used to grab a filtered list of inspection records for the inspector and the inspection date selected in the dropdown (using only the date portion in the criteria statement):

select [ID]
,[InspectorID]
,[DateInsp]
-- (more fields here)
from [dbo].[IncomingInspection]
where [InspectorID] = @InspectorID and DATEADD(dd, 0, DATEDIFF(dd, 0, [DateInsp])) = DATEADD(dd, 0, DATEDIFF(dd, 0, @DateFilter))

Sometimes I just have to go with works rather than what is new and shiny. I have struggled with the simplest things in Linq on occasion and I think it is both because Linq is new to me and I beat my head on VB.NET syntax, especially when combining it with Linq.

鲜血染红嫁衣 2024-08-18 09:39:13

很抱歉用 C# 回答,但这是我对您的疑问的解释:

问题#1。

您在问题中使用having,并将日期时间转换为字符串。我认为没有必要进行这些操作。

string inspectorId = "GPA";

List<DateTime?> someDates = db.IncomingInspection
  .Where(insp => insp.InspectorId == inspectorId)
  .Select(insp => insp.InspectedDate)
  .Distinct()
  .OrderByDescending(d => d)
  .Take(7)
  .ToList();

问题#2。

有两种情况:要么您从用户处获得 null,要么您有一个值。编写针对每种情况的查询很简单。如此简单,我觉得我误解了这里的意图。

DateTime? selectedDate = control.SelectedValue;

List<IncomingInspection> someRecords = null;

if (selectedDate.HasValue())
{
  DateTime selectedDateValue = selectedDate.Value;
  someRecords = db.IncomingInspection
    .Where(insp => insp.InspectorId == inspectorId)
    .Where(insp => insp.InspectedDate == selectedDateValue)
    .ToList();
}
else
{
  someRecords = db.IncomingInspection
    .Where(insp => insp.InspectorId == inspectorId)
    .Where(insp => insp.InspectedDate == null)
    .ToList();
}

Sorry to answer in C#, but here's my interpretation of your queries:

Problem #1.

You use having in the question, as well as convert the datetimes to strings. I didn't see a need for either of those operations.

string inspectorId = "GPA";

List<DateTime?> someDates = db.IncomingInspection
  .Where(insp => insp.InspectorId == inspectorId)
  .Select(insp => insp.InspectedDate)
  .Distinct()
  .OrderByDescending(d => d)
  .Take(7)
  .ToList();

Problem #2.

There's two cases: either you have a null from the user or you have a value. It is simple to write a query to target each case. So simple, that I feel like I've misread the intention here.

DateTime? selectedDate = control.SelectedValue;

List<IncomingInspection> someRecords = null;

if (selectedDate.HasValue())
{
  DateTime selectedDateValue = selectedDate.Value;
  someRecords = db.IncomingInspection
    .Where(insp => insp.InspectorId == inspectorId)
    .Where(insp => insp.InspectedDate == selectedDateValue)
    .ToList();
}
else
{
  someRecords = db.IncomingInspection
    .Where(insp => insp.InspectorId == inspectorId)
    .Where(insp => insp.InspectedDate == null)
    .ToList();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文