|
|
Comments and Discussions
|
|
 |
|

|
Picking up on your most recent comment:
It has been published about three years ago and it has been writing on ef v1.1.
Given the amount that's changed since the original post:
-- The Opinions and Conventions of MVC have matured
-- EF Code First makes EF far more accessible (and therefore: mainstream)
-- 3rd party utilities have matured
-- Experience levels of senior-level devs has matured
The rigor and thoroughness you've applied to the explanation would be all that much more valuable if you undertook a more comprehensive re-write.
|
|
|
|
|

|
Sorry but I can not give this more than 1.
this is a typical case of over-architecting.
A pattern is useful not just because you can use it to prove you can do "correct design" or using the "good practices", it is useful because it can give you something: flexibility, speed, test-ability, scalability, etc.
you need to consider that EF already have Repository and UoW implemented. so, if you are about to wrap that in a second layer. That should be "easier" to use than just using EF directly.
Because of "repositories" like this is that some developers like Ayende hate the repository pattern http://ayende.com/blog/3955/repository-is-the-new-singleton[^]
I disagree with Ayende's extremist point view, I think you can use repository and UoW and make some good out of it (sometimes). But it needs to be done more simple.
You have used hundreds of lines of code for something that is achievable on less than 30 lines of code (including IoC, UoW and POCO). No to mention what you have done with the KEY...
Sorry but if you are using a pattern to is supposed to make things easier, and is not doing it, then you are using it the wrong way.
Leonardo Paneque
|
|
|
|

|
Thanks for your judgement!! its not on "good practices" mood,it help me to have a single entry point of all
db related code, implementing Logging and Caching , audit trial ....its totally up to you whether you want it or not ....its just an concept that I share and Im sure it helps some people get some ready to use code. ....yes, Surely , I also feel there is always some areas of improvement...and this article has that also....I am not worry about anybody's vote , all I am worry about reader's feedback that I may missed here. It has been published about three years ago and it has been writing on ef v1.1.
modified 12-May-12 9:24am.
|
|
|
|

|
So EF implements UoW and Repository patterns, or so I've heard. Yet I've never seen a good example of how to use EF properly WITHOUT it being directly in the presentation layer. In my case a MVC project. Please if you know of a simpler implementation, share it.
|
|
|
|

|
They do implement those patterns, a DbContex or ObjectContext would be your UoW, and the ObjectSet or Set inside are your repositories, then, there is no need to rebuild the pattern around the pattern.
so, if you have a UoW you use it in your site from the presentation layer right? why not EF then? now, if the problem is that you dont want dependencies/references to EF (which makes sense) I would recommend to use Unity Framework and inject those into your project. All you need to do is wrap that around with an interface that return IQueryable.
IQueryable is the center of all here, is what makes those pattern-wrapping obsolete, when Martin Fowler wrote that in the book, he referred to "collections", and IQueryable is more powerful than that.
Leonardo Paneque
|
|
|
|

|
Actually our presentation layer would call services, which would then call the DB or UoW, but same difference. Abstracting out EF is not my intention, I'd rather have testable code. IE I don't want to have to use a database to test code. I've always assumed this was the reason people implemented their own UoW and Repository patterns. I suppose I'll go look and see how testable EF is on it's own.
And I certainly plan on using a dependency injection framework. Unfortunately I learn from example and most examples out there are so trivial they are useless when it comes to wiring all this up in a real app that doesn't get things one entity at a time.
Thank you.
|
|
|
|

|
Nice article, thanks.
But how can i use it with dependency injection?
|
|
|
|

|
Hi
Morshed Anwar,
Excellent code you have published for us. thanks for sharing with us. My vote of 5
Can you explain how to call SQL View using Repository Pattern and Entity Framework 4.0 wit MVC 3.0?
Any answer would be appreciated!.
Thanks,
Imdadhusen
sunaSaRa Imdadhusen
+91 99095 44184
|
|
|
|

|
This sounds good to have a generic repository, but would this approach work for entities with multiple primary keys?
|
|
|
|

|
I see in your code you create _ctx with:
_ctx = Helper.SecurityContextInstance;
I am new to EF and was wondering what your Helper method/property looks like??
"Those that say a task is impossible shouldn't interrupt the ones who are doing it." - Chinese Proverb
|
|
|
|

|
Any thoughts on how to implmenet this generic repository in a WCF service? It doesn't seem to support Generics, where you have to provide a concrete type while instantiating. Thanks.
|
|
|
|

|
Hello,
Thanks for this article, makes the pattern really easy to use. One questions though, this may sound dummy as I am new to LinQ, how can I use your example with Linq some more complex queries?
Consider this example:
var myList = from a in _db.apples
join p in _db.oranges on a.idequals p.Id
where a.color == p.color
select p ;
Or perhaps a sample that works with a function parameter
var myList = from a in _db.apples
join p in _db.oranges on a.idequals p.Id
where a.color == PARAM
select p ;
In addition would you please provide an example on how to use those methods that work with the ISpecification?
Thanks a lot!
|
|
|
|

