2015-12-02 5 views
0

Предположим, что у меня есть модель под названием Item, которая выглядит следующим образом:Применение Linq к DbSet внутри DbContext

public int ID { get; set; } 
public DateTime DateCreated { get; set; } 
public DateTime? DateArchived { get; set; } 
[Required] 
public string Alias { get; set; } 

Он был включен в DbContext ...

public DbSet<Item> Items { get; set; } 

Всякий раз, когда я хочу выберите все элементы из базы данных, я хочу включить только элементы, где Archived == null и отсортировано по Alias.

Есть ли способ настроить EF для этого, когда вызывается DbSet (например, на DbContext)?

Например, если я вызываю db.Items в контроллере, я всегда хочу, чтобы эти параметры применялись, не указывая их явно.

Мой текущий способ сделать это - переименовать DbSet с префиксом «Все» и добавить функцию с этими параметрами (функция использует исходное имя DbSet, чтобы контроллеры и страницы эскалаторов использовали настраиваемый запрос без каких-либо изменений):

public DbSet<Item> AllItems { get; set; } 
public IQueryable<Item> Items 
{ 
    get { return AllItems.Where(item => item.Archived == null).OrderBy(item => item.Alias); } 
} 

Но что-то об этом методе кажется хакерским/неправильным. Это прекрасный способ сделать это? Как это обычно делается?

+1

Я не думаю, что это взломать или неправильно. Что, если вам по какой-то причине нужны все предметы? – MutantNinjaCodeMonkey

+0

@ Я согласен с @MutantNinjaCodeMonkey. Мне кажется, это прекрасно для меня –

ответ

0

У меня была знакомая проблема один раз, и я создал представление базы данных, чтобы представить свои данные со всеми необходимыми ограничениями. Вид может иметь те же поля, что и таблица, но не требуется. Затем вы создаете другой элемент DbSet, например. DbSet<ItemView>, который в базе данных подходит для просмотра вместо таблицы. Внутри этой точки зрения вы заявляете, где заявление, как вы пожелаете. Если свойства одинаковы, вы также можете создать одного и того же предка для обоих классов (например, Item и ItemView оба наследуются от ItemBase).

У меня это было сделано на MS SQL Server.

0

Я вообще избегаю прямого доступа к DbSet и применяю идею, скрывая контекст за интерфейсом. Затем я получаю доступ только к методам репозитория из интерфейса. Это скрывает DbSets от intelli-sense при использовании его в вашем клиентском коде, если вы предпочитаете, чтобы клиентский код не имел доступа к коллекциям таблиц (и хочет направлять их на некоторые отфильтрованные подмножества данных).

public interface IDataContext : IDisposable 
{ 
    void SaveChanges(); 
    IQueryable<Item> GetItems(); 
} 

public class DataContext : DbContext, IDataContext 
{ 
    public DataContext(string connectionStringName) : base(connectionStringName) { } 

    public DbSet<Item> Items { get; set; } 

    public IQueryable<Item> GetItems() 
    { 
     return Items.Where(item => item.Archived == null).OrderBy(item => item.Alias); 
    } 
} 

using (IDataContext context = new DataContext("myConnection")) 
{ 
    var items = context.GetItems(); 
} 
Смежные вопросы