在linq语句中包含变量作为字段名称

时间:2013-05-28 07:55:00

标签: linq

嗨我有一个针对我没有创建的数据库表的链接声明......数据结构是

  • Tbl_BankHols
  • BHDate .... Datetime
  • E ......... Bit
  • S .........位
  • W .........位
  • 我.........位

基本上它有一个日期列表,然后是E,S,W,I中的值0或1,表示该日期是英格兰,苏格兰,威尔士和/或爱尔兰的银行假日。

如果我想知道某个国家的日期是否是银行假日我的Linq声明是

Dim BHQ = From d in db.Tbl_BankHols _
          Where d.BHDate = chkDate _
          Select d.BHDate

其中chkDate是我正在检查的日期。如果返回结果,则该日期是其中一个国家/地区的银行假日。

我现在需要查明chkDate是否是特定国家/地区的银行假日,如何将其引入where语句?

在考虑更改数据库的结构之前,我问这是否可行。我想的是只有一个国家字段作为一个字符串,其中包含E,EW,EWS,EWSI,I和其他类似组合的值,然后我只使用WHERE BCountry LIKE%X%(其中X是国家我'我很感兴趣)。或者有更好的方法吗?

4 个答案:

答案 0 :(得分:1)

您可以引入一个新的Region(Code,Description)表,并在表中添加一个指向Regions表的外键,而不是以您编写的方式更改表的结构。然后,您的银行假期表将包含每个(日期/地区)组合的一条记录。

你的linq声明:

Dim BHQ = From d in db.Tbl_BankHols _
      Where d.BHDate = chkDate And d.Region = "England" _
      Select d.BHDate

答案 1 :(得分:1)

呃停止,

您对额外非规范化和使用LIKE的建议是一个非常“错误”的想法。

您需要一个国家/地区的表格,我们称之为Country,另一个表格为假期,我们称之为HolidayCountry表应包含系统/模型中每个国家/地区的行。 Holiday表应该有两列。一个用于Date和一个foriegn国家/地区的密钥,我们可以将其称为CountryId

然后你的linq可能看起来像,

db.Holiday.Any(Function(h) h.Country.Name = 
                    "SomeCountry" AndAlso h.Date = someDate)

你不应该使用LIKE的原因是多方面的,但有两个主要的反对意见。

LIKE表现不佳,索引难以支持,

让我们想象一下您需要为这些国家存储假期的情况,

  

厄瓜多尔

     

萨尔瓦多

     

爱沙尼亚

     

埃塞俄比亚

     

英国

现在,您已将代码"E"分配给英格兰,您将向其他人提供哪些代码?您说没问题,"EL""ET" ...但是,您的LIKE "%E"条件已经损坏。


以下是我将使用的架构的脚本。

CREATE TABLE [Country](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](100) NOT NULL,
    CONSTRAINT [PK_Country] PRIMARY KEY CLUSTERED
    (
        [Id] ASC
    ));

CREATE TABLE [Holiday](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Date] [date] NOT NULL,
    [CountryId] [int] NOT NULL FOREIGN KEY Country(Id),
    CONSTRAINT [PK_Country] PRIMARY KEY CLUSTERED
    (
        [Id] ASC
    ));

答案 2 :(得分:0)

  

在我考虑改变数据库的结构之前

您可以使用LINQKit通过使用OR谓词撰写查询来完成此操作。

Dim IQueryable<BankHoliday> BHQ = ... (your query)

Dim pred = Predicate.False(Of BankHolifday)

If countryString.Contains("E")
    pred = pred.Or(Function(h) h.E)
EndIf
If countryString.Contains("S")
    pred = pred.Or(Function(h) h.S)
EndIf
...

Return query.Where(pred.Expand())

(我不熟悉VB,所以可能会有一些错误)

有关类似示例,请参阅this answer

答案 3 :(得分:0)

虽然数据库结构不是最佳的,但如果您正在使用遗留代码并且没有为完整的重构做出任何努力,那么您将不得不去做(我觉得对你而言)。< / p>

我认为你最简单的选择不仅是选择日期,还要选择属性。

Dim BHQ = From d in db.Tbl_BankHols _
          Where d.BHDate = chkDate _
          Select d

此代码将为您提供d.S,d.E,d.W和d.I,您可以通过编程方式确定假期是否适用于您当前正在处理的任何国家/地区。这意味着在查询之外,如果假期适用于您正在处理的国家/地区,您将有一个单独的if语句。