|
Never mind, I figured it out... Thanks
|
|
|
|
|

|
First, this is a great starting reference for Repository patterns. I have modified your repository to support POCO and have tested and works nice.
Second, I have a question about using static methods such as
public static Setting GetSettingByID(int settingID)
{
return (Setting)settingsRepo.Single(p=>p.SettingID == settingID)
}
my class is structured as
public class SettingBLL
{
private static Repository<Setting, EntityModel> settingsRepo;
static SettingBLL()
{
EntityModel db = new EntityModel();
settingsRepo = new Repository<Setting, EntityModel>(db);
}
public static Setting GetSettingByID(Int32 settingID)
{
return (Setting)settingsRepo.Single(param => param.SettingID == settingID);
}
}
As you know, you mention that the context lifetime should be kept as long as the class/BLL workflow will be executed. Then the context should be disposed with the implementation of IDisposable. But this is in a case when we instantiate the class, and not the case when we have static methods. So i had to abandon the Dispose because later in the front end code a if a call is made again to the SettingBLL, the current that executed is disposed and since i am calling a static method the class will not be constructed again, nor the context will be kept alive for long enough.
Are there any implications of using the repository pattern as such, will it consume more memory, what will be the performance issues that i can expect?
Thanks, Martin.
|
|
|
|

|
Hi Martin,
I'm currently working with this implementation of repository and I just read that you modify to support POCO.
I would like to do it myself, but I can find the way to do it.
So, it would be nice if you can share it (or if you can explain your approach)
Thank you in advance,
Jerome
|
|
|
|

