2010-04-09 2 views
3

Я использую шаблон репозитория с linq для sql, я использую класс репозитория для таблицы. Я хочу знать, я делаю в хорошем/стандартным способом,Linq to sql Образец репозитория, Некоторые вопросы

ContactRepository

Contact GetByID() 
    Contact GetAll() 

COntactTagRepository

List<ContactTag> Get(long contactID) 
List<ContactTag> GetAll() 
List<ContactTagDetail> GetAllDetails() 

class ContactTagDetail 
{ 
    public Contact Contact {get;set;} 
    public ContactTag COntactTag {get;set;} 
} 

Когда мне нужен контакт я называю метод contactrepository, то же самое для contacttag

, но когда мне нужен контакт и теги вместе, я вызываю GetDetais() в репозитории ContactTag, не возвращая объект COntactTag созданный orm, установил возвращаемый объект ContactTagDetail, координирующий как COntact, так и COntactTag, сгенерированные orm, я знаю, что могу просто вызвать GetAll в репозитории COntactTag и получить доступ к Contact.ContactTag, но в качестве его linq для sql он не будет иметь возможности для отложенной нагрузки на уровне запросов, поэтому всякий раз, когда мне нужна сущность со связанным объектом, я создаю класс проецирования

Еще одно сомнение в том, что мне действительно нужно право на метод, который я могу сделать в обоих контактах & ContactTag repostitory как в контактном репозитории GetALlWithTags () или что-то, но я делаю это в репозитории COntactTag

Каковы ваши предложения?

ответ

5

У меня нет времени для подробностей, но в основном нет взаимно-однозначных отношений между таблицами и вашими репозиториями. Я допустил эту ошибку, и она не работает. Вместо этого, у вашего репозитория есть все таблицы, которые связаны концептуально. В вашем случае просто создайте репозиторий Contact, который обрабатывает как Контакты, так и ContactTags (и любые другие связанные таблицы). Нет никакого правила относительно того, что означает «связанный», только вы можете решить, но управляйте своим решением на основе понимания того, как элементы вашего приложения естественно группируются вместе.

также чтение этих двух потоков на SO, что имеют дело с подобным вопросом:

Multiple or Single Repositories with LINQ и How to use the repository pattern correctly?

+0

его хорошо, но когда у меня есть хранилище со многими связанными сторонами, где я буду писать вставки/удаления и т.д. методы, – MindlessProgrammer

+0

вы могли бы поместите их все в один репозиторий, если они связаны как «единица работы». –

-1

Я считаю, что ты на правильном пути. Одна проблема, с которой вы столкнетесь с linq в sql, - это сопоставление от одного к одному с таблицами. Таким образом, вы вынуждены раскрывать вам множество коллизийных столов.

Способ, которым я получил это, - использовать слой данных, который имеет доступ к linq для sql, но возвращает все обратно в объекты POCO перед возвратом вызова.

public IQueryable<ArtGalleryData.Image> GetImagesByImageGroup(int id) 
    { 

     return SqlDataContext.Image_ImageGroups 
      .Where(iig => iig.ImageGroupID == id) 
      .Join(
      SqlDataContext.Images, 
      iig => iig.ImageID, 
      i => i.ImageID, 
      (iig, i) => new ArtGalleryData.Image 
      { ImageID = i.ImageID, 
       Description = i.Description, 
       Title = i.Title, 
       Height = i.Height, 
       Width = i.Width }).AsQueryable(); 
    } 

В основном я сопоставляю объект linq Образ к объекту POCO Изображение. (я знаю, что его вид грязные, но это лучший пример у меня на руки.)

Чтобы получить эффект отсроченной нагрузки вы возвращающий IQueryable <T> объекта. Это позволит вам приостановить выполнение запроса до тех пор, пока вам не понадобится.

Кроме того, для объектов с зависимой коллекции в них я нашел этот большой вспомогательный класс: LazyList это позволяет для отложенной загрузки (отложенное исполнение) коллекций через IQueryable <T>

Большинство из того, что я знаю, что было от чтения Rob Connerys Блог MVC Store Front.

Прочтите его сообщение в блоге и загрузите проект магазина Store. Думаю, он ответит на многие ваши вопросы. Если вы не используете asp.net MVC, просто просматривая его уровень доступа к данным, это будет огромной помощью.

Надежда Это помогает

+1

Rob Connery not Roby Cory –

+0

Ой, спасибо, я обновлю свою запись – Anthony

+0

-1 Не подвергайте эту утечку 'IQueryable '. – jgauffin

1

Это не хранилище образов. Шаблон репозитория в основном создает объект, который абстрагирует упорство, действуя (концептуально) как совокупность всех объектов определенного типа в домене.

Поэтому контакт хранилище может работать что-то вроде этого:

IContacts contacts = GetContactRepository(); 
using(var uow = UnitOfWork.Create()) { 
    var contact1 = contacts.Get(new FindByNameSpecification("Fred")); 
    contact1.LastName = "Rubble"; 
    var contact2 = new Contact("Barney", "Flistone"); 
    contacts.Add(contact2); 
    // both contact1 and contact 2 are implicitly saved at the end of the unit of work 
} 

немного свободнее определение того, как хранилище должно работать может быть что-то вроде этого:

IContactRepository contacts = GetContactRepository(); 
using(var uow = UnitOfWork.Create()) { 
    var contact1 = contacts.GetByName("Fred"); 
    contact1.LastName = "Rubble"; 
    contacts.Save(contact1); 
    var contact2 = new Contact("Barney", "Flistone"); 
    contacts.Save(contact2); 
} //The save is explicit but the commit is implicit 

Что у вас есть a table data gateway.

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

Является ли пометка частью вашего контактного домена или нет? Если это так, то у вас должны быть свойства

public class Contact { 
    public IEnumerable<Tag> Tags { get; } 
    public void TagWith(Tag tag) { .... } 
    public void UnTag(Tag tag) { ... } 
} 

Кроме того, спросите себя, сможете ли вы когда-нибудь добавить тег с нулевыми контактами под ним? Если нет, то это становится еще проще - вам не нужен шлюз для управления тегами на всех, просто дайте вашему объекту контакта справиться с этим

public interface IContactRepository { 
    IEnumerable<Contact> GetAll(); // returns Contacts along with their tags 
    void Save(Contact); // saves Contact along with any tags 
} 

Кстати, если пометка не является частью домена (как в нем это беспокойство приложение), то вы должны иметь отдельную службу, возможно, даже в отдельном проекте

public interface IAssociateTags { 
    IEnumerable<Tag> GetTagFor(Contact contact); 
    void TagContact(Contact contact, Tag tag); 
    void UnTagContact(Contact contact, Tag tag); 
} 
Смежные вопросы