On Service Layer how to return couple entity from repository which is responsible of one entity - entity-framework

if i know correct each Repository is on Entity
I have and ProductService then i need to get current product's images ,
there is not some repository for Images.
And my Product repositoy is responsible of product Entity.
Repository just return to us Entity objects because repositories should be unaware from DTO objects if i know correct.
So briefly How can i return Images entity. How should i get current selected product Images.
Between product and Images Foreign Key .
But product can have 10.000 Image row in database.
I need IQueryable data of them 10 by 10.
I tried Product.Images bla bla.. .but it didnt satisfied me.
Or should i create a new ImageRepository and inject it to Product service.
Then use it with filtered method which inside in BaseRepository.
How can i design it ?

Leave the product repository alone. You can change your service layer to accept interfaces instead of a BaseRepository. That interface could deal with either EF or some other type (not strictly EF\ORM repository). There are refactoring tools that can help with this by generating the interface from the existing BaseRepository (ex. ReSharper).

Related

EF relationships when adding to database

I have a question about relationships in Entity Framework when adding to database.
I have the following layers
Web app
Service layer
Repository
Data layer
Lets say i have these entities
Course
Department
These entities reference each other.
In my service layer I get the course entity and the department entity.
Then I do something like:
Course.Department = department;
Unitofwork.CourseSet.Add(Course);
Unitofwork.SaveChanges();
My question is then:
Do I also need to add the department entity to the context?
Because even if I dont add the department to the DepartmentSet it is still beeing added to the database.
Is there some kind og rule about when to add to the context and when its not necesary
Hope someone can help
You don't need to add related entities separately since EF is able to detect that automatically.
Also, even if you do add it separately, it will have no effect since the related entity is (internally) already attached to the Context and its state is already set to 'Added'.
The 'rule' you're looking for is very simple: if it's not part of the 'root' entity, you'll have to add it separately.
P.S: This is all true for Insert/Add scenario. Update/Edit scenario (from detached entity) is more complicated and changes to related entities usually aren't detected.

Domain driven design: overriding virtual methods in Domain classes

My application is broken down into several assemblies.
The MyProject.Infrastructure assembly contains all of the Domain objects such as Person and Sale as well as interfaces repositories such as IPersonRepository and ISaleRepository.
The MyProject.Data assembly contains concrete implementations of these repositories.
The repositories pull data from a database and instantiate new domain classes. For example, IPersonRepository.GetPersonByNumber(customerNumber) will read a customer from the data source, create a new Person class, populate it and return to the caller.
I'm now starting to see cases where adding some methods to my Domain classes might make sense, such as Person.UpdateAddress(address).
Is it ok to put this method on my Person class as a virtual method, and then create derived classes inside my Data layer which override those methods to provide the desired functionality?
I want to make sure I'm not going breaking any DDD conventions.
I know I also have the option of putting these methods on the repository - e.g. IPersonRepository.UpdatePersonAddress(person, address).
Person.UpdateAddress should definitely be in your domain, not in your Repository. UpdateAddress is logic and you should try to avoid logic inside your repository. If you're working with Entity framework there is no need for 'data classes'.
Most ORMs have change trackers which will persist related entities automatically when you persist the main one (provided you declared the right relations in the mapping configuration), so you don't need UpdatePersonAddress() on your Repository. Just do whatever you want to do at the object level in Person.UpdateAddress(address) without thinking about persistence, this is not the place for that.
What you need though is an object that will be called in execution context-aware code to flush changes to the persistent store when you think it's time to save these changes. It might be a Unit of Work that contains the Entity Framework DbContext, for instance.

wcf data service with Entity Framework

