Добавяне на клауза where по подразбиране към таблица linq-to-sql

Възможно ли е да се добави клауза where по подразбиране към всеки SQL израз, генериран от клас Linq-to-SQL?

Имам персонализиран DataContext с клас Customer. Класът Customer има атрибут Deleted, което искам винаги да бъде NULL, когато правя заявка към таблицата.

Така например мога да напиша:

List<Customer> customers = db.Customers.ToList<Customer>();

Но наистина вземете:

List<Customer> customers = db.Customers.Where(o => o.Deleted == null).ToList<Customer>();

Искам да поддържам "изтритите" данни в моята база данни, но никога няма да има нужда да ги виждам в моя .NET код. Този вид настройка по подразбиране би била удобна, така че не е нужно да помня да добавям филтъра към всяка заявка.


person Paul    schedule 21.09.2012    source източник
comment
Вместо да добавяте таблицата към вашия dbml дизайнер, добавете изглед, който съдържа клаузата where по подразбиране, и просто наименувайте изгледа Customer във вашия dbml.   -  person hatchet - done with SOverflow    schedule 21.09.2012
comment
виж отговора, който добавих. Включих информация за актуализации.   -  person hatchet - done with SOverflow    schedule 22.09.2012


Отговори (2)


Вместо да добавяте таблицата към вашия dbml дизайнер, добавете изглед, който съдържа клаузата where по подразбиране, и просто наименувайте изгледа Customer във вашия dbml.

За да позволите актуализации, вмъквания и изтривания, уверете се, че сте избрали колоните с първичен ключ във вашия DBML дизайнер и маркирайте тяхното свойство Primary Key като true.

person hatchet - done with SOverflow    schedule 21.09.2012
comment
След още малко тестване всъщност мога да правя вмъквания и актуализации съвсем добре, освен когато се опитвам да актуализирам полето Изтрито. Получавам ChangeConflictException - Row not found or changed., когато се обадя на SubmitChanges(). Предполагам, че това се дължи на факта, че търси изгледа, който не съдържа този запис, тъй като Deleted вече не е null в съзнанието на моя DataContext. - person Paul; 22.09.2012
comment
Открих проблема. Трябваше да променя изчислените си колони от AutoSync=Винаги на AutoSync=Никога. - person Paul; 22.09.2012

Можете да добавите ново свойство, наречено ActiveCustomers, което връща това:

public IQueryable<Customer> ActiveCustomers {
    get { return db.Customers.Where(e => e.Deleted == null); }
}

Всякакви заявки срещу това свойство могат да указват допълнителни Where условия и по друг начин да променят резултатите, но те винаги ще започват с клиенти, които не са били изтрити. И поради отложеното изпълнение на LINQ, този оператор не предизвиква изпълнение на допълнителни заявки.

Ако трябва да се уверите, че никой няма достъп до db.Customers, можете да опитате да го скриете, като направите нещо подобно (може да не работи, трябва да видя вашето внедряване):

public new IQueryable<Customer> Customers {
    get {
      throw new InvalidOperationException("Use property ActiveCustomers instead.");
    }
}
person Yuck    schedule 21.09.2012
comment
Проблемът с това решение е, че когато създавам new IQueryable<Customer> Customers, получавам грешка при неяснота между това и оригиналните клиенти, които връщат System.Linq.Table<Customer>. Но не мога да премахна оригинала, защото тогава моите извиквания на InsertOnSubmit се провалят, тъй като се опитва да изпълни това срещу IQueryable. - person Paul; 21.09.2012
comment
@Paul Ако използвате имплементация на модела на хранилището, така или иначе не трябва да правите заявки директно срещу контекст. - person Yuck; 22.09.2012