Starting from an EF 4 entity diagram and using T4 templates one can create POCO classes that can be used inside the Domain Model. The generated code looks like this:
public partial class Product
{
public virtual int Id
{
get;
set;
}
public virtual string Name
{
get;
set;
}
//and so on
}
Is there any elegant approach to add my own code for implementing the properties? for example, the Name setter I would like to be implemented by lowering all the characters. I would like that my code resist to repeated regeneration of the POCO classes from the EF diagram.
This requirement is somewhat similar to adding validation code to the POCO classes. This issue is already solved by creating a separate validation class and linking it to the POCO through the MetadataType attribute. That separate validation class is not overwritten by repeatedly regenerating POCOs from the EF diagram.
Thanks,
Lucian
No there is no easy way to do that. You must not touch generated code because your changes will be deleted after each regeneration. You options are:
Write entities yourselves and don't use generator - you will get full control over entity code
Modify T4 template in generator to either add your direct code (this can be quite hard to generalize) or simply add call to partial methods (you must also declare these methods in generator) in getter and setter and in your partial part of entity class implement partial methods you need.
Related
I was using EF 4.x database-first approach. I have the edmx file and it generated the C# class that derived from EntityObject. I have an ASP.NET MVC 4 application that uses the generated class as model. The client validation that validates the required fields worked fine.
Now I moved to EF 5 and used the DbContext generator, it generates the POCO C# class. I found that the required field validation no longer works in EF 5.
I think the problem is that in EF 4.x EntityObject generator, the generated class has [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] attribute. However in the EF 5.x POCO class, no data annotation attributes are generated. So the required field information is lost.
So my questions are:
Why does the EF 5.x DbContext generator not generate
[Required] annotations from the edmx file?
Where is the right place to
put these data annotations? Should I modify the .tt file to generate
the [Required] attribute? Or manually write a [MetadataType] partial
class and define data annotation attributes in a separate
class?
1) I don't know why. I just know that Db-first approach doesn't add any data annotations to properties.
2) Indeed creating a separate partial class! Here is an example. Because EF will overwrite and regenerate all POCO classes every time you update your model, any changes (also data annotations) to those classes will be lost...
Perhaps you can find this link useful.
EF Validation
Simply add Metadata class with the required validation:
[MetadataType(typeof(UserMetadata))
public partial class User
{
...
}
public class UserMetadata
{
[UserValidate("State")]
public string State;
// etc.
}
hope this can help
I've got an ADO.NET background and its the first time I've used Entity Framework in a serious project so I've gone ahead and got VS2012 and am using .NET 4.5 and entity framework 5.
I'm taking the data first approach and have created the database, generated the .edmx and also seperated out the POCOS from the context using this method: http://allen-conway-dotnet.blogspot.co.uk/2013/01/separating-entity-framework-poco.html
So my solution looks like this:
Data.Access (where I access the EF context and return POCOS to Business Layer)
Data.Model (where the POCOs are)
Data.Repository (where the context sites)
Presentation.Admin.Website
Now say I have the following table in the database / POCO class (just an example - not real)
namespace Data.Model
{
using System;
using System.Collections.Generic;
public partial class Car
{
public Car()
{
this.Parts= new HashSet<Parts>();
}
public int ID { get; set; }
public string Manufacturer { get; set; }
public string Model{ get; set; }
public Nullable<bool> Enabled { get; set; }
public virtual ICollection<Parts> Parts{ get; set; }
}
}
Now say all the cars in the database have an web service or even just a link to a URL which returns XML and gives me a list of available parts. The way in which each car retrieves the parts data is different (some are REST, some WCF, some from a CSV file, etc).
So I want to define classes that extend Car and define a "GetParts()" method which will have specific business logic to get parts for that particular car.
I also want to be able to get all cars from the database and loop them, calling the GetParts method for each one to retrieve the data.
I am thinking I need to define an interface or abstract class ICar declaring the GetParts method and somehow incorporating the Car POCO but getting confused about how to go about coding this.
Can anyone explain briefly how I can structure my code to get this done, perhaps suggesting a design pattern?
I'm taking the data first approach
The way in which each car retrieves the parts data is different (some
are REST, some WCF, some from a CSV file, etc).
Considering your type of data store is variable and you presumably want a reusable model then I think the choice of using EF database first is not a good one for you. Better to go with code first.
So I want to define classes that extend Car and define a "GetParts()"
method which will have specific business logic to get parts for that
particular car.
Your model should be persistence ignorant. I would not consider extending or hardcoding a data store specific GetParts() if that's what you are after.
perhaps suggesting a design pattern?
Perhaps look into using a repository to provide a layer of abstraction over your data mapping.
I'm new to Entity Framework and the database first approach. Can anyone please help me?
Here is the case:
I have a clean, ordinary domain class (Person) with only properties. This class is defined in a VS-project that will only contain domain classes, without any reference to Entity Framework or other things that belong in a data access layer.
I also have a database table (tblPerson). I have created an EDMX for it and used DbContext Generator to create POCO-classes for it.
It is important to keep entity framework references separate from the project with the domain class, and I want to use a repository pattern combined with dependency injection.
The question is:
How do I "map" the Entity Framework POCO-class to my existing domain class? They have the same properties. I have read something about proxies, buddy classes and more, but didn't find any good examples.
Please help.
Lets say that the domain model class looks like this (just an example):
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
and the database table has the same colums:
Id (int, not null, primary key)
Name (nvarchar(50), not null)
Update:
Ok, I found a solution. I did what Ladislav Mrnka suggested and derived from ObjectContext. Here is a page that describes how it's done: Entity Framework 4.0 – Part4: How to use your own POCO’s
If you want to map your "domain objects" to the EF generated POCO classes, then you can use a mapper such as AutoMapper https://github.com/AutoMapper/AutoMapper/wiki
Ok, I found a solution. I did what Ladislav Mrnka suggested and derived from ObjectContext.
Here is a page that describes how it's done: Entity Framework 4.0 – Part4: How to use your own POCO’s
Does it makes sense to introduce an abstract IdableEntity base class, that has a public Guid Id { get; set;} property, and then derive all my entities from it, so I don't have to add key field to each one of them? Will I face any pitfalls if I do in theory?
I used to never do this since my DbContext model was rather simple and consisted of a few classes. Now I am designing a large entity number model that may benefit from it.
Speaking from experience of this exact thing - yes it makes sense. Note that this EF base class doesn't have to be the heirarchical root though - it could inherit from a base class that implements things like INotifyPropertyChanged, IChangeTracking, etc. So your inheritance chain would look like this:
BaseDataClass <- BaseEFDataObject <- [actual EF entities]
Using entity framework (EF) as ORM tool in a 3-tier project, I found entity framework generated code as DAL + a little BLL. Since the DAL and BLL are different layers in this scenario and different coders will work on each of them, there is a need for separating each layer as a different project.
The problem is I don't want changing EF generated code and still need an extra project for BLL (I'm aware of EF partial classes and On...Changing() methods but this doesn't make sense of a good separation of concepts to me and also a partial class cannot be implemented in a different project).
I wish EF would generate an interface for each entity and then implement it as the generated code. That way, I could implement those interfaces by my BLL classes. Then making changes to entities in EF designer would lead to automatically changing the interfaces and my BLL would stopped working (doesn't compile any more, since the interface has been changed). Unfortunately EF doesn't supply those interfaces and extracting them from generated code is hard to maintain since any new change to model need extracting them manually again.
Then I thought of wrapping entity framework generated classes with our own BLL classes (deriving BLL classes from EF classes) and add extra BLL logic there (validations, business rules...) and hide underlying methods and properties with BLL equivalents.
// example of a new property which facilitates using an EF object
class EFaccount // EF generated class
{
DateTime CreationDate { get; set; }
DateTime ExpiranDate { get; set; }
}
class BLLaccount : EFaccount // BLL class
{
new DateTime CreationDate { get; set; }
new DateTime ExpiranDate { get; set; }
// Total age in days as a new property. Storing this, in dbase cause unnecessary redundancy
int Days { get { return (ExpirationDate - CreationDate).TotalDays; } }
}
Since BLL classes are derived from their equivalent EF classes, I need casting from and to a base class which is not allowed.
In my case if I'm casting from a EF to BLL it means object is coming from dbase and extra properties can easily be calculated from base class but compiler doesn't allow casting from base. And if I'm casting from BLL to EF it means object is gonna to be stored in dbase so extra properties could be throw away but compiler doesn't allow casting to base.
What do you suggest ?
The suggestion is:
Use Entity framework 4
Use Entity Objects or preferably POCO
Use Entity Objects or POCO T4 template
Modify T4 template to add additional features for you - generating and implementing interface based on entity properties should be possible.
Argument that you don't want extra codings is ridiculous. You have already proved that with generated code you need a lot of extra codings and you have a lot of additional complications. Generated doesn't mean good. It is not easy to work with generated code if you can't modify its generation (this is possible only if you write your own custom tool for code generation). So here is clear advantage of T4 templates.