I'm new to EF so please excuse me if this is a noob question.
Basically, we have a EF model set up using Model First for our 'platform' project and is shared across many applications which we build on top of this platform. In some of these applications we want to extend the classes to include additional properties without changing the model in the platform. Is this possible with EF 4 and how would I be able to do it without modifying the .edmx file?
I notice that the generated classes are all partial so potentially I could create a new partial class with the same name to include the new properties but is there any mappings that need to be taken care of?
p.s. under normal circumstances I'd have preferred to use inheritance and create a new class to hold the new properties instead but again, I don't know how to do that with EF.. any enlightenment here will be much appreciated!
Many thanks,
You cannot use inheritance because once entity is loaded from the data source EF will not know about inheritance and because of that it will instantiate base type without your properties instead of derived type with your properties. Any inheritance must be mapped in EDMX if EF have to work with it.
Using partial class will solve your problem but:
All parts of partial class must be defined in the same assembly
Properties from your partial part are not persisted to the database
Properties from your partial part cannot be used in linq-to-entities queries
EF generates partial classes. So to extend MyEntity, create a MyEntity.cs file with
partial class MyEntity
{
public string MyExtraProperty {get;set;}
}
edit: in the same namespace as your generated entities
I agree with adding additional properties to partial class of your entities (as you and Kaido said).
This way you can freely add the properties you want, without modifying generated classes and if you generate your model again (or update it from DB), your partial class is not modified.
In my opinion, adding properties to partial classes of generated entities is the way to go.
Related
I want to add attributes on properties inside my model class. But I know if I create new changes in database and update my model the attributes added will be removed. So my question is can I manipulate the model class into a POCO and reference the POCO instead of using EF model class when I do IQueryables.
public IQueryable<UserAccount> GetUserAccounts()
{
return Entity.UserAccounts;
}
UserAccount is an auto generated template model class which was created by EF. Can I have my own model to have data annotations ?
Hy,
The best approach is that you keep the autogenerated class as it is, which makes it more clean and extend class with a partial class containing the extra properties you want.
In a LINQ to SQL class you get the option to View Code of any entity you drag in the design surface. This creates a Partial Class.
Lets say we have an Employee Entity and I create a partial class Employee. What can I use that partial class for? Is it to add Employee methods such as DoWork()?
Do I need to declare any variables that are in the table? (In case of Employee: Name, Surname etc) If so, how do I make the connection between the data present in the Employee record to the class?
partial class is used in EF in order to allow you to make changes and additions to entity classes in a file that is not auto generated. Changes in and auto-generated file might be overridden when updating db context. The use of your own files which extend the partials defined in the auto-generated files prevents that. this also allows you to add implementation to partial methods defined in that partial class, most typically event handlers.
using a partial class in the same name space is very much similar to work inside the other part of class it extends, and it simply allows you to write one class in more than one file. for more information:
https://msdn.microsoft.com/en-us/library/wa80x488.aspx
I have created an entity data model and generated a database from it.
One of the entities is called Template.
Created partial classes to extend the functionality of Template works fine.
If I create a new class and try to derive from Template, I get a runtime exception upon instantiating:
Mapping and metadata information could not be found for EntityType 'Template001'.
How can I work around this? I definitely need to inherit from the EF classes.
EDIT
Does not seem possible. If that is the case, what would be the best way to implement the following requirement: The template entity stores information about templates that each have their own code to execute. That is why I was trying to derive from the entity in the first place.
It is not supported. You cannot derive a new type from entity and use it instead of the mapped entity type for persistence. If you want to have derived class from entity you must use mapped inheritance where every child is also mapped to the database.
Why do you need to inherit from entity class first of all? If you want to add some simple behavior, use partial class.
Update: Based on comments, it appears that there is possibility that behavior will be extended over the time. In this case, I would recommend using composition/aggregation, not inheritance. Let the classes that need to be extended have an entity as a field. In Raheel's scenario, it would be a class called TemplateLogic with field/property of type Template.
I'm studying Fluent NHibernate now, and have a question about mapping. It's not an issue, but a best practice question.
I know that with Fluent NHibernate there is a new fluent mapping, and it requires a new Class for mapping fields that will be used by the Entity Class. I was wondering, if the Mapping Class is directly linked to the Entity Class (It will map exacly for the entity class), do best practices dictate that they can't be joined within the same .cs file?
Please note that there will be no nesting here.
I.e.: There are Product and a ProductMap classes, both for a Product table on my database, so I'd place both classes within the same Product.cs, like the following:
namespace Business.Entity
{
public class Product
{
...
}
public class ProductMap : ClassMap<Product>
{
...
}
}
If the classes shouldn't be inside the same file, would you care to explain why, and maybe with real examples?
Thanks in advance!
When creating the SessionFactory instance, you will pass a class that tells which assembly has the mapping definitions. Then, using reflection, it'll iterate through all the classes on this assembly that inherit from ClassMap<T>.
That said, for a faster initialisation, it's better to have this assembly as light as possible, and it means that it would be better to have an assembly that would hold only the mappings and not the classes definitions.
AFAIK this is the only difference. Any feedback will be appreciated.
You should design your entities persistant ignorant as much as possible.
That means you shouldn't make Product derive from ClassMap<Product>. But it also means that the ProductMap shouldn't even be in the same project as your entity.
Typically, you would have a DAL project that contains the mapping and a Domain / Business project that contains the entity
You can keep both classes in different files, even in different namespace. but if you are beginner then you can keep entity class in different file and map class in different file within same namespace.
/* Product.cs */
namespace Business.Entity
{
public class Product
{
...
}
}
/* ProductMap.cs */
namespace Business.Entity
{
public class ProductMap : ClassMap<Product>
{
...
}
}
What is the best practice for implementing IDataErrorInfo for an entity class. A class that is associated with a table or view.
I have a View that binds to a record from a Task entity class and need to validate the data before it is saved to the SQL CE database. Need to know the best way to implement IDataErrorInfo in this case. I assume just do it on the Task entity class, but want to make sure. Since I have many entity classes that will need validation.
Are you using autogenerated entities? In such case the usual practice is creating second file in the same project where entity is defined and create its second partial part:
public partial Task : IDataErrorInfo
{
...
}
The reason why the interface is implemented in another partial part is that the initial part is autogenerated by some API (Linq-to-sql, EF, etc) and that API can regenerate the code each time you do some changes. That regeneration would delete your changes but if you place them to your own partial part changes will not be deleted.