Няколко забележки и моите мнения:
1)
Трябва ли да имам само идентификатора на категорията в продуктовия клас и да използвам отделно хранилище за продуктови категории, за да заредя категорията?
Не. Използвате ORM (поне предполагам, че го правите), за да можете да моделирате връзки чрез препратки между екземпляри на класове, а не чрез идентификатори, които използвате след това, за да правите заявки по релационен начин. Пренасянето на идеята ви до последното следствие би означавало, че премахвате всички навигационни свойства изобщо от класовете на модела и имате само скаларни свойства и някои от тях действат като ключове между обекти. Това е само "R" в ORM.
2)
Засега моята реализация на интерфейса на хранилището връща обект от тип, който разширява типа продукт и има поддръжка за отложено зареждане през екземпляра на хранилището.
Не съм сигурен какво точно означава това. (Бих искал да видя кодов фрагмент как да направите това.) Но моето предположение е, че във вашия извлечен Product
клас инжектирате по някакъв начин препратка към хранилището, като така:
public class ProductProxy : Product
{
private IProductRepository _productRepo;
public ProductProxy(IProductRepository productRepo)
{
_productRepo = productRepo;
}
// now you use _productRepo to lazily load something on request, do you?
}
Е, очевидно сега е проблем да се заредят категориите, тъй като IProductRepository
няма методи за достъп до тях.
3)
Интересувам се как трябва да си взаимодействат хранилищата за продукти и категории, за да се постигне мързеливото зареждане? Трябва ли да се препращат един към друг, или трябва да имам основно хранилище с двете подхранилища и да предам това на моите типове разширени модели?
Вашето ProductRepository и CategoryRepository изглеждат като екземпляри на общо хранилище, което отговаря само за един тип обект (в EF 4.1 това би било подобно на DbSet<T>
, където T
е Product
или Category
съответно).
Бих избягвал да има препратки между тези хранилища, тъй като това може да доведе до адски сложни репо-препратки всеки път, когато добавяте нови обекти или свойства за навигация.
Виждам още два варианта:
(По принцип това, което вече споменахте) Наличие на хранилище, което отговаря за Product
и Category
заедно. Все още можете да имате вашите общи хранилища, но бих ги разглеждал повече като вътрешни помощни хранилища и бих ги използвал само като частни членове вътре в основното хранилище. По този начин можете да имате група от хранилища, всяко от които отговаря за някои тясно свързани обекти.
Въведете Unit of Work
, който е в състояние да създаде всичките ви общи хранилища (отново в EF 4.1 това би било нещо като фабричния метод DbContext.Set<T>()
, където DbContext
е работната единица) и след това инжектирайте тази единица работа във вашите извлечени екземпляри:
public class ProductProxy : Product
{
private IUnitOfWork _unitOfWork;
public ProductProxy(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public Category Category
{
get
{
// ...
var productRepo = _unitOfWork.CreateGenericRepo<Product>();
var categoryRepo = _unitOfWork.CreateGenericRepo<Category>();
// you can pull out the repos you need and work with them
}
set { ... }
}
}
Бих предпочел втория вариант, защото при първия може да се окажете в огромни хранилища, за да поддържате зареждането на всички възможни връзки. Помислете за: Поръчката има артикули за поръчка, артикулът за поръчка има продукт, продуктът има категория, поръчката има клиент, клиентът има списък с адреси, адресът има списък с лица за контакт и така нататък, и така нататък...
4) (защото вие също поискахте критика)
Пишете ли свой собствен ORM или пишете приложение? Вашият дизайн отива в посока, която може да стане много сложна и вие преоткривате колелото според мен. Ако планирате да използвате EF или NHibernate (или други ORM), тогава вие създавате функции, които вече са налични извън кутията, вие само поставяте абстракции върху тях, които не добавят стойност. Мързеливото зареждане чрез динамични проксита се случва прозрачно в смисъл, че никога не работите изрично с тези проксита във вашия код, вие винаги работите с вашите POCO обекти. Те са невидими и съществуват само по време на изпълнение. Защо искате да разработите своя собствена инфраструктура за мързеливо зареждане?
person
Slauma
schedule
10.05.2011