How to implement in EF5 a KeyTable style identity method
"Uses a table in the database to store the next Id, and advances this value every time a new block of Ids is required" from LightSpeed
I believe this is like Oracle sequences.
This feels like it should be easy (as it is in LightSpeed). This gives the ORM an easy way to do bulk inserts ie it can get 10 identities at a time, then do a bulk insert back to the db.
Am using EF5 / WCF RIA Services (latest) talking to Silverlight. The rest of the project uses bulk insert SSIS stuff.. and the SL project does some inserting. So I need to follow this convention.
I guess the question is fundamentally more about whether Entity Framework can support this style of key generation, and a secondary part of the question is whether RIA Services would integrate OK with that.
It reminds me of the range of key generation strategies that are available in NHibernate.
Here's an answer here which suggests that EF does not have such full support as NHibernate 'out of the box':
Unfortunately, EF doesn't have anything very close to the POID
generators like NHibernate does, although I hear rumors that similar
capabilities will be included in the next release of EF.
from HiLO for the Entity Framework
This answer suggests that it's not too tricky to intercept a Save (specifically an insert) in RIA Services and call a SPROC to get the new ID
you only need to call stored procedure to get a value before you are
going to save the record [can put this into an] overriden
SaveChanges() in your context
see https://stackoverflow.com/a/5924487/5351 in answer to What is the best way to manually generate Primary Keys in Entity Framework 4.1 Code First
and a similar answer here... https://stackoverflow.com/a/5277642/5351
Here are some findings on possibly implementing a HiLo generator (a more robust key gen pattern) with EF:
The Hi/Lo pattern describe a mechanism for generating safe-ids on the
client side rather than the database. Safe in this context means
without collisions. This pattern is interesting for three reasons:
It doesn’t break the Unit of Work pattern (check this link and this other one)
It doesn’t need many round-trips as the Sequence generator in other DBMS.
It generates human readable identifier unlike to GUID techniques.
from http://joseoncode.com/2011/03/23/hilo-for-entityframework/
Related
In my spare time, I'm trying restart my effort to learn F#. I'm doing so by trying to create a simple application that will allow me to analyze my financial transactions.
My first attempt at creating this application failed due to the persistence step. I used SQL and the EntityFramework package, but the latter generated database entities, which I did not want to use throughout my application since they're all mutable (I think..). Instead I had to map these database entities to domain entities. Much manual glue code later it worked....until I found a bug and was forced to replace much of that glue code. That was the tipping point that made me quit.
On SO I found a question describing my situation, e.g. Saving F# types to a database. Mark Seeman suggested that the pain of mapping can be overcome if I'd not use objects for persistence. At work I have recently been introduced to MongoDb, which at least saves me the pain of mapping from database entities to domain entities. These entities all need some ID, and I chose to use an ObjectId from Mongo. Ooops, there comes the deja vu, in order not to have my domain entities being dependent on Mongo, I will once more have to create database and domain entities....as well as the mapping. Bah & Ugh.
In C# I'm used to do such mapping with tools like Automapper, but they don't really work for special F# types. So now I'm wondering what Mark Seeman ment by "using objects for persistance". How is this solved in F#? So far I haven't been able to fine more info on this topic besides the aforementioned question on SO.
So it turns out that I am the last person to discover the fundamental floor that exists in Microsoft's Entity Framework when implementing TPT (Table Per Type) inheritance.
Having built a prototype with 3 sub classes, the base table/class consisting of 20+ columns and the child tables consisting of ~10 columns, everything worked beautifully and I continued to work on the rest of the application having proved the concept. Now the time has come to add the other 20 sub types and OMG, I've just started looking the SQL being generated on a simple select, even though I'm only interested in accessing the fields on the base class.
This page has a wonderful description of the problem.
Has anyone gone into production using TPT and EF, are there any workarounds that will mean that I won't have to:
a) Convert the schema to TPH (which goes against everything I try to achieve with my DB design - urrrgghh!)?
b) rewrite with another ORM?
The way I see it, I should be able to add a reference to a Stored Procedure from within EF (probably using EFExtensions) that has the the TSQL that selects only the fields I need, even using the code generated by EF for the monster UNION/JOIN inside the SP would prevent the SQL being generated every time a call is made - not something I would intend to do, but you get the idea.
The killer I've found, is that when I'm selecting a list of entities linked to the base table (but the entity I'm selecting is not a subclass table), and I want to filter by the pk of the Base table, and I do .Include("BaseClassTableName") to allow me to filter using x=>x.BaseClass.PK == 1 and access other properties, it performs the mother SQL generation here too.
I can't use EF4 as I'm limited to the .net 2.0 runtimes with 3.5 SP1 installed.
Has anyone got any experience of getting out of this mess?
This seems a bit confused. You're talking about TPH, but when you say:
The way I see it, I should be able to add a reference to a Stored Procedure from within EF (probably using EFExtensions) that has the the TSQL that selects only the fields I need, even using the code generated by EF for the monster UNION/JOIN inside the SP would prevent the SQL being generated every time a call is made - not something I would intend to do, but you get the idea.
Well, that's Table per Concrete Class mapping (using a proc rather than a table, but still, the mapping is TPC...). The EF supports TPC, but the designer doesn't. You can do it in code-first if you get the CTP.
Your preferred solution of using a proc will cause performance problems if you restrict queries, like this:
var q = from c in Context.SomeChild
where c.SomeAssociation.Foo == foo
select c;
The DB optimizer can't see through the proc implementation, so you get a full scan of the results.
So before you tell yourself that this will fix your results, double-check that assumption.
Note that you can always specify custom SQL for any mapping strategy with ObjectContext.ExecuteStoreQuery.
However, before you do any of this, consider that, as RPM1984 points out, your design seems to overuse inheritance. I like this quote from NHibernate in Action
[A]sk yourself whether it might be better to remodel inheritance as delegation in the object model. Complex inheritance is often best avoided for all sorts of reasons unrelated to persistence or ORM. [Your ORM] acts as a buffer between the object and relational models, but that doesn't mean you can completely ignore persistence concerns when designing your object model.
We've hit this same problem and are considering porting our DAL from EF4 to LLBLGen because of this.
In the meantime, we've used compiled queries to alleviate some of the pain:
Compiled Queries (LINQ to Entities)
This strategy doesn't prevent the mammoth queries, but the time it takes to generate the query (which can be huge) is only done once.
You'll can use compiled queries with Includes() as such:
static readonly Func<AdventureWorksEntities, int, Subcomponent> subcomponentWithDetailsCompiledQuery = CompiledQuery.Compile<AdventureWorksEntities, int, Subcomponent>(
(ctx, id) => ctx.Subcomponents
.Include("SubcomponentType")
.Include("A.B.C.D")
.FirstOrDefault(s => s.Id == id));
public Subcomponent GetSubcomponentWithDetails(int id)
{
return subcomponentWithDetailsCompiledQuery.Invoke(ObjectContext, id);
}
I read an old MSDN Forums post about Entity Framework where Julie Lerman stated:
wrt Stored Procedures. This is even
better than what you are referring to.
Not only can you map to sprocs (both
in EF and in LINQ to SQL) or override
the update/insert/delete methods, but
in EF, there is coming a capability to
CREATE stored procedures right in the
mapping layer. Not create them and add
them into the db, but just have them
live in the EDM. So the sproc doesn't
have to exist in the db.
This is not in the March bits, but I
saw a demo of it last week and we will
have it in the next CTP.
I want to see a demo of how this works, but it is excruciatingly hard to jump into such a huge framework and all of its documentation, and discover how to look at a single feature. From best as I can tell, Entity Framework is not dynamic enough to support the scenarios I want, at least not yet, but there are features discussed for future versions of EF that fit my needs. For now I am using a hand-rolled query generator, since the ORM features of EF do not fit my needs and I really just want an awesome query generator and the ability to create stored procedures and serialize Parameterized Queries.
Bottom line: So how does Entity Framework create stored procedures "live" without them existing a priori in the database? Is it customizable? How does it handle changes to the conceptual layer? And why would the mapping layer own this logic? Or is Julie just referring to something gross like T4 Templates (YUCK!!!)?
Julie's post seems a little vague. If it's not in the DB, it's not a "stored proc" as most people know it. I don't think she meant generate a proc; I don't think you can do that today, and I know you couldn't do it in 2007. Nor was T4 in use in 2007.
She may have been talking about EdmFunction, but it's hard to tell. She's pretty active on Twitter, so you could just ask her what she meant.
Does the Entity Framework 4 support generators for id values like NHibernate? NHibernate has generator classes to help with this.
EF4 supports whatever the back-end server supports:
IDENTITY columns or GUID columns with default values (newid(), newsequentialid()) in SQL Server
Sequences in Oracle
whatever other mechanism the target database might provide
EF4 itself doesn't have any built-in support for generators of any kind, as far as I know.
I'm not sure if making this the ORM's responsibility is a good idea, quite honestly. This should really be left to the backend store to handle, in my opinion.
However, you should have no trouble implementing your own custom ID generator in .NET code, and plug that into EF4, if you wish to do so.
This question is an extension of another question, but I think it warrants its own thread. See See Silverlight Question
I have a stored procedure (SQL 2005) that returns a dynamic data set (different columns/schema) each time it is called.
I want to consume this in Silverlight 3.0 so I need to somehow wire this up using Entity Framework and RIA Services. I also need this to be Bindable (Silverlight Grid) so I need these dynamic columns to be accessible via properties (grid limitation). Any ideas?
In the currently shipping version of the Entity Framework, the only type of stored procedures you can map are those which return entity types. The mapping is done, generally, before you compile, although it seems at least theoretically possible to generate Entity Framework metadata at runtime.
Therefore, I see a few choices.
Give up on the whole idea of consuming a procedure which does not return a defined schema. You will never be able to map such a procedure before you compile.
Dynamically generate EDMX at runtime in order to map an entity type to the expected output columns of the procedure before you invoke. Note that the current version of the Entity Framework is a bit finicky about the columns a procedure returns; you can find documentation about this on MSDN.
In .NET 4.0, there are new features which allow you to inform the Entity Framework about your client schema at runtime without having to generate EDMX first. You might be able to leverage these features in order to map some entity type to the expected output columns of the procedure.
Again, in .NET 4.0, there may be support for procs which return scalar values. I can't remember if this is the case or not.
You can always get a standard database connection from the entity connection and execute the procedure directly, using regular SqlCommands. Unfortunately, this makes your code database-provider-specific, but it may be the simplest solution to your problem. Indeed, using such a procedure at all is already database-server-specific.
You might use a WCF web service wraper for accesing your SP and use the WCF service as data source Brad Abrams has a way to do that on his series of articles on RIA Services