Best practise for using EF Entities
-
There simply isn't enough code here to make any real judgment of what you're doing. I can see some smallish things but nothing about any patterns you're using. 1) Your method is called "Return..." something. Personally, I always name methods that return something "Get...". Return is a bit more vague as to what it does. Does "Return" refer to retrieving a database object, or does it refer to some business rule method. It's the concept of "self documenting code". Method names should describe exactly what they do. 2) Entities (or DbContext) classes should be Disposed when you're done with them. It should be something like this:
internal static Purchase GetPurchaseItem(int purchaseId)
{
Purchase purchase = null;using (var context = new RegulusEntities()) { return context.Purchases.Find(purchaseId); }
}
- If you have a primary key Id for an object, you don't need an entire Linq query to find it. You just need to call the Find method to retrieve it.
Find()
will return the object with the specified key. If it's not found, it'll throw aInvalidOperationException
. You can replace it withFirstOrDefault()
if you want the "Get..." method to return a null of the specified type instead of throwing. Other than that, a couple of rules I follow: I don't have my database code return any ViewModel objects, not does it accept any. My database layer will accept and return Entity objects only. If these objects need to be translated into ViewModel objects, I can have another layer above this that does the translation, such as in an MVC Controller class or what I call a "Services" class. I never expose my database layer directly to UI code.
A guide to posting questions on CodeProject[^]
Dave KreskowiakThanks for the reasoned and well thought out answer Dave. In showing you only a tiny patch of my code, I actually missed out the whole structure that this little method sits in. This method, as with all my other calls to EF sits in a service class written to handle all the calls to a particular table. for example, all the calls to the purchase table are made from the clsPurchaseHandler class, thus separating it from the UI. Your answer is exactly what I wanted. as I explained I am a freelance programmer running my own little operation, and I haven't got the luxury of being able to discuss code with anyone, and there's always the niggle at the back of my mind that 'I know it works, but is it the most efficient'. Your code detailing the disposal of entities after use and the find method is invaluable. As for my naming of the method "ReturnPurchaseItem", that's my usual practise, as that's what the method does, I take your point that it may sound vague, but I've got a lot of code out in the wild that uses this notation, so for now, I'll stick with it. Thanks again Dave, much appreciated. George
George
- If you have a primary key Id for an object, you don't need an entire Linq query to find it. You just need to call the Find method to retrieve it.
-
There simply isn't enough code here to make any real judgment of what you're doing. I can see some smallish things but nothing about any patterns you're using. 1) Your method is called "Return..." something. Personally, I always name methods that return something "Get...". Return is a bit more vague as to what it does. Does "Return" refer to retrieving a database object, or does it refer to some business rule method. It's the concept of "self documenting code". Method names should describe exactly what they do. 2) Entities (or DbContext) classes should be Disposed when you're done with them. It should be something like this:
internal static Purchase GetPurchaseItem(int purchaseId)
{
Purchase purchase = null;using (var context = new RegulusEntities()) { return context.Purchases.Find(purchaseId); }
}
- If you have a primary key Id for an object, you don't need an entire Linq query to find it. You just need to call the Find method to retrieve it.
Find()
will return the object with the specified key. If it's not found, it'll throw aInvalidOperationException
. You can replace it withFirstOrDefault()
if you want the "Get..." method to return a null of the specified type instead of throwing. Other than that, a couple of rules I follow: I don't have my database code return any ViewModel objects, not does it accept any. My database layer will accept and return Entity objects only. If these objects need to be translated into ViewModel objects, I can have another layer above this that does the translation, such as in an MVC Controller class or what I call a "Services" class. I never expose my database layer directly to UI code.
A guide to posting questions on CodeProject[^]
Dave KreskowiakSorry to be a pest Dave, but the 'find' method you suggest isn't available to my version of EF. I've read up on it and it appears to come in after EF 4.0. I appear to be running EF 6.0, but I still can't see it. What am I doing wrong?
- If you have a primary key Id for an object, you don't need an entire Linq query to find it. You just need to call the Find method to retrieve it.
-
Sorry to be a pest Dave, but the 'find' method you suggest isn't available to my version of EF. I've read up on it and it appears to come in after EF 4.0. I appear to be running EF 6.0, but I still can't see it. What am I doing wrong?
You have to import the
System.Data.Entity
namespace at the top of the code file. If you get the red squiggly underFind
, right click the word and then you should be able to pick Resolve -> System.Data.Entity.A guide to posting questions on CodeProject[^]
Dave Kreskowiak -
You have to import the
System.Data.Entity
namespace at the top of the code file. If you get the red squiggly underFind
, right click the word and then you should be able to pick Resolve -> System.Data.Entity.A guide to posting questions on CodeProject[^]
Dave KreskowiakI've done all of that Dave, and I still get the red squiggly. It's got to be something to do with the version of the System.data.entity dll that I'm importing. EF reports that it's using version 6, but the DLL reports version 4. I'll keep trying, but until then, I'll use the version that works, but I can't help feeling that i's going to get up and bite me one day.
-
I've done all of that Dave, and I still get the red squiggly. It's got to be something to do with the version of the System.data.entity dll that I'm importing. EF reports that it's using version 6, but the DLL reports version 4. I'll keep trying, but until then, I'll use the version that works, but I can't help feeling that i's going to get up and bite me one day.
If you've got a mismatch like that, something went terribly wrong. Go to the Package Manager Console and do a
Uninstall-Package EntityFramework
. Then go through the References in the project and remove theEntityFramework
reference if it's still there. Once that's done, you can go back to the Package Manager Console and do aInstall-Package EntityFramework". That should take care of any mismatches. [A guide to posting questions on CodeProject](http://www.codeproject.com/scrapbook/ForumGuidelines.asp)[[^](http://www.codeproject.com/scrapbook/ForumGuidelines.asp "New Window")] **Dave Kreskowiak**
-
If you've got a mismatch like that, something went terribly wrong. Go to the Package Manager Console and do a
Uninstall-Package EntityFramework
. Then go through the References in the project and remove theEntityFramework
reference if it's still there. Once that's done, you can go back to the Package Manager Console and do aInstall-Package EntityFramework". That should take care of any mismatches. [A guide to posting questions on CodeProject](http://www.codeproject.com/scrapbook/ForumGuidelines.asp)[[^](http://www.codeproject.com/scrapbook/ForumGuidelines.asp "New Window")] **Dave Kreskowiak**
Thanks Dave, will do.
-
If you've got a mismatch like that, something went terribly wrong. Go to the Package Manager Console and do a
Uninstall-Package EntityFramework
. Then go through the References in the project and remove theEntityFramework
reference if it's still there. Once that's done, you can go back to the Package Manager Console and do aInstall-Package EntityFramework". That should take care of any mismatches. [A guide to posting questions on CodeProject](http://www.codeproject.com/scrapbook/ForumGuidelines.asp)[[^](http://www.codeproject.com/scrapbook/ForumGuidelines.asp "New Window")] **Dave Kreskowiak**
I've been battling since Tuesday to fix this Dave. (sorry for taking so much of your time), I've done what you detailed above, but still the 'find' method isn't recognised. Funny thing though, the text I get when I try to use the method is: "Error 1 'System.Data.Objects.ObjectSet' does not contain a definition for 'find' EntityResearch...." I thought the find method would be in System.Data.Entity? I've gone so far as repairing my .NET 4.5 but that didn't work either.
-
I've been battling since Tuesday to fix this Dave. (sorry for taking so much of your time), I've done what you detailed above, but still the 'find' method isn't recognised. Funny thing though, the text I get when I try to use the method is: "Error 1 'System.Data.Objects.ObjectSet' does not contain a definition for 'find' EntityResearch...." I thought the find method would be in System.Data.Entity? I've gone so far as repairing my .NET 4.5 but that didn't work either.
Repairing anything isn't going to do anything for you. Nothing is broken except your code. There are multiple Find methods. The one that works on DbSets is in System.Data.Entity. If it's saying the you're using the System.Data.Objects namespace version, you're not using Entity Framework. Your entity sets have been defined using ObjectSet instead of DbSet.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak -
Repairing anything isn't going to do anything for you. Nothing is broken except your code. There are multiple Find methods. The one that works on DbSets is in System.Data.Entity. If it's saying the you're using the System.Data.Objects namespace version, you're not using Entity Framework. Your entity sets have been defined using ObjectSet instead of DbSet.
A guide to posting questions on CodeProject[^]
Dave KreskowiakHow can I define my entity sets using DbSet then? To all intents and purposes I am using Entity framework, it's calling it up in app.config, and in the references, so what can be going wrong?
-
How can I define my entity sets using DbSet then? To all intents and purposes I am using Entity framework, it's calling it up in app.config, and in the references, so what can be going wrong?
Using CodeFirst, in your DbContext derived class:
public DbSet MyTableName { get; set; }
A guide to posting questions on CodeProject[^]
Dave Kreskowiak -
Using CodeFirst, in your DbContext derived class:
public DbSet MyTableName { get; set; }
A guide to posting questions on CodeProject[^]
Dave KreskowiakThanks Dave, But what If I'm using DB first?
-
Thanks Dave, But what If I'm using DB first?
Wait, you mentioned EF 4.0 .DLL's, correct? Is this an old EF 4.0 project you're upgrading?? If so, see Upgrading to EF6[^].
A guide to posting questions on CodeProject[^]
Dave Kreskowiak -
Wait, you mentioned EF 4.0 .DLL's, correct? Is this an old EF 4.0 project you're upgrading?? If so, see Upgrading to EF6[^].
A guide to posting questions on CodeProject[^]
Dave KreskowiakNo, I started a new project to test the find method, before I used it in one of my operational ones. My app.config looks like this:
but the version of Sysytem.Data.Entity.Dll reports back as being version 4. I've downloaded a version 5 of this DLL, but even that r4ports that it's version 4.0
-
Wait, you mentioned EF 4.0 .DLL's, correct? Is this an old EF 4.0 project you're upgrading?? If so, see Upgrading to EF6[^].
A guide to posting questions on CodeProject[^]
Dave KreskowiakI started a new project to test the find method, and I'm still getting the problem. My app.config looks like this:
The System.Data.Entity DLL reports as being version 4.0. I downloaded a version 5.0 of this DLL, but even that reports as version 4.0
-
Wait, you mentioned EF 4.0 .DLL's, correct? Is this an old EF 4.0 project you're upgrading?? If so, see Upgrading to EF6[^].
A guide to posting questions on CodeProject[^]
Dave KreskowiakI've found what I've been doing wrong Dave. When I've been adding the Entity Data model when I started the project, I've been deleting the two .tt template files and setting the code generation strategy in the edmx properties to 'default'. This hasn't been generating the (correct) code to use dBSet. I've still got a lot to learn yet about this, as it's opened a few more cans of worms for me, (For example, what happened to my 'AddObject' methods?) This highlights my original point. I'm a freelance developer, and have been for about 10 years now. I work by myself, and I have no-one to bounce ideas off, or show me my mistakes. I learnt EF by buying Julia Lerman's book and studying enough of it to get my current project up and running, but not going any further. When I worked for a software house in England, I used to dread code review day, but I can see now how useful it was. I know I'm still missing a lot, and I would be grateful if you could point me to a good tutorial about the correct way to deal with Entity Framework, and .tt files and all. Thanks for all your patience Dave, it's been much appreciated. George
-
I've found what I've been doing wrong Dave. When I've been adding the Entity Data model when I started the project, I've been deleting the two .tt template files and setting the code generation strategy in the edmx properties to 'default'. This hasn't been generating the (correct) code to use dBSet. I've still got a lot to learn yet about this, as it's opened a few more cans of worms for me, (For example, what happened to my 'AddObject' methods?) This highlights my original point. I'm a freelance developer, and have been for about 10 years now. I work by myself, and I have no-one to bounce ideas off, or show me my mistakes. I learnt EF by buying Julia Lerman's book and studying enough of it to get my current project up and running, but not going any further. When I worked for a software house in England, I used to dread code review day, but I can see now how useful it was. I know I'm still missing a lot, and I would be grateful if you could point me to a good tutorial about the correct way to deal with Entity Framework, and .tt files and all. Thanks for all your patience Dave, it's been much appreciated. George
The best out there are Julia's books. I have them all and am going the CodeFirst route on my current project. I've been working on this one for the last year and will probably be doing it for another.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak