Как сделать общий репозиторий? - PullRequest
4 голосов
/ 27 марта 2010

Мне интересно, есть ли у кого-нибудь хорошие уроки (или, может быть, даже библиотека, которая уже создана и хорошо документирована) по созданию общего репозитория.

В настоящее время я использую linq to sql, но он может измениться, поэтому я не знаю, сможете ли вы создать общий репозиторий, который не потребовал бы особых изменений, если бы я сказал, переключиться на платформу сущностей.

Спасибо

Думаю, мне следует добавить, почему я хочу общий репозиторий. Причина в моей базе данных: корпоративные таблицы (пользователи, чьи подписки оплачиваются кем-то другим) и отдельные таблицы (люди, которые находят мой сайт через Google или где-либо еще и оплачивают собственную подписку)

Но у меня будет 2 очень похожих таблицы. Например, у меня есть две таблицы настроек: одна для корпоративных пользователей и одна для физических лиц.

Теперь, так как это две разные таблицы, мне нужны два разных метода вставки, так как я вставляю их в две разные таблицы, и в настоящее время отличается только одно поле (это PK).

Так что теперь мне нужны все эти дублирующие методы, а я этого не хочу. Может быть, то, что у меня есть в моей базе данных, может рассматриваться как недостаток дизайна (и, возможно, так оно и есть), но одной из причин этого было, в случае необходимости, то, что я могу легко разбить свою базу данных на 2 разные базы данных, и я не собираюсь менять мой дизайн в ближайшее время.

Ответы [ 2 ]

2 голосов
/ 27 марта 2010

Вот мой ответ на другой вопрос того же типа. Надеюсь, это поможет:

Преимущество создания общего хранилища по сравнению с конкретным хранилищем для каждого объекта?

Редактировать:

Похоже, вы хотите рассматривать два конкретных типа как один логический тип. Для этого сначала определите логический тип:

public interface ISubscription
{
    // ...
}

Затем определите конкретные типы как часть вашей модели данных (интерфейсы будут реализованы в другом частичном классе):

[Table("CorporateSubscription")]
public partial class CorporateSubscription : ISubscription
{

}

[Table("IndividualSubscription")]
public partial class IndividualSubscription : ISubscription
{

}

Затем определите хранилище, которое работает с логическим типом:

public interface ISubscriptionRepository
{
    CorporateSubscription GetCorporate(string key);

    IndividualSubscription GetIndividual(int userId);

    IEnumerable<ISubscription> ListAll();

    IEnumerable<CorporateSubscription> ListCorporate();

    IEnumerable<IndividualSubscription> ListIndividual();

    void Insert(ISubscription subscription);
}

Наконец, реализуйте интерфейс, используя обе таблицы:

public class SubscriptionRepository : ISubscriptionRepository
{
    private readonly YourDataContext _dataContext;

    public SubscriptionRepository(YourDataContext dataContext)
    {
        _dataContext = dataContext;
    }

    #region ISubscriptionRepository

    public CorporateSubscription GetCorporate(string key)
    {
        return _dataContext.CorporateSubscriptions.Where(c => c.Key == key).FirstOrDefault();
    }

    public IndividualSubscription GetIndividual(int userId)
    {
        return _dataContext.IndividualSubscriptions.Where(i => i.UserId == userId).FirstOrDefault();
    }

    public IEnumerable<ISubscription> ListAll()
    {
        return ListCorporate()
            .Cast<ISubscription>()
            .Concat(ListIndividual().Cast<ISubscription>());
    }

    public IEnumerable<CorporateSubscription> ListCorporate()
    {
        return _dataContext.CorporateSubscriptions;
    }

    public IEnumerable<IndividualSubscription> ListIndividual()
    {
        return _dataContext.IndividualSubscriptions;
    }

    public void Insert(ISubscription subscription)
    {
        if(subscription is CorporateSubscription)
        {
            _dataContext.CorporateSubscriptions.InsertOnCommit((CorporateSubscription) subscription);
        }
        else if(subscription is IndividualSubscription)
        {
            _dataContext.IndividualSubscriptions.InsertOnCommit((IndividualSubscription) subscription);
        }
        else
        {
            // Forgive me, Liskov
            throw new ArgumentException(
                "Only corporate and individual subscriptions are supported",
                "subscription");
        }
    }
    #endregion
}

Вот пример вставки. Не зацикливайтесь на классе докладчика; Мне просто нужна была ситуация, когда подписки будут создаваться на основе флага:

public class CreateSubscriptionPresenter
{
    private readonly ICreateSubscriptionView _view;
    private readonly ISubscriptionRepository _subscriptions;

    public CreateSubscriptionPresenter(
        ICreateSubscriptionView view,
        ISubscriptionRepository subscriptions)
    {
        _view = view;
        _subscriptions = subscriptions;
    }

    public void Submit()
    {
        ISubscription subscription;

        if(_view.IsCorporate)
        {
            subscription = new CorporateSubscription();
        }
        else
        {
            subscription = new IndividualSubscription();
        }

        subscription.Notes = _view.Notes;

        _subscriptions.Insert(subscription);
    }
}
1 голос
/ 27 марта 2010

Великие ресурсы Linq to Sql:

Шаблон t4, который генерирует именно то, что создается по умолчанию, но может быть полностью настроен.

http://l2st4.codeplex.com/

Использование Linq to Sql для многоуровневого приложения. У него есть GenericObjectDataSource, который я нашел очень удобным

http://multitierlinqtosql.codeplex.com

Поиск всех свойств IQueryable одним поиском

http://naspinski.codeplex.com/

...