【问题标题】:Insert in to DB if input doesn't fall within a range如果输入不在范围内,则插入数据库
【发布时间】:2018-03-07 17:47:12
【问题描述】:

作为输入,我得到了 startDate 和 endDate。我必须从客户端进行 linq 查询,以检查在这段时间内 DB 中是否存在任何现有条目。

例如,在我的数据库中,如果我有一个 StartDate 为 2018-01-05 且 enddate 为 2018-01-09 的条目,并且用户尝试输入另一个条目,其开始日期为 2018-01-04 且 enddate 为 2018 -01-06 我不应该允许这样做,因为在我的数据库中我已经有一个在此时间范围内常见的条目。这是我的代码

 var stDate = dbcontext.tables.Where( st => 
                             st.StartDate <= UserStartDate && st.EndDate >= UserEndDate && st.Status == "Queued" ||
                             st.StartDate >= UserStartDate && st.EndDate >= UserEndDate && st.Status == "Queued" ||
                             st.StartDate <= UserStartDate && st.EndDate <= UserEndDate && st.Status == "Queued" ||
                             st.StartDate >= UserStartDate && st.EndDate <= UserEndDate && st.Status == "Queued").ToList();
                if (stDate.Count >0 )
                {
                    //notification to user("There is an existing request within this time range");
                }
                else
                {
                    // do the rest operation
                }

但问题是,如果有人尝试从 2018 年 1 月 9 日到 2018 年 1 月 10 日输入条目,则它属于 3 种条件,并且应用程序不接受该条目。 对我有什么建议可以改进我的代码吗?

【问题讨论】:

  • 我总是会在查询本身中进行过滤/检查。将数据检索到您的客户端以进行过滤/检查会要求解决诸如种族条件、网络负载过大等问题。至于“查找数据是否在范围内”的问题,这也是一个困扰我的问题。
  • 你能检查.Status这个范围吗?
  • 我认为没有任何日期范围不属于这些条件。
  • 你是对的@FaizanRabbani,你知道如果用户的开始和结束日期落在现有条目中,我如何允许用户输入。 .Staus 我必须使用 Queued 因为我的其他条目可能在同一时间范围内但处于不同状态。我不关心这些状态。
  • @Shaif 你只希望 start 和 end 都不在现有范围内吗?这些范围可以吗:2018-01-08 & 2018-01-15 2018-01-02 & 2018-01-07 2018-01-01 & 2018-01-15?

标签: c# sql linq


【解决方案1】:

你的逻辑有点不对劲。在您的所有条件下,您将StartDateUserStartDateEndDateUserEndDate 进行比较。相反,您应该在每种情况下比较相同的事物。见下文:

var stDate = dbcontext.tables
             .Where(st =>  st.Status == "Queued" 
               && (  st.StartDate >= UserStartDate && st.StartDate < UserEndDate   
                  || st.StartDate > UserStartDate  && st.StartDate <= UserEndDate  
                  || st.EndDate >= UserStartDate   && st.EndDate < UserEndDate     
                  || st.EndDate > UserStartDate    && st.EndDate <= UserEndDate )
              ).ToList();

请注意,StartDate 与前 2 个条件中的 UserStartDateUserEndDate 进行比较,EndDate 与后 2 个条件中的 UserStartDateUserEndDate 进行比较。

我不应该允许这样做,因为在我的数据库中我已经有一个在此时间范围内常见的条目。

这意味着您唯一担心的情况是UserStartDateUserEndDate 是否位于StartDateEndDate 的相对两侧,如下所示。

如果满足其中任何一个条件,您将始终处于同一日期范围内。

更新:

上面的代码已更新,因为 OP 指出 UserStartDate 实际上可能与 EndDate 相同,或者 UserEndDate 可能与 StartDate 相同但不算作重叠数据。

更新2:

正如 OP 所指出的,我忘记了 UserStartDateUserEndDate 都在日期范围内的情况。根据 OP 的评论,该行如下:

st.StartDate <= UserStartDate && st.EndDate >= User.EndDate && st.Status == "Queued"

【讨论】:

  • 比你@Sudsy1002 但问题如果我按照你的代码用户无法创建开始和结束日期小于 DB 的条目。例如,如果有人尝试将条目 2018-01-04 添加到 2018-01-05,它将阻止他们
  • @Shaif 我进行了编辑,使StartDate 可以与UserEndDate 具有相同的值,而EndDate 可以与UserStartDate 具有相同的值,但不能同时满足两者(因为这会导致数据重叠)。
  • 您应该使用.Any() 而不是.ToList().Count&gt;0 之后出于性能原因,但是。这样,在数据库中有很多行的情况下,您不会获得数百万个匹配项。
  • 非常感谢@Sudsy1002。问题已解决。我刚刚添加了另一个检查点,不允许用户在雾凇范围内添加条目。 st.StartDate &lt;= UserStartDate &amp;&amp; st.EndDate &gt;= User.EndDate &amp;&amp; st.Status == "Queued"
  • @Shaif 谢谢你的评论。答案已更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-24
  • 2020-06-17
  • 2022-01-08
  • 1970-01-01
  • 2017-03-20
  • 2016-11-19
相关资源
最近更新 更多