I am using database first approach with Entity Framework 6 and generating POCO objects using T4 templates to use them in my WCF service application.
When creating new instances of the POCO objects on the server side if there are any missing required fields, as a final resort if the code missed any, I could call the method GetValidationResult() on the DBContext.Entry to get any validation errors. However I would like to be able to handle any of these on the client end by emitting the Data Annotations on the POCO objects as I am sharing the POCO objects between the Server and Client application.
I was thinking to add buddy classes to define the metadata and create partial classes to configure the buddy class. I was wondering if there are any T4 templates which would help me generate these partial classes with the metadata since there are a lot of entities and also whenever there is an update to the tables the partial classes with the metadata could be updated easily instead of going through each object and updating.
Please let me know whether my thought process is in the right direction and other best approaches.
Related
This answer describes a way at runtime to "add" properties to a class by creating a base class of the class you want to add properties to.
https://stackoverflow.com/a/14724876/2437521
Would it then be possible to map this class that was created with reflection to a table or view in Entity Framework (in the OnModelBuilding method most likely)
Before people say "That's a dumb idea" let me tell what I'm trying to accomplish. We have a data provider that's compatible with multiple DBMS platforms and using EF as a single code path for this compatibility. We need the ability to use Entity Framework to map to a view in the database to do things like filtering, etc.
This is easy and EF can do these things without trouble. Here's where the problem is. There's a requirement that we be able to join in custom columns into this view and be able to search, sort, filter etc. on these custom columns.
I immediately thought, drat, EF can't do this so I made the method for querying this view just access the vanilla ADO.NET provider underneath and just wrote almost 1000 lines of code with platform agnostic SQL.
Here are the problems I can think of that need to be solved to get this runtime configuration of Entity Framework to work:
Make EF Model Builder map to the Emitted class generated at runtime.
Use reflection somehow to create an Expression that can be used to pass into the IQueryable extension methods
Assume that EF will work with these Expressions and actually generate the SQL needed.
The EF code is something that exists in our core product and it can't be recompiled once it's deployed, hence why I'm trying to accomplish this all at runtime.
I am new to Code First. I am interested in using Code First going forward on my projects. I am using EF 6.xx. I will be creating several projects using an existing database but will be adding additional tables/views/stored procedures where necessary. Perhaps a silly question... Can I develop a library of POCOs that are tagged with the appropriate Fluent API tags and then pick and choose what Fluent API tagged POCO library classes I want to include in the OnModelCreating method for the particular project. I'm interested in re-using the same POCOs from project to project. Is this what others are doing or are they re-creating the POCOs in every project?
Thanks in advance,
Terry
You can certainly re-use the POCO classes between applications. If they are not referenced directly by your DbSet subclass or indirectly by another class that is already referenced then they won't be used by EF.
You can use attributes (what I think you mean by tags) on the various POCO classes as long as those attributes are the same between all projects that will use them - e.g. column name etc.
For stuff that changes between projects you'll definitely want to use Code First's fluent interface to configure them in the OnModelCreating.
I have 20 class.cs with x00s properties for my old project
and now i want to use EntityFramework
but I dont want to rewrite all this classes from begin
i just want to convert this class to DataModel.dbml or use some thing like add Existing Item
and I tried creat class with same name and copy the code inside them but the editor clear them after saving
how can i do that ?
There is plenty of resources regarding Plain Old CLR Objects and Entity Framework code first model on the web.
ADO.NET EF 4.0: Working with Plain Old CLR Objects (POCO) Classes
Code First step by step tutorial
But the gist of it is:
Entity Framework >4.0 supports POCO types that don’t need to inherit from a base class or
implement any interfaces to get persistence. There is also no need for metadata or mapping
attributes on type members, so you can use your existing code as simple entity classes.
An EDMX file that contains the conceptual model is still required. Add a new ADO.NET Entity Data Model to the project.
Using the toolbox, drag entities and associations from the toolbox and design the conceptual model. Simply make sure that the names on your POCO classes match the names of your conceptual entities.
Add entity keys as you would add primary keys in a db. Add associations like foreign keys in a db.
In Solution Explorer, click the EDMX file and then, in the Properties window, clear the Custom Tool property to turn off the automatic generation of .NET classes for your conceptual model.
Right click edmx design area and select 'Generate database from model'. DDL will be produced. Run that to create your db.
Make sure your POCO classes and POCO edmx model are in a separate assembly.
Create your custom ObjectContext derived data context with ObjectSet<T> members like here. Newer EF releases use System.Data.Entity.DbContext and System.Data.Entity.DbSet<T> instead.
You can use dbml too (Linq To Sql classes instead of EF), but you still need to generate your model from scratch, like you'd do with EF.
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
Whenever I read an article on linq to entities, I sounds like I should embed my business logic in the generated entity-classes.
This would means that the "user" of the business-objects (controller, service-layer, ...) would have to know about the datacontext-object that's needed to use linq.
It would also mean that the DAL-logic and the business-logic will be mixed up.
A lot of microsoft examples use some kind of DTO-approach. I'm not a big fan of the DTO pattern.
So should I let the business-object encapsulate the linq-entity and provide access to it using properties, or should I stick with the DTO pattern?
What are your suggestions?
Thanks
The entity model generates partial classes. In a project of mine I'm using an entity model inside a class library and added a few .cs files to it that add functionality to the default entity classes. (Mostly functions related to error and message logging to a database table and a method to import/export all data to XML.)
But true business logic is located in a second class library that refers to this entity class library.
Let's explain. First I created an entity model from a database. It contains a list of company names and addresses. I do this by choosing "New project|Class library" and then add an ADO.NET Entity Data Model to this library. The Entity model will be linked to my SQL Server database, importing the tables I need and auto-creates classes for the tables I want to access.
I then add a second .cs file for every table that I want to expand. This would be a few raw methods that are strongly linked to the database. (Mostly import/export methods and error logging.) This I will call Entity.Model, which will compile to Entity.Model.dll.
Then I add a second project which will contain the business logic. Again, I use "New project|Class library" to create it and add Entity.Model.dll to it's references. I then start writing classes which will translate the database-specific classes to more logical classes. In general, I would not have to make many changes except that I will protect or hide certain fields and add a few calculated fields. The business logic would only expose the functionality that I want to access from my client application and not a single method more. Thus, if I don't allow the client to delete companies then the "Delete" function in the entity model will not be exposed in the business layer. And maybe I want to send a notification when a company changes their address, so I'll add an event that gets triggered when the address field of the company is changed. (Which will write a message log or whatever.) I'll call this business.logic and it compiles to Business.Logic.dll.
Finally, I'll create the client application and will add a reference to Business.Logic.dll. (But NOT to the entity model.) I can now start to write my application and access the database through the business layer. The business layer will do validations, trigger a few events and do whatever else in addition to modifying the database through the entity model. And the entity model just serves to keep the database relations simple, allowing me to "walk through" the data through all foreign links in the database.
I wouldn't edit the generated files as they are likely to change.
What you could do is wrap them some query object and pass that around.
ayende makes a very good point about where the DAL should really live
Also, you should be a fan of viewmodels/dtos ;)
I prefer to wrap calls to the entity classes in business classes. (Call it BC for short.) Each BC has several constructors, one or more of which allows the context to be passed to it. This allows one BC to call another BC and load related data in the same context. This also makes working with collections of BCs that need a shared context simpler.
In the constructors that don't take a context, I create a new context in the constructor itself. I make the context available through a read-only property that other BCs can access.
I write using the MVVM pattern. The nice thing about this approach is that so far I have been able to write my viewmodels without ever refering to the data context, just the BCs that form my models. Hence if I need to modify my data access (replace entity framework, or upgrade to version 4 when it is out of beta) my views and viewmodels are isolated from the changes required in the BCs.
Not sure this is the best approach, but so far I have liked the results. It does take tweaking to get the BCs designed correctly, but I end up with a flexible, extensible, and maintainable set of classes.