Our product is partially built using Delphi and partially .NET and in our current state of migration to .NET, we have the data dictionary in a Delphi component, so this is the master.
From this we generate .NET source code through templating, to support simple querying but also to do Linq2Sql, since our product requires SQL Server.
However, I'd like to switch to the new Entity model in .NET instead of Linq2Sql, but I don't know how much work that would be. All the tutorials or examples I find seem to revolve around modelling the data model in the designer, or getting it from the database, neither works for our needs.
In Linq2Sql, we annotated our query-classes with TableMappingAttribute and ColumnMappingAttribute, and then generated a descendant of DataContext, this all works very well.
Is there a similar easy path to get to use the Entity model code instead? Or do I have to produce all those xml files and run tools to produce resources, etc.?
Has anyone been in the same situation and can shed some light on this?
Unfortunately for you I think you do need the XML files.
There are actually 3 files that make up the EDM. (although in visual studio they are all combined into 1 EDMX file)
ssdl - storage (Describes the database)
csdl - conceptual (Describes data objects)
msl - mapping (Describes the mapping between storage and conceptual)
From the EDM files, the EDM Generator can be used to generate all three from a database connection, just the msl and csdl from the ssdl, or it can generate the actual data objects from the csdl.
Unfortunately though, that isn't where the usage of the XML stops. It is still needed at runtime for the entity framework to perform the translation from objects to storage etc. A reference to the 3 EDM files must be provided in the Entity framework connection string. (More info on building EF connection strings)
You could probably come up with ways to have your data object code generated (or automatically tag your existing ones with the various required attributes and extra methods) - like Linq there are attributes like EdmEntityTypeAttribute and EdmScalarPropertyAttribute that are put on the classes and properties, but without the 3 EDM files the entity framework isn't going to know what to do with your data objects. The generator also adds other stuff to the data objects classes like property changed events, and an inheritance from EntityObject. I'm not sure what of the extra stuff is required for correct operation of the entity framework, and what is just there for the developer. I would assume the property changes events are required by the data context to track changes.
There's an article here on EDM tools and some code for generating/splitting EDMX files into their component ssdl/csdl/msl files.
Related
I have been tasked with upgrading our software to use EF6. Previously it was using a combination of EF4 & 5.
We use the database first approach. The upgrade went smoothly as far a code changes go, but after running the application and doing a query the following error is thrown.
Schema specified is not valid. Errors:
The mapping of CLR type to EDM type is ambiguous because multiple CLR types match the EDM type 'tblAccountMaintenance'.
Previously found CLR type 'DALUsers.StatusDB.tblAccountMaintenance', newly found CLR type 'DALUsers.AccountsDB.tblAccountMaintenance'.
The class in questions, tblAccountMaintenance, is generated inside multiple .tt files. The classes are references to the same table, just referenced in different .edmx files.
Simply removing one of the references is not a good option in this case as we have used a similar strategy with several other tables and would require thousands of lines of rewritten code.
What do I need to do to fix this in EF6?
So it turns out the the issue (using the same tables, with the same name in multiple edmx files in the same project) is related to the fact the the .tt files contain new objects that derive from dbContext - and this is a limitation/constraint that is specific to dbContext.
I downloaded this plugin: https://visualstudiogallery.msdn.microsoft.com/66612113-549c-4a9e-a14a-f629ceb3f89a
Which allows me to create EF6 .tt files that derive from EnityObject instead which does not have this constraint. It also makes it so I don't have to update all of my code to use the newer dbContext methods which is a plus.
As a note to others viewing this - this is probably not the best answer if you are starting with a newer project or have a small number of edmx files/tables as EntityObject is not as robust as dbContext, however this is a good band-aid fix - especially if you are like me and going to have to do a complete rewrite when EF7 comes out.
I'm building an application using EF 5 to talk to an existing Oracle database. I'm not allowed to change any part of the DB schema. I have generated my model from the database using the VS2012 wizard, and all classes are named after their Oracle counterparts.
The naming of objects in the database is QUITE_UGLY_AND_INCONSISTENT, so I'd like to rename the POCO classes and properties. I can easily do that from the EDM Designer. As a result, I get neatly named class and property names, that are mapped to the UGLY_NAMED tables from the DB. I can successfully perform queries and everything works smoothly. Exactly what I wanted.
However, when I need to add new tables to the model, I run the "Update Model from Database" wizard and check the additional tables to import. It suddenly lists my renamed (but still correctly mapped) classes under the Delete tab, saying it can't find them in the database. When I click Finish, my existing classes are unmapped and I have to manually re-map each property to its corresponding DB column... Or roll back to the previous version of the EDMX file from version control.
I'm looking for what you think would be the most elegant solution to this problem, since I need the application to be as maintainable as possible. I strongly favour an approach that lets me auto-generate new classes from the database while preserving the existing renamed objects and their mappings.
Am I overlooking some way to prevent the Update Model wizard from deleting my existing mappings?
Should I use a different approach to renaming the generated classes?
Should I leave the generated classes unchanged and instead construct sanely-named wrapper classes that are exposed to the rest of my application?
Should I refrain from auto-generation and instead go for a code-first approach? This is a very unfavorable option, because I need the time spent on manual model coding and mapping to be as little as possible. Adding objects will be a very frequent task.
Should I perhaps even use a different ORM altogether..?
I discovered the culprit myself: running the "Generate Database from Model" wizard due to a recommendation in an article I read somewhere. It changed all the model's underlying table and column names to SQL Server standard names ([dbo].[Customers].[CustomerID] etc.).
This does not seem to be explicitly listed as a feature in any of the sparse examples I can find, for example:
http://blogs.msdn.com/b/adonet/archive/2011/01/27/using-dbcontext-in-ef-feature-ctp5-part-1-introduction-and-model.aspx
http://www.codeproject.com/Articles/336187/code-first-practical-case
or
http://blogs.msdn.com/b/adonet/archive/2011/09/28/ef-4-2-code-first-walkthrough.aspx
But I think the DbContext docs at least imply that it's possible:
http://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext(v=vs.103).aspx
DbContext is usually used with a derived type that contains
DbSet properties for the root entities of the model. These
sets are automatically initialized when the instance of the derived
class is created.
My goal is to use the EF to access a DB through a WCF data service from a Silverlight client, where the some of the columns are unknown at runtime. Any better ideas would be appreciated
Neither WCF or EF is suitable technology for this situation. WCF and its autogenerated proxies expects compile time defined model - you can avoid this but as a result you will not work with strongly typed data contracts but with "generic data" and you will work with them on XML or JSON level.
In case of EF it is even worse there is no easy workaround to get dynamic behavior. You can change DB or even mapping (but not with code first - only with EDMX) in dynamic way but still at the end you need compiled classes representing your mapped data.
The part of documentation you are referencing is not about dynamic creation of mapping but only about dynamic initialization of mapping defined in design time.
If anyone is interested, here is a synopsis of how to change the EDMX files to match a DB discovered at runtime:
Get and parse schema from the database (simple XML)
Put the schema in a format that is comparable with the EDMX metadata (more complex XML)
Use a tool like this one: http://efmodeladapter.codeplex.com/ to make the changes to the metadata (some assembly required)
Instantiate the data model
There is a commercial tool to do the same, but it's not free: http://huagati.com/dbmltools/
And here is the best list of other, more palatable options: Modifying an Entity Framework Model at Run-Time
Background:
I started to create logical database model for ASP.NET MVC web site. I used visual designer for Entity framework that ships with VS because I have used it before.
But now I already have 33 classes and I'm not finished (including quite some inheritance and a lot of associations). I'm afraid that it would be too complicated and time consuming for me to manually set all the table mappings and than generate database tables. I've no experience with it - I've done it the other way: classes from database tables and it took me a lot of time to get it work in a smaller project.
Question:
How can I easily and quickly create database tables for logical model (class diagram) in .NET / VS ? It would be great if it was possible automatically. I have never worked with LinqToSQL visual designer and it seems to be no reference on the web on how to create database tables from LinqToSQL classes. Is it possible at all ? If not is there any way to create database tables with Entity framework automatically - without having to specify table mappings ?
And one side question: if I used LinqToSQL classes are that going to commit changes to database every time I change properties ? Or is some caching taking place there ?
Entity framework has a concept called "Model First", which generates the database model from you model, hence the name.
You can read about that here: http://msdn.microsoft.com/en-us/data/ff830362
However, my personal favourite when it comes to Object Relational Mappers is NHibernate with the addition Fluent NHibernate. They have a concept where you work with your domain model rather than you data model and you use conventions to control your mappings. It's pretty neat. You can get started with some pretty good examples by looking at this code here: https://github.com/sharparchitecture/Northwind/tree/master/app
Linq2Sql is too limited for the case you are talking about. And it has no capability to generate data models from code. In fact, Linq2Sql works the other way around - it generates a set of classes from your data model, much like Entity Framework also can do.
Neither Linq 2 SQL or Entity Framework commit anything until you explicitly choose to do so. They both have a notion of a object context which keeps track of all changes made. When you call "Save", they transform those changes into SQL which is then executed in the database.
Like MikeEast, I've had a very good experience with Fluent NHibernate.
On my project, I use the Automapping feature, which allows me to change my data model almost at will, and the database schema automagically gets updated.
No SQL, no worrying about foreign keys, etc, etc, etc - I love it!
Fluent NHibernate Automapping
Finally I have sticked with Entity framework - tables generating is really plainless once I learnt how to deal with database connections...
I've begun experimenting with LINQ to SQL and what I am doing is basically creating classes with LINQ mapping decorators - thereby choosing which parts of the db table schema I want to incorporate into my classes.
A simple example:
private DateTime? _LocalCopyTimestamp = (DateTime)SqlDateTime.MinValue;
[Column(Name = "recaLocalCopyTimestamp", Storage = "_LocalCopyTimestamp", CanBeNull = true)]
public DateTime? LocalCopyTimestamp
{
get
{
return this._LocalCopyTimestamp;
}
set
{
this._LocalCopyTimestamp = value;
}
}
I am not using and am not willing to resort to modeling tools due to project contraints (the way schema changes are handled and because there is an existing database schema and it is a bit too organic and non-strict)
Is there a way to have this flexibility with the Entity Framework without having to include schema information files and/or lots of distinct code files?
Could I then also create classes that "use" more than one underlying table?
Can anyone point me to documentation regarding this?
The feature you are requesting (write C# classes and generate your model from those) is termed by the Entity Framework team "Model First." It does not exist in the current, shipping version of the Entity Framework, but is a planned feature for the next version. If you watch the Entity Framework talks from PDC, you can see demonstrations of this new feature. With the current version, you do not have to write "many" mapping files, but you do need one (the EDMX file), and it must be XML.
Yes, you can create entity classes which use more than one underlying table. This is called "Entity splitting." Step-by-step instructions at the link. In general, you will find that the Entity Framework supports many more complicated mapping scenarios than LINQ to SQL.
I'm afraid that I have to completely disagree with Marc regarding writing EDMX without use of the designer. Writing EDMX without using the designer is not only possible, but for projects exceeding a certain side, it is all but inevitable. A few points on this:
For most of the early history (pre-RTM; "ObjectSpaces") of the Entity Framework, writing the XML files manually was the only way to use the tool. The designer is a recent feature, and is considerably less stable than the Entity Framework itself.
There are certain Entity Framework features, such as complex types, which are not supported in the designer at all.
Certain mapping scenarios, such as not mapping individual columns, or mapping tables without a foreign key relationship, which may be necessary for legacy databases, are not supported in the designer.
As I mentioned in (1) the designer is quite a bit buggier than the Entity Framework itself. So on larger projects you will probably end up having to clean up after the designer's mistakes.
Entity Framework uses the EDM to model data; this is a set of 3 complex schema files (storage, conceptual, mapping), most commonly stored as resources in the project (via the designer which uses a single EDMX file to generate all 3 schema files).
It doesn't support attributed classes for this information. The only sensible way to write EDM is via the designer (essentially, a modelling tool which you dislike).
Re classes the "use" more than one underlying table; yes, a single Entity Framework entity at the conceptual layer (i.e. classes) can span multiple storage tables. This is especially useful for some inheritance examples, but can (IIRC) be used by flat models too. You do this via the "mappings" between the storage and conceptual layers (most commonly; on the tab in the designer).