|
Hi Morshed,
Do you plan on supporting Compound Keys on an Entity (an entity who's tables primary key is made up of two or more Foreign Keys)?
Thanks again for your excellent work.
|
|
|
|

|
Hello,
can you please post the code. Since the classes you have provided does not seem to compile.
Thanks in advance.
Ganapatsa
|
|
|
|

|
Had missed out using clause of system.linq. after that it compiles
|
|
|
|

|
This is really good artical you have wirtten. But still its is giving me error. Can you please give me solution if possible for this so that I can see what I am doing wrong.
Thank you,
Sanjay
|
|
|
|

|
Hi
I couldn't find the download for the POCO with Repository Pattern can you please let me know if I am missing something.
Regards,
Ram
|
|
|
|

|
Hello Morshed,
Thanks for the great article. I have couple of questions in dealing with relationships.
1. With foreign key relationship:
In the first scenario, assume we have two tables: Order and OrderDetails. Order.OrderId is the primary key in Order table and the OrderDetail.OrderId is the foreign key.
How do you include the orderdetails in the following code?
public List<Order> GetOrderDetails(ISpecification<Order> where)
{
Repository<Order, OrderEntities> orderRepo = new Repository<Order, OrderEntities>;
orderRepo.DoQuery("Order", where);
}
2. Without foreign key relationship:
In the second scenario, we still have the above two tables, but the OrderDetail.OrderId is not defined as a foreign key in the database.
How do we retrieve OrderDetails in this case?
Regards,
Hari.
modified on Monday, August 2, 2010 8:49 PM
|
|
|
|

|
DoQuery returns an ObjectQuery. This functions just like LINQ statements. The Session property is the context that can be used to join additional tables.
from o in orderRepo.DoQuery(where)
join od in orderRepo.Session.OrderDetails on o.OrderId equals od.OrderId
where o.modifiedDate > since
select new OrderWithDetail
{
Order = o,
OrderDetail = od,
}
or if there this is a one to many,
public class OrderWithManyDetail{
public Order {get;set;}
public IEnumerable<OrderDetail> OrderDetails {get;set;}
}
...
from o in orderRepo.DoQuery(where)
where o.modifiedDate > since
select new OrderWithManyDetail
{
Order = o,
OrderDetail = from od in orderRepo.Session.OrderDetails
where od.OrderId == o.OrderId
select od,
}
modified on Friday, August 27, 2010 4:36 PM
|
|
|
|

|
Hi Morshed Anwar,
this is a great article, thanks for share.
how can I present in WCF the IRepository?
Thank you,
Neo
modified on Thursday, June 3, 2010 5:37 PM
|
|
|
|

|
If your Business layer and DAL on server side, why do you want the repository on client? for V1, it has an N-tier issue. service layer will expose domain objects only.If all you want is a thin CRUD layer exposed as a web service, then WCF data service will do that for you.
|
|
|
|

|
Hi Morshed Anwar,
This is a cool article with loads of information. Here are few questions or concerns about it.
a. You are using an ObjectContext per repository. I like this idea, but the life time of it making me nervous. As you know, over the time the memory consumption of object context can dramatically increase as it keeps track of old vlaues and new values...etc. I am new to Entity Framework, so please pardon my ignorance.
b. You are using DbTransaction to perform critical database operations. My question is, will object context keep tracking the data, even though dbConnection is Closed?
Thank you,
Suresh
|
|
|
|

|
Suresh.. .thank you so much for the compliment. As I said in article, you just have to keep alive context in a workflow only and share the context in all created repositories in a workflow. After competing a workflow it can be disposed. So its completely depend on your using.
The Entity Framework opens connections only when required, for example to execute a query or to call SaveChanges, and then closes the connection when the operation is complete and it exposes the EntityConnection through the Connection property. This enables you to manage the connection and transactions or to supply your own EntityConnection. When you manually open the connection in a long-running object context, you must call the Dispose method to ensure that the connection is closed when the context is no longer needed. You can also call the Close method on the EntityConnection to explicitly close the connection. For more information, see .How to: Manage the Connection in a Long-Running Object Context (Entity Framework) . Any streaming type data access (DataReader) will not work after the dispose because the connection will be closed. Moving items into a list will get around this problem and EF use this internally. So I think it shouldn't be work.
|
|
|
|
|

|
I have used TryGetObjectByKey to ensure the attachment of the orginal item in the context. In EF, it lookes up for data from db, when you tell it to do so. Before calling ApplyPropertyChanges, I need the orginal item present in the context. Then ApplyPropertyChanges compare the scaler properties of new object with old one.
|
|
|
|

|
Thank you for your fast answer.
So TryGetObjectByKey loads the old values, ApplyPropertyChanges somehow will compare them with the currents. Not so transparent, but now it's clearer
|
|
|
|
|

|
The patterns is really nice, but I see a lot of code here, fortunatelly we are not using the JVM; but is this code fast? What happend if I really need performance in my app?
|
|
|
|

|
Design Patterns are about capturing reusable solutions to software engineering problems. If you are worry about you application performance then first you need to decide whether you are going to use ORM or not. I don't have the idea about your application volume. Its true that when you are implementing some pattern , you may need to wrap your objects. Wrapping is expensive, and fpr the same reason any ORM is expensive in compare to use native SQL code. From my point of view, benefit of using pattern is much more then its cost. So Don't need to worry about that. to know about the FE performance,you can read a nice post here. Aywaz I am also a Java Fan, I don't think that you have to worry about implementing any pattern in Java.
|
|
|
|

|
Hi thanks for a great article.I implemented exactly the way specified everything works fine.But how should i implement specification with sorting.For example in my case i want to get rows only which satisfy my condition followed by sortexpression,then loading them into grid by sending rowindex and max rows.Thanks.
|
|
|
|

|
Fantastic article. It has proved invaluable for my project, however I have a question,
Can you please explain why you have chosen to return an ObjectQuery(Of T) for DoQuery rather than IQueryable(Of T)?
From what I have read (and experienced in my project), the type ObjectQuery cannot be mocked as it is not an abstract class whereas it's base class IQueryable can be, I have made this change in my project and it has passed the litmus test (ie I can still retrieve data).
|
|
|
|

|
No specific reason. Thanx for sharing your experience. When the query has been processed, it's no longer an IQueryable, becomes an ObjectQuery.But At design time, the compiler recognizes that it's a LINQ query and therefore assumes the return will be an IQueryable. So sure you can change/cast it into IQueryable.
|
|
|
|

|
I'm developing a prototype using your repository implementation and I', having some difficulties in understating how to pass a sortExpression to the Selectall method when I want to sort, for example, by a DateTime field?
Since de lambda expression is expecting an object type, it automatically inserts “Convert” into the expression.
I’m using the following code:
return repository.SelectAll(o => o.NewsDate, 10, 1);
Thnsk for the help.
Thanks,
Antonio
|
|
|
|
|

|
The error message is: Unable to cast the type 'System.DateTime' to type 'System.Object'. LINQ to Entities only supports casting Entity Data Model primitive types.
Thanks
|
|
|
|

|
IList<Project> list =
(from x in _repository.DoQuery(p => p.StatusDate, maxrows, startrow)
select x).ToList();
So far this Repository implementation is impeccable and fits very well in to a solution I am working on. Thank you for your effort; it has helped a lot.
I am having trouble with Ordering/Sorting however; similar to Antonio's problem.
When I try to run the above code, I get the same Casting Error already mentioned in this thread. (unable to cast to System.DateTime)
None of the methods using "sortExpression" allow sorting, and any DoQuery(int maxrows, int startrow) calls fail with a message stating you must "OrderBy" before you "Skip".
I'm sure it's something I'm doing but could you maybe provide a working example of your code, using the DoQuery(sortExpression, maxrows, startrow) method?
|
|
|
|

|
I am very much sorry for the trouble. I am going to change the method signature and make it Generic in place of 'object' type as result parameter. The change will be like this -
previous signature was -
ObjectQuery<E> DoQuery(Expression<Func<E, object>> sortExpression);
ObjectQuery<E> DoQuery(Expression<Func<E, object>> sortExpression,
int maximumRows, int startRowIndex);
IList<E> SelectAll(Expression<Func<E, object>> sortExpression);
IList<E> SelectAll(Expression<Func<E, object>> sortExpression,
int maximumRows, int startRowIndex);
New methods will be -
ObjectQuery<E> DoQuery<T>(Expression<Func<E, T>> sortExpression);
ObjectQuery<E> DoQuery<T>(Expression<Func<E, T>> sortExpression, int maximumRows, int startRowIndex);
IList<E> SelectAll<T>(Expression<Func<E, T>> sortExpression);
IList<E> SelectAll<T>(Expression<Func<E, T>> sortExpression, int maximumRows, int startRowIndex);
So now these method will be sothing like these
public ObjectQuery<E> DoQuery<T>(Expression<Func<E, T>> sortExpression)
{
if (null == sortExpression)
{
return ((IRepository<E, C>)this).DoQuery();
}
return (ObjectQuery<E>)((IRepository<E, C>)this).DoQuery().OrderBy<E, T>(sortExpression);
}
public ObjectQuery<E> DoQuery<T>(Expression<Func<E, T>> sortExpression, int maximumRows, int startRowIndex)
{
if (sortExpression == null)
{
return ((IRepository<E, C>)this).DoQuery(maximumRows, startRowIndex);
}
return (ObjectQuery<E>)((IRepository<E, C>)this).DoQuery<T>(sortExpression).Skip<E>(startRowIndex).Take(maximumRows);
}
public IList<E> SelectAll<T>(Expression<Func<E, T>> sortExpression)
{
if (null == sortExpression)
{
return DoQuery(sortExpression).ToList();
}
return DoQuery(sortExpression).ToList();
}
public IList<E> SelectAll<T>(Expression<Func<E, T>> sortExpression, int maximumRows, int startRowIndex)
{
if (sortExpression == null)
{
return DoQuery(maximumRows, startRowIndex).ToList();
}
return DoQuery(sortExpression, maximumRows, startRowIndex).ToList();
}
I am going to update the example source also. Please let me knoe if you get any trouble to work with this. Download the new example source
|
|
|
|

|
Bingo. Those changes work great.
Thanks again Morshed.
|
|
|
|

|
no problem.
|
|
|
|

|
Please rate this Article whatever you think about this article.That will help me to write my next one.
|
|
|
|
|

|
no problem Cyril....my pleasure to share my thoughts wid u.
I am Bangali, and my english is also very bad:S. :P
so the answer is , I never try the scenario you have mentioned.
But I think it should work.EntityObject implements the 3 interfaces- IEntityWithChangeTracker, IEntityWithKey,IEntityWithRelationships. Apart from these interfaces, EntityObject also implements StructuralObject which its uses to set field values for properties as Zeshaan said in his tutorial.
you have to marked the class with EdmEntityTypeAttribute which tells entity framework that your POCO class in an entity. EdmEntityTypeAttribute attribute takes two parameters. First parameter represents the namespace where the entity resides and second parameter specifies the name of the entity.
Md. Morshed Anwar
modified on Thursday, November 26, 2009 11:47 PM
|
|
|
|

|
After looking through your code, which has been a great read btw, I can't seem to see how you approach the issues of eager loading child object using this generic repository.
Am I missing something here, or is it outside of the scope of the repository interface?
I was thinking about something like, in a very basic form to illustrate an idea:
public ObjectQuery<E> DoQuery(string include)
{
return entities.CreateQuery<E>("[" + typeof(E).Name + "Set]").Include(include);
}
or perhaps using a string array to construct a dot-seperated list for the Include method.
|
|
|
|

|
Thank you so much for the sharing. Yes you are right. Here I didn't implement any approach of eager loading child object. This was just an sample. You can add more methods if u need.
The example that you have provided is ok but I wanna share something with you -
"[" + typeof(E).Name + "Set]" is ok but EDMX has the option to change the entity set name. Its better to retrieve the entity set name from metadata query.
To Avoid the string parameter ,you can consider a very good read here
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
Implement Repository Pattern in data access layer with Entity Framework 4.0 and Below version( Working with ObjectContext and EntityObject )
| Type | Article |
| Licence | CPOL |
| First Posted | 10 Jun 2009 |
| Views | 176,658 |
| Downloads | 1,416 |
| Bookmarked | 157 times |
|
|