Выявление столкновений дат с помощью linq

#c# #asp.net #linq #asp.net-mvc-3 #entity-framework

#c# #asp.net #linq #asp.net-mvc-3 #entity-framework

Вопрос:

Я ищу, чтобы идентифицировать строки с помощью linq, где есть столкновение дат. У меня есть (для этого примера) 5 столбцов

 ID   ref_id   ref_Name   Borrow_Date  Return_Date
1    1343     Gate       13/09/2011   20/09/2011
2    1352     Door       20/09/2011   22/09/2011
3    1343     Gate       17/09/2011   21/09/2011
  

В этом случае мои «Ворота» сталкиваются, потому что кто-то хочет позаимствовать его, когда кто-то другой также хочет его позаимствовать.

Есть ли способ легко идентифицировать столкновения диапазонов дат с помощью linq?

Ответ №1:

Один из способов может быть таким. Хотя там могут быть более производительные варианты:

 var collisions = myList.Where( d1 => !myList.Where( d => d != d1).All( d2 =>  d1.Return_Date <= d2.Borrow_Date|| d1.Borrow_Date >= d2.Return_Date));
  

Это вернет все строки, которые перекрываются хотя бы с одной другой строкой. В приведенном выше случае он вернет все три из них, поскольку строка с идентификатором 3 перекрывает как 1, так и 2. Если вы измените 1 на Return_Date 17/09/2011, он вернет только 2 и 3.

Ответ №2:

Если у вас есть список объектов со свойствами, показанными в вашей таблице, вы можете найти книги с тем же названием, которые имеют противоречивые даты, используя что-то вроде этого:

(Не тестировал этот код, поэтому могут быть некоторые ошибки с опечатками.)

 var collisions = collection
                .Join(collection, x => x.ref_Name, y => y.ref_Name, 
                                (x, y) => new {
                                                ID_x = x.ID, 
                                                ID_y = y.ID, 
                                                ref_id = x.ref_id, 
                                                ref_Name = x.ref_Name, 
                                                Borrow_Date_x = x.Borrow_Date, 
                                                Borrow_Date_y = y.Borrow_Date, 
                                                Return_Date_x = x.Return_Date, 
                                                Return_Date_y = y.Return_Date
                                                }
                        )
                .Where( z => (z.Return_Date_x > z.Borrow_Date_y amp;amp; z.Borrow_Date_x < z.Return_Date_y))
                .Where( z => z.ID_x != z.ID_y);
  

Вероятно, вы получите дубликаты результатов. (т.Е. ID 1 и 3, а также ID 3 и 1)

Ответ №3:

Хотя, безусловно, можно идентифицировать эти столкновения в базе данных после их возникновения, не было бы лучше запретить второму пользователю заимствовать элемент, когда его уже планируется заимствовать. В этом случае это было бы простым вопросом тестирования, чтобы убедиться, что никакие существующие строки с ref_id 1343 не имеют даты возврата, равной или превышающей новую запрошенную дату заимствования.