- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
Entity Framework vs LLBLGEN
Joined: 15-Jul-2006
Agreed, althought I think they will support the databases that ado.net supports.
One thing I know is that it does not support mapping to different databases within the same context. I think you would just make a different one. Not that big of a deal.
Joined: 17-Aug-2003
BringerOD wrote:
Agreed, althought I think they will support the databases that ado.net supports.
One thing I know is that it does not support mapping to different databases within the same context. I think you would just make a different one. Not that big of a deal.
I don't think it's a small deal. We have some customers who have 1 project with several databases and can now define relations between entities across those databases. THis is very handy when working with data in 1 application.
Here's a (small) list of limitations of the entity framework so far: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2626244&SiteID=1
Their eager loading system is very limited, string based and can't handle all scenario's. Also their designer is flawed: they require all entities to be part of the same model and part of the same designer canvas. This is terrible if you have a project which spans more than, say 50, entities or so. They also generate all code in one file, and that's not a good thing also.
It's a v1 tool, as they say, however what I find a bit odd is that there is SO MUCH work done in the past 20 years in this area that they can't come out with a toolkit which lacks essential features everybody else has and still call it an earth-shaking invention. I mean, we're a small company, I more or less wrote llblgen pro on my own, and they work with 100+ people on this, it shouldn't be a match at all, but in practise they can't really bring something to the table which doesn't need the excude 'it's a v1 product'. Oh well, more room for us
Joined: 15-Jul-2006
I appreciate the feedback. I have been using LLBLGen for 3 years now with great success. I ask the question becuase the topic of tools of this nature is large and complex. Its hard to find and read all the blogs and articles on this subject and get a honest comparision and evaluation of the products.
Joined: 17-Aug-2003
BringerOD wrote:
I appreciate the feedback. I have been using LLBLGen for 3 years now with great success. I ask the question becuase the topic of tools of this nature is large and complex. Its hard to find and read all the blogs and articles on this subject and get a honest comparision and evaluation of the products.
The entity framework has some things which llblgen pro will get in v3, like value types ('address' as separate object inside 'customer' for example), though their intermediate mapping layer is interesting as well and I don't think we'll be implementing that, as it's IMHO also a bit over the top: one can also simply bite the bullet and be a bit more flexible and write the code that works with the db at hand instead of insisting that the code has to be in model ABC and thus requires an intermediate layer: databases often last longer than code.
Joined: 04-Apr-2007
Thought I would respond since I have just started a project where I wanted to use Entity Framework (The requestor had a requirement where no third party components should be used.)
I won't go into everything but I will list a few of the problems with the Entity Framework.
1) The designer will try to detected computed fields however if you have an updated on field that has its value set by a trigger you can't specify that in the designer. You have to modify that in the xml document. If you dont and create a new entity, it will persit the datetime value whether or not you have changed the value. Datetime fields are assigned DateTime.Min and SQL 2005 will throw an exception with DateTime.Min so you are left with always having to update that property unless you modify the xml file manually.
2) The marriage between an entity and its original datacontext is a complete pain. First, creating a datacontext and getting an entity marries that entity to that instance of the datacontext. If you try to attach the entity to a different context to either save its changes or attach it to another entity from another datacontext you will get an exception. (Think about web development where you might want to cache entities to use them later) You have to either call the detach method on the original datacontext or cast the entity to the IEntityWithKey interface to change the status of the entity. It is a complete pain. Instead, you could go back an retreive the entity again with the new datacontext but where is the performance tuning in that.
Second, when retreiving an entity from the datacontext, the OnPropertyChanged methods for each entity property are called before the entity is actually attached to a context. So if you want to pull the line items for an order to prepopulate properties on the entity when it is retreived from the database you can't. You will get an exception that the entity is detached.
3) How in the world can you forget about SQL_Variant. I will not even go into it.
4) Updating the model from the designer doesn't work very well.
5) Their use of partial methods is nice but they can't be overridden, so when you have an inheritance model you have to do double the work. This point is negligible as it has a work around.
6) There are no foreign key properties. AARARRRARARRGGGGGGGG. Therefore you are forced to pull an entity from the database and it has to be attached to the current context to save a relationship.
Entity framework makes it very difficult to save and update relationships between entities.
That is my own personal opinion so take it as is.
Joined: 17-Aug-2003
Thanks for the list!
Brandt wrote:
Thought I would respond since I have just started a project where I wanted to use Entity Framework (The requestor had a requirement where no third party components should be used.)
I won't go into everything but I will list a few of the problems with the Entity Framework.
1) The designer will try to detected computed fields however if you have an updated on field that has its value set by a trigger you can't specify that in the designer. You have to modify that in the xml document. If you dont and create a new entity, it will persit the datetime value whether or not you have changed the value. Datetime fields are assigned DateTime.Min and SQL 2005 will throw an exception with DateTime.Min so you are left with always having to update that property unless you modify the xml file manually.
Their designer is indeed pretty much.... a piece of crap, considering what they COULD have produced. I'm not sure what they were thinking but my guess is that they tried a lot of different things (I saw at least 2 different UI's which didn't make it) and in the end ran out of time.
2) The marriage between an entity and its original datacontext is a complete pain. First, creating a datacontext and getting an entity marries that entity to that instance of the datacontext. If you try to attach the entity to a different context to either save its changes or attach it to another entity from another datacontext you will get an exception. (Think about web development where you might want to cache entities to use them later) You have to either call the detach method on the original datacontext or cast the entity to the IEntityWithKey interface to change the status of the entity. It is a complete pain. Instead, you could go back an retreive the entity again with the new datacontext but where is the performance tuning in that.
They have looked closely at nhibernate I think, and haven't thought about a distributed disconnected scenario where entities lose their changes once you disconnect them from the almighty context. It's the classical Scott Ambler design of an o/r mapper but it also has it's weaknesses.
What's odd is that apparently they didn't have a single person on the project who stood up and said "this isn't going to work in a distributed scenario". From the start of llblgen pro I built changetracking inside the entities for precisely this reason. Of course, POCO then gets in the way, but so be it.
Second, when retreiving an entity from the datacontext, the OnPropertyChanged methods for each entity property are called before the entity is actually attached to a context. So if you want to pull the line items for an order to prepopulate properties on the entity when it is retreived from the database you can't. You will get an exception that the entity is detached.
Why would anyone want to have PropertyChanged events when you retrieve an entity? Nothing could possibly be bound to it IMHO.
3) How in the world can you forget about SQL_Variant. I will not even go into it.
hehe but then again... who uses SQL_Variant?
4) Updating the model from the designer doesn't work very well.
True, though they also don't have much choice in some scenario's where it doesn't work well. The main problem is that if you start with an entity and then map it onto something, and you change the meta-data through a refresh, what do you do? It's very complex to track all manual changes and leave them alone as it might be the user did manually change things but now wants to have things updated by the system.
5) Their use of partial methods is nice but they can't be overridden, so when you have an inheritance model you have to do double the work. This point is negligible as it has a work around.
their choice of code generation is really short sighted: everything in 1 file (imagine an enterprise app with 500 entities in such a file) and the context gets a LOOOOOOOOOOT of methods, a couple for every entity...
the partial method crap is simply stupidity introduced by the C# team due to their stubborn refusal of doing REAL AOP so they ran into a problem with linq to sql and hacked around it with partial methods, and the EF used them too, but actually, partial methods should be removed from the language altogether.
Let's hope that due to the EF becoming POCO that the CLR will get AOP constructs or better: a class loader you can extend so you can alter IL on the fly.
6) There are no foreign key properties. AARARRRARARRGGGGGGGG. Therefore you are forced to pull an entity from the database and it has to be attached to the current context to save a relationship.
Heh Classic Ambler again. Some people really like it though, however I find it a bit farfetched. In v3 of llblgen pro, the entities also don't have FK fields in the entity model, simply because it makes no sense: Customer 1:n Order, the FK in order is the PK in customer. However as soon as you are going to map, they'll be there and in the code they'll be there too. It makes life so much easier when you work with them to DO things, but when you DEFINE them, they're not really handy. However their transition from 'model' to 'code' is really straight forward.
Joined: 29-Jan-2006
Hi Frans,
What's odd is that apparently they didn't have a single person on the project who stood up and said "this isn't going to work in a distributed scenario". From the start of llblgen pro I built changetracking inside the entities for precisely this reason. Of course, POCO then gets in the way, but so be it.
I did never understand this, too. No multitier support? WTF?
the partial method crap is simply stupidity introduced by the C# team due to their stubborn refusal of doing REAL AOP so they ran into a problem with linq to sql and hacked around it with partial methods, and the EF used them too, but actually, partial methods should be removed from the language altogether.
I can see partial methods together with code generation. Perhaps they are not the best solution out there but they do help a lot with extending generated code. On the other side, AOP might be tricky to understand and debug, etc. etc. Nevertheless it would be nice to have some sort of AOP handy.
Joined: 04-Apr-2007
Otis wrote:
Why would anyone want to have PropertyChanged events when you retrieve an entity? Nothing could possibly be bound to it IMHO.
Data was stored as XML in the database and additional properties were added to the entity to return the values of specific xml elements. Each property could have created a new XmlDocument from the xml string but the performance was rather slow so a single XmlDocument was created when the xmldata property changed. This was to make sure the XmlDocument object was always current. It could have been done other ways however the result uncovered the DataContext / property changed problem.
hehe but then again... who uses SQL_Variant?
I use it only for an Attribute table. The Attribute table has a related AttributeTemplate table that defines the data type, default values and range of the attribute. It works very well for storing additional property information for an entity with out having to modify the database. You can always use a varchar and then convert to the datatype but sql_variant works very well so why change it.
I did forget to include the problem with using uniqueidentifiers as a primary key field. When using EF you can't use newid() or newsequentialId() to generate unique ids for uniqueidentifier columns because EF does not know how to refetch the key. The only way it works is if you use Guid.New() on the client side before it is saved to the server. That sucks.
LLBLGEN is still way ahead of the game!
Joined: 17-Aug-2003
mihies wrote:
What's odd is that apparently they didn't have a single person on the project who stood up and said "this isn't going to work in a distributed scenario". From the start of llblgen pro I built changetracking inside the entities for precisely this reason. Of course, POCO then gets in the way, but so be it.
I did never understand this, too. No multitier support? WTF?
It's a hard problem though: if you follow Ambler's design, distributed scenario's are a big problem, and to solve it, you effectively have to abandone that design.
the partial method crap is simply stupidity introduced by the C# team due to their stubborn refusal of doing REAL AOP so they ran into a problem with linq to sql and hacked around it with partial methods, and the EF used them too, but actually, partial methods should be removed from the language altogether.
I can see partial methods together with code generation. Perhaps they are not the best solution out there but they do help a lot with extending generated code. On the other side, AOP might be tricky to understand and debug, etc. etc. Nevertheless it would be nice to have some sort of AOP handy.
Partial methods are really a hack IMHO, as they're nothing more than a virtual method in a base class which isn't there because they avoid base classes (but the net effect is the same). The limitations on the partial methods are simply too high. (e.g. I don't see use for them in our code)
Brandt wrote:
hehe but then again... who uses SQL_Variant?
I use it only for an Attribute table. The Attribute table has a related AttributeTemplate table that defines the data type, default values and range of the attribute. It works very well for storing additional property information for an entity with out having to modify the database. You can always use a varchar and then convert to the datatype but sql_variant works very well so why change it.
Ok Sql_variant always gave me the VB5/6 variant feeling: it's a great bucket to store various data in, but it always gave the hint that some day you'd regret the decision of using a variant instead of a stronger type
I did forget to include the problem with using uniqueidentifiers as a primary key field. When using EF you can't use newid() or newsequentialId() to generate unique ids for uniqueidentifier columns because EF does not know how to refetch the key. The only way it works is if you use Guid.New() on the client side before it is saved to the server. That sucks. LLBLGEN is still way ahead of the game!
heh Well, NEWID() is problematic though, one can't retrieve the value generated back from the DB, but for newsequentialID() it is possible. It surprises me they didn't build support for that into EF, considering they cooked up the newsequentialid() thing in the first place!
Joined: 29-Jan-2006
Hi Frans,
Partial methods are really a hack IMHO, as they're nothing more than a virtual method in a base class which isn't there because they avoid base classes (but the net effect is the same). The limitations on the partial methods are simply too high. (e.g. I don't see use for them in our code)
In terms of performance are better than virtual methods. The same is true for the footprint (if nobody uses them no code is created). As per your code, here is an example:
protected virtual void InitClassEmpty(IValidator validator, IEntityFields2 fields)
{
...
// __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty
// __LLBLGENPRO_USER_CODE_REGION_END
...
}
You are "forcing" people to write into the generated file which isn't the best practice IMO. True, code is preserved but it is mixed with autogenerated code. Instead you could write something like (out of my head):
protected virtual void InitClassEmpty(IValidator validator, IEntityFields2 fields)
{
...
InitClassEmptyCustom(validator, fields);
...
}
internal partial void InitClassEmptyCustom(IValidator validator, IEntityFields2 fields);
This way it would be easy to add the custom code in partial class instead of mixing it with autogenerated one. Furthermore you could get rid of your stubs (__LLBLGENPRO_USER_CODE_REGION_START/__LLBLGENPRO_USER_CODE_REGION_END) and don't bother with them anymore.
Joined: 17-Aug-2003
mihies wrote:
Hi Frans,
Partial methods are really a hack IMHO, as they're nothing more than a virtual method in a base class which isn't there because they avoid base classes (but the net effect is the same). The limitations on the partial methods are simply too high. (e.g. I don't see use for them in our code)
In terms of performance are better than virtual methods. The same is true for the footprint (if nobody uses them no code is created). As per your code, here is an example:
protected virtual void InitClassEmpty(IValidator validator, IEntityFields2 fields) { ... // __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty // __LLBLGENPRO_USER_CODE_REGION_END ... }
You are "forcing" people to write into the generated file which isn't the best practice IMO. True, code is preserved but it is mixed with autogenerated code. Instead you could write something like (out of my head):
protected virtual void InitClassEmpty(IValidator validator, IEntityFields2 fields) { ... InitClassEmptyCustom(validator, fields); ... } internal partial void InitClassEmptyCustom(IValidator validator, IEntityFields2 fields);
This way it would be easy to add the custom code in partial class instead of mixing it with autogenerated one. Furthermore you could get rid of your stubs (__LLBLGENPRO_USER_CODE_REGION_START/__LLBLGENPRO_USER_CODE_REGION_END) and don't bother with them anymore.
True. The thing is thought that these regions are really for people who work with .NET 1.x, as .NET 2.x+ can use partial classes and override the On* methods which are there for extensibility (so .NET 2.x users are never forced to use these regions actually)
IF we didn't have a base class, your setup would indeed be a choice to consider. However, if there's a base class, why not use it? I don't think the 1-2ms it takes extra to call a virtual method is really worth the trouble, or are virtual methods so slow?
For example: why didn't MS generate a base class with virtual methods instead and derive the entity classes from that, implementing only the ones they needed? If they're so concerned about performance, they should have implemented their hierarchical fetch system properly. .
Anyway, not to bash your argument, miha . Your point is valid and I agree with that, however I think we're in a different situation and it's not the only solution out there (our factories for example use a generated base class which makes code less bloathed. It's a solution to the same problem, AND it works on .NET 2.x, the platform most people are still working with). For them it's not a problem as they're on .net 3.5 only, but for us it's a maintenance problem as well to have 2 different template sets, one for .net 2.x and one for .net 3.5.
Joined: 29-Jan-2006
Another bonus for the partial methods might be the case when different autogenerated classes have different capabilities (they have different custom methods to call or they could pass strongly typed arguments). If you have this problem then even having a base class doesn't help you - would you implement virtual methods for every occurence?
But yes, in the case of LLBLGenPro, due to the legacy and maintenance reasons it is a problem and even implementing them wouldn't yield important advantage if any.
Joined: 17-Aug-2003
mihies wrote:
Another bonus for the partial methods might be the case when different autogenerated classes have different capabilities (they have different custom methods to call or they could pass strongly typed arguments). If you have this problem then even having a base class doesn't help you - would you implement virtual methods for every occurence?
Indeed, that is a good point.
As ironic as it might sound, being a developer of a system which generates code, I'm always looking for a solution which requires LESS code to be generated (so more code to be moved into a base class). One core reason is that maintaining templates is often not that easy, until the code become stable (from then on it's code which requires little maintenance: we have almost no changes in templates after release though we do have the occasional bug in the runtime libs).
Joined: 29-Jan-2006
Otis wrote:
As ironic as it might sound, being a developer of a system which generates code, I'm always looking for a solution which requires LESS code to be generated (so more code to be moved into a base class). One core reason is that maintaining templates is often not that easy, until the code become stable (from then on it's code which requires little maintenance: we have almost no changes in templates after release though we do have the occasional bug in the runtime libs).
I fully understand you. I quite often work with code generators, specially CodeSmith (besides LLBLGenPro). And I've come to the same conclusion - it is easier to provide code within base class and autogenerate as less as possible. As long as it makes sense of course.
Joined: 17-Aug-2003
I was watching the EF v2 presentation from the PDC 2008 and at the end, some people asked questions about elements which were brought up in this same thread. Were you guys the ones asking the questions?
It was shocking to see that they didn't have a solid answer. They don't realize that if one scratches the chrome of their demoware designer, it shouldn't be rust that's showing but solid steel.