Как использовать функцию sql (coalesce или isnull) в Simple.Data - PullRequest
3 голосов
/ 23 февраля 2012

Я портирую SQL-запрос на Simple.Data, оригинальный запрос выглядит примерно так:

select a.Field1, a.Field2, b.Field1
from TableA a
join TableB b ON a.KeyField = b.KeyField
where coalesce(b.SomeDate, '1/1/1900') <= getdate()

Я смог портировать все в запросе, кроме этой проклятой логики объединения:

var currentDate = DateTime.Now;
var result = db.TableA.Query()
    .Join(db.TableB).On(db.TableA.KeyField == db.TableB.KeyField &&
        db.TableB.SomeDate == currentDate)
    .Select(db.TableA.Field1, db.TableA.Field2, db.TableB.Field1);

Есть какие-нибудь мысли о том, как добиться такого поведения?Я пытался использовать оператор ?? безрезультатно.

Заранее спасибо!

Ответы [ 3 ]

10 голосов
/ 27 февраля 2012

Когда есть функция SQL, которая принимает имя столбца в качестве первого параметра, вы можете указать его как метод для столбца:

var currentDate = DateTime.Now;
var defaultDate = new DateTime(1900,1,1);
var result = db.TableA.Query()
    .Join(db.TableB).On(db.TableA.KeyField == db.TableB.KeyField &&
        db.TableB.SomeDate.Coalesce(defaultDate) <= currentDate)
    .Select(db.TableA.Field1, db.TableA.Field2, db.TableB.Field1);

Обратите внимание, что если вы установили ссылочную целостность между таблицей Aи TableB, вы можете опустить явное объединение и упростить этот запрос до:

var currentDate = DateTime.Now;
var defaultDate = new DateTime(1900,1,1);
var result = db.TableA
    .Query(db.TableA.TableB.SomeDate.Coalesce(defaultDate) <= currentDate)
    .Select(db.TableA.Field1, db.TableA.Field2, db.TableB.Field1);
1 голос
/ 23 февраля 2012

Я никогда не использовал Simple.Data раньше, но я думаю, что вы хотите сделать это:

var currentDate = DateTime.Now;
var nullDate = new DateTime(1900, 1, 1);
var result = db.TableA.Query()
    .Join(db.TableB).On(db.TableA.KeyField == db.TableB.KeyField &&
        ((!Object.ReferenceEquals(null, db.TableB.SomeDate) ? db.TableB.SomeDate : nullDate) <= currentDate)
    .Select(db.TableA.Field1, db.TableA.Field2, db.TableB.Field1);

Или выведите его из объединения:

var currentDate = DateTime.Now;
var nullDate = new DateTime(1900, 1, 1);
var result = db.TableA.Query()
    .Join(db.TableB).On(db.TableA.KeyField == db.TableB.KeyField)
    .Where((!Object.ReferenceEquals(null, db.TableB.SomeDate) ? db.TableB.SomeDate : nullDate) <= currentDate)
    .Select(db.TableA.Field1, db.TableA.Field2, db.TableB.Field1);

Какой тип данных для db.TableB.SomeDate? Если Simple.Data генерирует его как обнуляемый тип данных (Nullable<DateTime>), тогда вы можете сделать:

db.TableB.SomeDate.GetValueOrDefault(nullDate) <= currentDate
0 голосов
/ 24 февраля 2012

Coalesce здесь совершенно бесполезен.

where coalesce(b.SomeDate, '1/1/1900') <= getdate()

Это, по сути, означает, что если b.SomeDate имеет значение null, вернуть true, поскольку getdate () никогда не будет <= 1/1/1900.Вы можете заменить вышеперечисленное этим .... </p>

where (b.SomeDate is null) or (b.SomeDate <= getdate())

это может немного упростить это ...

...