I am trying to create WCF Data service project using Entity Framework. ( I am new to both).
I created entities using DB.
Now, I created service operation, which returns the IQueryable<entity>.
My problem is
I do not want to return the entire set of columns in the entity. I cannot delete them from the entity as it is not null. How to avoid these?
I have few FK columns and I need other column details of the table. How to include columns from other table?
Why it is not possible to use POCO class to be returned from WCF Data service?
How do I format the response; i.e., add few more details to the response like page number etc, change the xml tags, remove few details like "link rel"?
I have tried a lot of things to achieve 1 and 2. But finally I realised that I can only use the entity as it is to make it work.
I have no idea about 4.
Any suggestions would be appreciated.
1. I do not want to return the entire set of columns in the entity.
2. I have few FK columns and I need other column details of the
table.
For this, you should define a new class that matches what you need / what you want your clients to see. That can be a straight POCO class - no special requirements. Assemble that class for each entity, leaving out the unwanted columns, and grabbing the extra field or two for the FK columns into that new class. Return an IQueryable<YourNewClass> instead of the entity class directly.
To avoid huge left-right-assignment statements just to fill the properties of the new class, you should have a look at AutoMapper which makes it really easy to copy around classes that are very similar to one another (e.g. missing or adding a few properties).
4. How do I format the response; i.e., add few more details to the
response like page number etc, change the xml tags, remove few details
like "link rel"?
That's not possible - the OData protocol very strictly defines what's going to be in the message, what links there are etc. If you can't live with that - you'll have to roll your own WCF REST service and drop the WCF Data Service stuff altogether.
Check out the WCF REST Developer Center on MSDN if you want to investigate that route more thoroughly.
Update: that link seems to have gone dead - try WCF Web Http Programming Overview instead.
Make sure you have an Id property or you specify either [Key] or [DataServiceKey("Your_Custom_ID_Property")]
For me this sorted out the issue

Entity Framework Service Layer Update POCO

I am using the Service Layer --> Repository --> Entity Framework (Code-First) w/POCO objects approach, and I am having a hard time with updating entities.
I am using AutoMapper to map my Domain Objects to my View Models and that works good for getting the data, no how do I get that changes back into the database?
Using pure POCO objects, I would assume that there is no sort of change tracking, so I see my only option is to handle it myself. Do you just make sure that your View Models have the EXACT same properties as your Domain Objects? What if I just change a field or two on the View Model? Won't the rest of the fields on the Domain Object get overwritten in the database with default values?
With that said, what is the best approach?
Thanks!
Edit
So what I am stumbling on is this, lets take for example a simple Customer:
1) The Controller has a service, CustomerService, that calls the services GetCustmoerByID method.
2) The Service calls into the CustomerRepository and retrieves the Customer object.
3) Controller uses AutoMapper to map the Customer to the ViewModel.
4) Controller hands the model to the View. Everything is great!
Now in the view you do some modifications of the customer and post it back to the controller to persist the changes to the database.
I would assume at this point the object is detached. So should the model have the EXACT same properties as the Customer object? And do you have to make hidden fields for each item that you do not want to show, so they can persist back?
How do you handle saving the object back to the database? What happens if your view/model only deals with a couple of the fields on the object?
If you're using EF Code First, i.e: the DbContext API, then you still do have change tracking which is taken care of by your context class.
after making changes to your objects, all you have to do is call SaveChanges() on your context and that will persist the changes to your database.
EDIT:
Since you are creating a "copy" of the entity using AutoMapper, then it's no longer attached to your context.
I guess what you could do is something similar to what you would in ASP.NET MVC (with UpdateModel). You can get the original entity from your context, take your ViewModel (which may contain changed properties) and update the old entity, either manually (just modified properties), or using AutoMapper. And then persist the changes using context.SaveChanges().
Another solution would be to send the model entity as [part of] the ViewModel. This way, you'll have your entity attached to the container and change tracking will still work.
Hope this helps :)
You are absolutely right that with a detached object you are responsible for informing the context about changes in your detached entity.
The basic approach is just set the entity as modified. This works for scalar and complex properties but it doesn't work for navigation properties (except FK relations) - for further reading about problems with navigation properties check this answer (it is related to EFv4 and ObjectContext API but same problems are with DbContext API). The disadvantage of this approach is that all fields in DB will be modified. If you just want to modify single field you still have to correctly fill others or your database record will be corrupted.
There is a way to explicitly define which fields have changed. You will set the modified state per property instead of whole entity. It is little bit harder to solve this on generic approach but I tried to show some way for EFv4 and for EFv4.1.
I agree with #AbdouMoumen that it's much simpler to use the model entities at the view level. The service layer should provide an API to persist those entities in the data store (db). The service layer shouldn't dumbly duplicate the repository lawyer (ie: Save(entity) for every entity) but rather provide a high level save for an aggregate of entities. For instance, you could have a Save(order) in the service layer which results in updating more basic entities like inventory, customer, account.

ASP.NET MVC - I think I am going about this wrong

