Как использовать общий параметр WHERE для всех моделей в EF от LINQ? - PullRequest
1 голос
/ 26 октября 2011

Система имеет несколько классов моделей (например, задачи, счета, отчеты).Для каждой таблицы в зависимости от зарегистрированной компании по какому-либо параметру (например, companyID).И я должен следить за этим параметром для каждой таблицы, каждого запроса, каждого сохранения и т. Д.Есть ли более простой способ сообщить EF LINQ, чтобы каждый запрос добавлял этот параметр?Другими словами, если я введу только:

List<Report> list = db.Reports;

, которые были выбраны только соответствующие записи с идентификатором компании зарегистрированной компании, например

List<Report> list = db.Reports.Where(r => r.companyID = idOfLoggedComp)

Большое спасибо за ответ.

Ответы [ 4 ]

0 голосов
/ 27 октября 2011

Не уверен, поможет ли это вам.Вы можете сделать что-то вроде этого.

string whereClause = "";

if(cId > 0)
{
whereClause += "it.companyID =@companyID && "

ob.Add(New ObjectParameter("companyID", cId));

}

// Вы можете добавить другие параметры, используя больше, если условия ..

whereClause  = whereClause.Remove(whereClause.Length, -3);

qry = dEntity.Reports.Where(whereClause, ob.ToArray);
0 голосов
/ 27 октября 2011

Простой ответ - нет.EF полностью отсутствует глобальные фильтры.Вы должны создать некоторый класс-обертку и скрыть запрос внутри пользовательского доступа IQueryable, например:

public class CompanyRestrictedDataAccess
{
    private int _companyId;
    private ObjectContext _context;

    public CompanyDataAccess(int companyId, ObjectContext context)
    {
        _companyId = companyId;
        _context = context;
    }

    public IQueryable<Reports> Reports
    {
        get
        {
            return _context.Reports.Where(r => r.CompanyId == _companyId); 
        }
    }
}

Но это все еще очень плохой обходной путь, потому что:

  • Этот класс необходимо использоватьдля запросов вместо контекста
  • Работает только для прямого доступа.Готовая загрузка и отложенная загрузка полностью игнорируют любые условия (готовая и отложенная загрузка в EF даже не может быть отфильтрована).

Поэтому вы должны правильно обрабатывать загрузку в приложении.

Единственное единственноеРешение, предоставляемое EF, называется условным отображением, но это жестко закодированное условие одиночной фильтрации непосредственно в EDMX, поэтому ваше приложение будет работать только для одной компании.

0 голосов
/ 27 октября 2011

EF не поддерживает это по умолчанию, но есть некоторые шаблоны проектирования, которые могут помочь.

Особенно шаблон Criteria в сочетании с хранилищем. Эта статья хороша для чтения.

В ней объясняется, как создавать критерии и комбинировать их (с помощью шаблона декоратора).Если бы вы добавили свой фильтр к классу базовых критериев, вы могли бы убедиться, что он добавлен ко всем запросам.

Фильтрация Включенные навигационные данные намного сложнее, как указал Ладислав.Вы можете использовать Expression Visitor, чтобы изменить свой запрос, или использовать базовый класс Criteria для выполнения фильтра Linq To Objects (что проще в реализации), но это означает, что вы будете загружать данные из базы данных.

0 голосов
/ 27 октября 2011

Если в ваших таблицах есть FK, указывающие на поле идентификатора в таблице компании, тогда вы сможете фильтровать все связанные таблицы, просто обращаясь к ним через вашу таблицу «компании» в контексте, например:

List<Report> list = db.Company.Reports;

Без особых хлопот.

Или, если у вас еще нет компании в контексте:

var company = db.FirstOrDefault( c => c.ID == companyId );
List<Report> list = company.Reports;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...