Вопрос

Я пытаюсь реализовать аутентификацию и авторизацию пользователя, используя таблицу ролей, таблицу пользователей и таблицу внешних ссылок, имеющую идентификатор пользователя, идентификатор роли.

Для реализации общего репозитория для обновления роли, вставки роли, добавления пользователя, добавления пользователя в роль, обновления пользователя, обновления роли пользователя, аутентификации пользователя, добавления сеанса пользователя для аудита и т. д. нужно ли мне писать отдельные функции для каждого или я могу использовать один общий метод для подобных функций.Существуют и другие операции, такие как присоединение пользователя к другой таблице и получение 5 верхних строк в зависимости от условий, вставка в 3 таблицы (объединенные по ключу) с использованием единой формы и т. д.

Я сбит с толку, читая множество статей и примеров, образцы bcos, которые я вижу, не подлежат глубокой реализации, за исключением операций CRUD.

Может ли кто-нибудь помочь мне или направить меня к хорошему образцу/статье?

Это было полезно?

Решение

Прежде всего, следуйте тому, что сказал Фрэнк Швитерман.Позвольте вашим репозиториям расти по мере роста их использования.Кроме того, изучите и используйте интерфейсы IQueryable.L2S, а также Entity Framework, LINQ to nHibernate и некоторые новые ORM, такие как SubSonic и Telerik ORM, поддерживают интерфейс IQueryable.

В тех случаях, когда вам нужны изменяемые запросы из вашего репозитория, но вы все равно хотите воспользоваться возможностью замены преобразователей OR, если это необходимо, IQueryable является мощным инструментом.Предположим что-то вроде следующего:

public class ProductRepository: IProductRepository
{
    public Product GetByID(int id);
    public IList<Product> GetAll();
    public void Insert(Product product);
    public Product Update(Product product);
    public void Delete(Product product);
}

Это довольно распространенный репозиторий с простыми общими методами.Со временем у вас может появиться еще несколько методов:

public IList<Product> GetByOrder(Order order);
public IList<Product> GetByCategory(Category category);
public IList<Product> GetByQuantityInStock(int quantityInStock);

Это также довольно распространено и вполне приемлемо в зависимости от вашего подхода к проблеме.Однако в долгосрочной перспективе ваш репозиторий может вырасти до громоздких размеров, а его интерфейс будет постоянно меняться.Вы также теряете реальную выгоду от использования сопоставителя OR за кулисами.

Вы можете сохранить исходный простой интерфейс репозитория, но при этом обеспечить себе большую гибкость, если измените один метод:

public IQueryable<Product> GetAll();

Теперь ваш репозиторий возвращает запрос, а не список уже полученных объектов.Теперь вы можете использовать этот запрос, как и любой другой объект с поддержкой LINQ:

var productsWithLowStock = productRepository.GetAll().Where(p => p.Quantity < 10);

var orders = orderRepository.GetAll();
var productsWithOrders = productRepository.GetAll().Where(p => orders.OrderLines.Any(ol => ol.ProductID == p.ProductID));

Как только вы начнете использовать интерфейс IQueryable со своими репозиториями, вы получите лучшее из обоих миров:Имитационная абстракция вокруг доступа к данным нижнего уровня, а также возможности динамических запросов в вашем коде.Вы можете пойти дальше и создать базовый класс Repository, который реализует сам IQueryable, что позволит вам исключить необходимость вызова GetAll() и просто напрямую запрашивать репозиторий (хотя и с другой степенью сложности).

Другие советы

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

linq2sql — это реализация шаблона ActiveRecord, который является своего рода антишаблоном, поэтому, если вы хотите использовать шаблон репозитория, вам не следует использовать linq2sql, а что-то другое, где возможно разделение задач (отдельный класс для сущности и отдельный класс для доступа к данным). )

или, возможно, можно как-то, я не знаю об этом :D

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top