I am in midst of developing an application using Entity Framework code first 4.1 and MVC3. Here are three entities that I have, basically, State => City => Locality.
public class State {
public virtual List<City> Cities { get; set; }
}
public class City {
public virtual List<Locality> Localities { get; set; }
public virtual State State { get; set; }
}
public class Locality {
public virtual City City { get; set; }
}
It can be seen that I am using bi-directional relationship for all three entities. Json does not allow that, so I am somewhat frustrated. Basically, I need to navigate in either direction. For example given a City I want to be able to locate State to which it belongs easily.
I scanned the web and came across a couple of workarounds, but none of them suits my scenario. The first was to make the relationship unidirectional(who will do that !) and I don't want that. Other was to introduce ViewModel with only the properties that I need, but then that would mean duplicate code if I need to use all the fields of Entity regularly. Also my controller will be flooded with those properties. So I don't like that too.
I was thinking that this was just basic stuff, but now I am struggling to find a workable solution. If anyone has a better alternative(perhaps something in MVC3), please help me out.
You could try using JavaScriptSerializer directly and registering your own converter to control the serialization process.
I am not an ASP expert, but I think the solution might be similiar to what I woudl do in Java, Groovy or python or any other language.
The best solution I could propose is to make City.Localities a kind of "transient" (in Java terms) field - i.e. don't serialize it, but update it at loading time (when you build the structure). This can be encapsulated in setter for City of the Locality class.
So in Locality.setCity, in the set method you should call (city->localities.append(this) (whatever language you write it in). This way it will become a "runtime cache" of City->Localities which will be build once during loading.
The problem appears to be a native issue with the DataContractJsonSerializer support for Entity types. In short, Entities that have relationships (i.e. two-way) with other Entity types cannot be serialized through Json. In your example: a State table connected to a Cities table will not translate well into Json serializing because a State may have many cities and a City is associated with a State.
One quick solution would be anonymous object projection.
Something like this example:
public JsonResult Orders()
var results = from Ord in databaseContext.Orders
select new
{
OrderID = Ord.ID,
OrderTitle = Ord.Name,
OrderDate = Ord.OrderDate
}
return Json(results);
}
For reference, see this: Serializing Entity Framework Objects into JSON Using ASP.Net MVC
Related
I have a circular object reference which stops an object from being serialized into json. I was trying to use ScriptIgnoreAttribute on the property that is causing problems, but it didn't seem to work. I believe that's because I'm using EF convention with virtual keyword:
[ScriptIgnore]
public virtual SomeObject SomeObject { get; set; }
The other side of this relationship looks like this
public virtual ICollection<OtherObject> OtherObjects { get; set; }
I have no additional mappings.
How can I resolve this?
The problem is that each of the OtherObject objects has a back reference to SomeObject, which in turn has a collection of OtherObject, etc.
I would recommend creating a viewmodel class which contains only the properties you need. Then, map your entity to the viewmodel class. Return the viewmodel class instance instead of the raw entity.
The other alternative is to tell the json serializer to stop serializing circular references. I prefer the first approach though.
You can also influence EF behavior (ex. disable lazy loading by removing the virtual keyword) or by changing the query.
But really, I prefer the viewmodel approach. I find that using viewmodels solves not only this but other problems as well.
I took the approach of ignoring the associated objects. To do this you just need to add
[ScriptIgnore(ApplyToOverrides = true)] into your text template (.tt) file.
Here a portion of my text template before
#>
<#=codeStringGenerator.NavigationProperty(navigationProperty)#>
<#
Once I inserted the code the line above the codeStringGenerator my classes auto generated and looked like this:
[ScriptIgnore(ApplyToOverrides = true)]
public virtual ICollection<Currency> Currencies { get; set; }
I also needed to modify the UsingDirectives function to insert "using System.Web.Script.Serialization;"
This is a common requirement in many web-based projects: an entity has to show information to another related entity. For example, a book in an e-commerce site has to show relevant information about its author.
Let say I model both the book and author as an entity, how should I implement a feature which display a book and its author's information on the same page.
I can make a call to the BookRepo to retrieve the book's information, and then another call to the AuthorRepo to retrieve the author, using the authorid inside the book entity. This is 2 queries
I can write a query where I join the Book and Author tables together and retrieve both information in 1 query. But which repo does this query goes? Does this break DDD because I am assuming details about the Book and Author entity?
Which is the 'best practices', and what are other ways I can approach this problem?
(I am assuming using the use of standard SQL queries [such as PHP + MySQL], since in EF 4 you would define associations between Book and Author which would solve the problem rather easily).
There is no silver bullet solution to this, but you have a few options.
Your first proposed solution of making a call to two repositories is perfectly valid and happens all the time in practice. For example, it takes over a hundred different services to render an Amazon product page. Each service is responsible for providing data specific to its bounded context. You can create a service called something like BookService which calls the two repositories to return a reporting object or a DTO that has all the data that you need for the particular view. If you feel that performance is due to two repository calls is going to be an issue, you can employ caching, or CQRS to create appropriate read models, but don't jump to those solutions prematurely.
But which repo does this query goes?
I would just add it to the BookRepository, or even a whole new repository called BookDetailsReportingRepository, perhaps a method called GetBookDetails. This method would not return an editable entity, but a reporting object which is a projection of values from multiple entities.
Does this break DDD because I am assuming details about the Book and Author entity?
This does not violate DDD and in my opinion makes it easier to apply. Just regard as the data returned by the aforementioned repository as reporting objects, not entities.
But even though you don't seems to use ORM's you probably have tto populate your entities from your SQL querys and your entities has to relate to each other in some way (collections, navigation properties etc...).
If your domain contains entities that have no associations between each other, I wouldn't call it DDD since you lack some important ingredients like aggregates, value objects, bi-/unidirectional relationships.
But what do I know :-) Maybe you have made your puzzle well and this last piece is to merge entities into a "view" that can be useful for your clients.
Since repositories normally operates on an aggregate-root entity you can have repository methods like ListBooksByAuthor (BookRepository) or ListAuthors (AuthorRepository).
When you want to display complex data from many different aggregates in a web page I recommend using Data Transfer Objects. Let that DTO object be unique for that page or Use Case and being a "view" that displays all (or most of the) data that web page needs.
I also recommend NOT using DTO's everywhere unless you're using web services. Using DTO's together gives both pros and cons. Together with a service layer it gives you a nive anti corruption layer and also gives you the place to inject Book and Author repository. Then from service layer you can assemble and reassemble DTO's (look at AutoMApper or similar...helps you a lot).
BUT to much DTO's everywhere also gives you overhead in maintenance of the application. It adds another layer to maintain.
I prefer to just use it for certain clients/web pages.
I hope you understand what I'm trying to explain :-)
If you look at this page it describes two ways to load and relate the aggregate roots. Linking this back to your example:
The Book class would encapsulate the relevant Author information as a Value Type so when the Book information is displayed on the web page it has all the information on the author it needs. If the users decides to view more information on the Author they can by following a link to an Author Page (whatever the requirement is).
If you have a service method called FindBookByTitle then
loading the Book entity would then load the relevant author information from the BookRepo.
class Author
{
public Author(int authorID, FullName name) { }
int AuthorID { get; }
FullName Name { get; }
List<BookDetails> AuthoredBooks { get; set; }
}
class BookDetails
{
public BookDetails(int ID, string title) { }
int BookID { get; }
string Title { get; }
}
class Book
{
public Book(int ID, string Title) { }
int BookID { get; }
string Title { get; }
List<AuthorDetails> Writers { get; set; }
}
class AuthorDetails
{
public AuthorDetails(int ID, FullName name) { }
int AuthorID { get; }
public FullName fullName { get; }
}
class FullName
{
public FullName(string name, string surname) { }
public string Name { get; }
public string Surname { get; }
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I'd like to make my application as flexible as possible, but not dig myself into a hole by making my Interface too specific.
What is the best object type for a repository? IEnumerable, IQueryable, or List?
The technologies I'm considering using are
Azure App Fabric Caching
Entity Framework 4.1
Possibly Windows Server AppFabric
It depends on whether you wish to have any future queries performed on the entity and whether these should be in memory or not:
If there are to be future queries and the DB should do the work return IQueryable.
If there are to be future queries and it is to be done in memory return IEnumerable.
If there are to be no further queries and all the data will need to be read return an IList, ICollection etc.
I would say build your DAL using IQueryable, and pass it around, make sure your object contexts lifetime is the request. This way you will get benefit of delayed execution, but are exposed to the risk of inefficient querying of database.
Then make sure you performance test your application( or at least the parts that are most likely to get traffic) and see the data access patterns. Create specialized methods in your DAL to retrieve fully materialized objects and make these queries as pre compiled queries.
a sample of the repository interface would be like
public interface IDataContext
{
void Add<T>(T entity) where T : BaseEntity;
void Delete<T>(T entity) where T : BaseEntity;
IQueryable<T> Find<T>(Expression<Func<T, bool>> where) where T : BaseEntity;
}
where BaseEntity is the base class to all our classes, it looks like, this class is not mapped to any table in DB
public abstract class BaseEntity
{
public int Id { get; set; }
public DateTime CreateDateTime { get; set; }
public string CreateUser { get; set; }
public DateTime ModDateTime { get; set; }
public string ModUser { get; set; }
public byte[] RowVersion { get; set; }
}
Expression<Func<T, bool>> would pass the whole expression to your repository instead of just Func, since EF works on expression to generate SQL query, a typical use would be
ICollection<WFGroup> wgGroups = this.dataContext.Find<WFGroup>((w) => true).ToList();
where WFGroup is a class derived from BaseEntity, I typically use lazy loading and proxy and don't detach/attach objects to a context.
How likely are you to ever need to return a custom implementation of IEnumerable (not a collection) from your DAL? (To answer this question, look at your previous projects and count how many of those or of yield returns you have around.)
If the answer is "not very", I'd just return ICollection or even arrays (if you want to prevent the query results from being inadvertently modified.) In a pinch, if you ever need to change a query to "stream" results with a custom IEnumerable, you can always have the old method call the new one and materialise the results to keep compatibility with older clients.
There is a very good recent article here that covers this, namely under the heading "Repositories that return IQueryable". This is what it says:
One of the reasons we use the repository pattern is to encapsulate fat queries. These queries make it hard to read, understand and test actions in ASP.NET MVC controllers. Also, as your application grows, the chances of you repeating a fat query in multiple places increases. With the repository pattern, we encapsulate these queries inside repository classes. The result is slimmer, cleaner, more maintainable and easier-to-test actions. Consider this example:
var orders = context.Orders
.Include(o => o.Details)
.ThenInclude(d => d.Product)
.Where(o => o.CustomerId == 1234);
Here we are directly using a DbContext without the repository pattern. When your repository methods return IQueryable, someone else is going to get that IQueryable and compose a query on top of it. Here’s the result:
var orders = repository.GetOrders()
.Include(o => o.Details)
.ThenInclude(d => d.Product)
.Where(o => o.CustomerId == 1234);
Can you see the difference between these two code snippets? The only difference is in the first line. In the first example, we use context.Orders, in the second we use repository.GetOrders(). So, what problem is this repository solving? Nothing!
Your repositories should return domain objects. So, the GetOrders() method should return an IEnumerable. With this, the second example can be re-written as:
var orders = repository.GetOrders(1234);
See the difference?
As a result of this, I've added the following coding convention within my team:
For repository class methods, never return a IQueryable object. Always enumerate or convert it first (e.g., ToArray, ToList, AsEnumerable).
The reasoning being that IQueryable would allow the caller to build on this and ultimately modify the SQL query that is executed on the database. This can potentially be dangerous in terms of DB performance, but it is more about SoC. The caller doesn’t care about the data source; it just wants the data.
I will use LINQ-to-SQL when the database is ready and use the entities there as models in my aplication. I'm trying to program against a interface to make changes to the program easier and I just realized that if I would later change from LINQ to something else I would have to create new model objects that would represent something very similar to the LINQ entities.
So I thought of creating interfaces for each entity and expose the properties and methods I would use in the program and aren't LINQ specific. But when I would apply this interface to the entity class would the implementation automatically bind to it's properties.
I'll give you an example to explain better.
I have table Cars that amongst others has the columns producer, type and wheels
So I make the interface ICar
public interface ICar
{
string Producer { get; set; }
string Type { get; set; }
int Wheels { get; set; }
}
The Car entity object will have these exact properties so will that work as the implementation of these properties or will they be defined seperatly so you get ICar.Producer and Car.Producer in the class?
This might be helpful: Linq to Sql, Programming Against an Interface and the Repository Pattern
First link is broken, check here instead: ORM and Repository pattern
So, I'm developing some software, and trying to keep myself using TDD and other best practices.
I'm trying to write tests to define the classes and repository.
Let's say I have the classes, Customer, Order, OrderLine.
Now, do I create the Order class as something like
abstract class Entity {
int ID { get; set; }
}
class Order : Entity {
Customer Customer { get; set; }
List<OrderLine> OrderLines { get; set; }
}
Which will serialize nice, but, if I don't care about the OrderLines, or Customer details is not as lightweight as one would like. Or do I just store IDs to items and add a function for getting them?
class Order : Entity {
int CustomerID { get; set; }
List<OrderLine> GetOrderLines() {};
}
class OrderLine : Entity {
int OrderID { get; set; }
}
And how would you structure the repository for something like this?
Do I use an abstract CRUD repository with methods GetByID(int), Save(entity), Delete(entity) that each items repository inherits from, and adds it's own specific methods too, something like this?
public abstract class RepositoryBase<T, TID> : IRepository<T, TID> where T : AEntity<TID>
{
private static List<T> Entities { get; set; }
public RepositoryBase()
{
Entities = new List<T>();
}
public T GetByID(TID id)
{
return Entities.Where(x => x.Id.Equals(id)).SingleOrDefault();
}
public T Save(T entity)
{
Entities.RemoveAll(x => x.Id.Equals(entity.Id));
Entities.Add(entity);
return entity;
}
public T Delete(T entity)
{
Entities.RemoveAll(x => x.Id.Equals(entity.Id));
return entity;
}
}
What's the 'best practice' here?
Entities
Let's start with the Order entity. An order is an autonomous object, which isn't dependent on a 'parent' object. In domain-driven design this is called an aggregate root; it is the root of the entire order aggregate. The order aggregate consists of the root and several child entities, which are the OrderLine entities in this case.
The aggregate root is responsible for managing the entire aggregate, including the lifetime of the child entities. Other components are not allowed to access the child entities; all changes to the aggregate must go through the root. Also, if the root ceases to exist, so do the children, i.e. order lines cannot exist without a parent order.
The Customer is also an aggregate root. It isn't part of an order, it's only related to an order. If an order ceases to exist, the customer doesn't. And the other way around, if a customer ceases to exist, you'll want to keep the orders for bookkeeping purposes. Because Customer is only related, you'll want to have just the CustomerId in the order.
class Order
{
int OrderId { get; }
int CustomerId { get; set; }
IEnumerable<OrderLine> OrderLines { get; private set; }
}
Repositories
The OrderRepository is responsible for loading the entire Order aggregate, or parts of it, depending on the requirements. It is not responsible for loading the customer. If you need the customer, load it from the CustomerRepository, using the CustomerId from the order.
class OrderRepository
{
Order GetById(int orderId)
{
// implementation details
}
Order GetById(int orderId, OrderLoadOptions loadOptions)
{
// implementation details
}
}
enum OrderLoadOptions
{
All,
ExcludeOrderLines,
// other options
}
If you ever need to load the order lines afterwards, you should use the tell, don't ask principle. Tell the order to load its order lines, and which repository to use. The order will then tell the repository the information it needs to know.
class Order
{
int OrderId { get; }
int CustomerId { get; set; }
IEnumerable<OrderLine> OrderLines { get; private set; }
void LoadOrderLines(IOrderRepository orderRepository)
{
// simplified implementation
this.OrderLines = orderRepository.GetOrderLines(this.OrderId);
}
}
Note that the code uses an IOrderRepository to retrieve the order lines, rather than a separate repository for order lines. Domain-driven design states that there should be a repository for each aggregate root. Methods for retrieving child entities belong in the repository of the root and should only be accessed by the root.
Abstract/base repositories
I have written abstract repositories with CRUD operations myself, but I found that it didn't add any value. Abstraction is useful when you want to pass instances of subclasses around in your code. But what kind of code will accept any BaseRepository implementation as a parameter?
Also, the CRUD operations can differ per entity, making a base implementation useless. Do you really want to delete an order, or just set its status to deleted? If you delete a customer, what will happen to the related orders?
My advice is to keep things simple. Stay away from abstraction and generic base classes. Sure, all repositories share some kind of functionality and generics look cool. But do you actually need it?
I would divide my project up into the relevant parts. Data Transfer Objects (DTO), Data Access Objects (DAO). The DTO's I would want to be as simple as possible, terms like POJO (Plain Old Java Object) and POCO (Plain Old C Object) are used here, simply put they are container objects with very little if any functionality built into them.
The DTO's are basically the building blocks to the whole application, and will marry up the layers. For every object that is modeled in the system, there should be at least one DTO. How you then put these into collections is entirely up to the design of the application. Obviously there are natural One to many relationships floating around, such as Customer has many Orders. But the fundamentals of these objects are what they are. For example, an order has a relationship with a customer, but can also be stand alone and so needs to be separate from the customer object. All Many to Many Relationships should be resolved down into One to Many relationships which is easy when dealing with nested classes.
Presumably there should be CRUD objects that appear within the Data Access Objects category. This is where it gets tricky as you have to manage all the relationships that have been discovered in design and the lifetime models of each. When fetching DTO's back from the DAO the loading options are essential as this can mean the difference between your system running like a dog from over eager loading, or high network traffic from fetching data back and fourth from your application and the store by lazy loading.
I won't go into flags and loading options as others here have done all that.
class OrderDAO
{
public OrderDTO Create(IOrderDTO order)
{
//Code here that will create the actual order and store it, updating the
flelds in the OrderDTO where necessary. One being the GUID field of the new ID.
I stress guid as this means for better scalability.
return OrderDTO
}
}
As you can see the OrderDTO is passed into the Create Method.
For the Create Method, when dealing with brand new nested Objects, there will have to be some code dealing with the marrying up of data that has been stored, for example a customer with old orders, and a new order. The system will have to deal with the fact that some of the operations are update statements, whilst others are Create.
However one piece of the puzzle that is always missed is that of multi-user environments where DTO's (plain Objects) are disconnected from the application and returned back to the DAO for CRUD. This usually involves some Concurrency Control which can be nasty and can get complicated. A simple mechanism such as DateTime or Version number works here, although when doing crud on a nested object, you must develop the rules on what gets updated and in what order, also if an update fails concurrency, you have to decide on whether you fail all the operation or partial.
Why not create separate Order classes? It sounds to me like you're describing a base Order object, which would contain the basic order and customer information (or maybe not even the customer information), and a separate Order object that has line items in it.
In the past, I've done as Niels suggested, and either used boolean flags or enums to describe optionally loading child objects, lists, etc. In Clean Code, Uncle Bob says that these variables and function parameters are excuses that programmers use to not refactor a class or function into smaller, easier to digest pieces.
As for your class design, I'd say that it depends. I assume that an Order could exist without any OrderLines, but could not exist without a Customer (or at least a way to reference the customer, like Niels suggested). If this is the case, why not create a base Order class and a second FullOrder class. Only FullOrder would contain the list of OrderLines. Following that thought, I'd create separate repositories to handle CRUD operations for Order and FullOrder.
If you are interested in domain driven design (DDD) implementation with POCOs along with explanations take a look at the following 2 posts:
http://devtalk.dk/2009/06/09/Entity+Framework+40+Beta+1+POCO+ObjectSet+Repository+And+UnitOfWork.aspx
http://www.primaryobjects.com/CMS/Article122.aspx
There is also a project that implements domain driven patterns (repository, unit of work, etc, etc) for various persistence frameworks (NHibernate, Entity Frameworks, etc, etc) called NCommon