Or I don't understand this at all.
I have started my ASP.NET MVC application using the Controller --> ViewModel --> Service --> Repository pattern.
Does every type of object (Customer, Product, Category, Invoice, etc..) need to have it's own repository and service? If so, how do you bring common items together?
I mean there are a lot of the times when a few of these things will be displayed on the same page. So I am not getting this I don't think.
So I was thinking I need a ShopController, which has a ShopViewModel, which could have categories, sub categoires, products, etc. But the problem, for me, is that it just does not seem to mesh well.
Maybe ASP.NET WebForms were for people like me :)
Edit
So would an aggregate consist of say:
Category, SubCategory, Product, ChildProduct, ProductReview with the Product being the aggregate root?
Then in the ViewModels, you would access the Product to get at it's child products, reviews, etc.
I am using entity framework 4, so how would you implement lazy loading using the repository/service pattern?
Does every type of object (Customer,
Product, Category, Invoice, etc..)
need to have it's own repository
You should have a repository per aggregate root in your domain. See this question for more information on what is an aggregate root.
In the example you give I could see a CustomerReposiotry which would handle retrieve all pertinent customer data(Customer has orders a order has a customer). A ProductRepository that handles retrieving product information.
and service? If so, how do you bring
common items together?
A service layer is nice but only if there is added value in adding this layer. If your service simply passes straight into the repository it might not be needed. However if you need to perform certain business logic on a Product a ProductService might make sense.
This might not make sense
public void UpdateProduct(Product product)
{
_repo.Update(product);
}
But if you have logic this layer makes sense to encapsulate your business rules for products.
public void UpdateProduct(Product productToUpdate)
{
//Perform some sort of business on the productToUpdate, raise domain events, ....
_repo.Update(productToUpdate);
}
So I was thinking I need a
ShopController, which has a
ShopViewModel, which could have
categories, sub categoires, products,
etc. But the problem, for me, is that
it just does not seem to mesh well.
If the domain is flushed out the view model ends up making sense
public ActionResult Index()
{
ShopViewModel shopViewModel = new ShopViewModel();
shopViewModel.Products = _productRepo.GetAll();
//other stuff on the view model.
return(shopViewModel);
}
Update
What happens when you also need to
provide data unobtainable from an
aggregate root? For example, say I
have a create Customer view and in
that view, I also need to provide the
user with a collection of Companies to
choose from to associate a new
customer with. Does the collection of
Companies come from CustomerRepository
or would you also need a
CompanyRepository?
If a Company can live by itself (e.g. you edit, update, delete a company) I would suggest a Company is also an aggregate root for your domain (A Customer has a company and a company has a list of Customers). However if a Company is only obtainable via a Customer, I would treat a company as a ValueType/Value Object. If that is the case I would create a method on the customer repository to retrive all CompanyNames.
_repo.GetAllCompanyNames();
Repositories are indispensable, just go with them. They hide out data implementation. Used with an ORM you can pretty much forget about core db activity (CRUD). You'll find generally there's 1:1 map between an object and a repository, but nothing stops a repository returning anything it likes. Typically though you will acting upon an instance. Create non-object specific repositories for your queries that don't naturally fit into an existing one.
You will find a lot of conflicting arguments on the "Services" part of it - which some people like to split between Domain Services (i'd call these business rules that don't comfortably fit into a Core Domain Object) and Application Services (logical groupings of operations on Domain Objects). I've actually gone for one, separate project called [ProjectName].Core.Operations that lives in my [ProjectName].Core solution folder. Core + Operations = Domain.
An operation might be something that returns a DTO of all the information a View requires built via a number of repository calls and actions on the Domain. Some people (myself included) prefer to hide Repositories completely from Presentation and instead use Operations(Services) as a facade to the them. Just go with gut feeling on naming and don't be afraid, refactoring is healthy. Nothing wrong with a HomePageOperations class, with a method GetEveryThingINeedForTheHomepage returns a ThingsINeedForTheHomePage class.
Keep your controllers as light weight as possible. all they do is map data to views and views to data, talk to "Services" and handle application flow.
Download and have a look at S#arp architecture or the Who Can Help Me projects. The latter really shows a good architecture IMHO.
Lastly don't forget one of the major concerns of tiers is pluggability/testability, so I advise getting your head around a good IoC container (I'm a fan of Castle.Windsor). Again S#arp architecture is a good place to find about this.
You can pass more than one type of Repository to the controller (I'm assuming your using some kind of IoC container and constructor injection). You may then decide to compose some type of service object from all of the passed repositories.