I have two properties ("FIRST_NAME" and "LAST_NAME") I need to access as a single property (e.g. "FULL_NAME"). Is there a way for me to add a property to my entity model that contains the combine value of FIRST_NAME and LAST_NAME?
Since the model classes which are created by EF4 are usually partial classes you have the option to extend the classes in a separate file with your additional properties and methods. There you could add a readonly property with only a Getter to return your combined full name:
public partial class Person
{
public string FullName
{
get
{
return string.Concat(FirstName, " ", LastName);
}
}
}
This is a property which is only in your model class but not mapped to the database and it doesn't exist as a column in the database. Because you create this part of the partial class in a separate file it is not touched and overwritten by the model designer if you should change the model.
Related
I'm using Entity Framework (DB First) on a new project and wanted to add some customisation to the classes generated. However, my changes are obviously lost every time that the edmx is refreshed. I was just wondering if there is a design pattern for handling this sort of thing?
As an example, suppose I have a class with a integer property; StatusID - and I'd like to extend the entity class so that the status value can also be accessed/set via the related enum and finally a property that gets a text representation of that Enum from the description attribute. This all works, but those customisations are lost when the model is refreshed. I appreciate that the property can be converted to an enum, so the latter property that gets the description of the enum is perhaps a better example for this question.
I think I know the answer but I just wanted to put this out there in case there were some magic tricks that would allow this to work and prevent those customisations from being lost.
public int StatusID { get; set; }
public Enumerations.ValidationStatus StatusEnum
{
get
{
return (Enumerations.ValidationStatus)StatusID;
}
set
{
StatusID = (int)value;
}
}
public string StatusText
{
get
{
return MyMethodThatGetsTheEnumDescription(StatusEnum);
}
}
Two Solutions to work around the problem:
User Data Transfer Object(DTO) nd put the enum there. then use Automapper or manually map between the DB Model and the DTO Model (best practice)
Instead of enum you can use extension functions on the model and define your getter, setters and any extra properties you want as extension functions to the class
(will add some complexity to your models)
In our application, we are using EF4.0 and POCO Entity generator to generate Entities from the database. To apply data annotation, we are creating Interfaces and implementing those interfaces on the partial classes we have created to match the partial class generated by using EF.
/*Entity Generated Type*/
public partial class SomeEntity : EntityBase
{
public virtual string SomeProperty
{
get {...}
set {...}
}
}
/*Interface containing metadata*/
public interface ISomeEntityMetadata
{
[SomeCustomAttribute]
string SomeProperty { get; set; }
}
/*Partial matching class for interface*/
[MetadataType(typeof(ISomeEntityMetadata))]
public partial class SomeEntity : ISomeEntityMetadata
{
}
Now, using reflection, when we try to get if 'SomeCustomAttribute' is applied on 'SomeEntity.SomeProperty', it returns that the attribute is not applied.
If we edit the generated code and apply the Attribute directly, it works.
If we check for the partial classes merging to form a single type, it does.
If we check for the MetadataType attribute to be applied on the type (using reflection), it is.
Also, when the entity is bound to any WPF's UI-Element, the validations work as they should but using reflection we are unable to find the Validation Attributes and/or Custom Attributes applied on the property.
Any help or pointers would save a soul.
But interface / class marked with MetadataType attribute will never add those attributes to your original class so you can never find them on the class with reflection. That is not a purpose of MetadataType attribute. If you want to use reflection you must first find MetadataType attribute, check the type passed to that attribute and search for your custom attribute in that type. That is how validation uses MetadataType.
I have an existing SQL Database in which all tables have an ID column as the primary key. Can I generate an Entity Framework Model from this database AND make sure all the generated types inherit from an interface that defines the ID property?
Basically, I want everything that I return from the database to implement this:
public interface IDatabaseTable
{
public int ID { get; set; }
}
I hope you using EntityFramework 4 if so you need to use T4 templates to generate your entity and data context, you may download that from here
http://visualstudiogallery.msdn.microsoft.com/23df0450-5677-4926-96cc-173d02752313
Than when you get it setup you would need to modify T4 template to generate inheritance.
So you would get two tamplates one template which is generating Data Context and other one which is generating Entities.
You need to modify the second one(entity generator template), go to line 41 of your entity .tt file and add your inheritance there like that:
<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#> : IDatabaseTable
Some details on T4 POCO tamplates you may find here
http://sharedtolearn.blogspot.com/2010/06/entity-framework-40-and-t4-templates-to.html
http://msdn.microsoft.com/en-us/data/gg558520
See this MSDN page about partial classes.
In short, you can create a partial class for your EF entities and implement whichever interfaces you'd like.
Here's the documentation from the MSDN page:
The following are merged from all the partial-type definitions:
XML comments
interfaces
generic-type parameter attributes
class attributes
members
For example, consider the following declarations:
partial class Earth : Planet, IRotate { }
partial class Earth : IRevolve { }
They are equivalent to the following declarations:
class Earth : Planet, IRotate, IRevolve { }
I need to bind request parameters to an instance of the following Java class (getters and setters omitted):
public class ShippingHouse {
private String name;
private String description;
private List<ShippingRule> shippingRules = new ArrayList<ShippingRule>();
}
public class ShippingRule {
private ShippingHouse shippingHouse;
private String name
}
Notice that there is a 1:N relationship between ShippingHouse and ShippingRule, but each ShippingRule also has a reference to the ShippingHouse thaat owns it.
If these were Grails command/domain classes, I would bind them with request parameters
name=foo&description=bar&shippingRules[0].name=sr0&shippingRules[1].name=sr1
But it doesn't seem like this will set the reference to the owning ShippingHouse within each ShippingRule. Is there a way I can bind this automatically, or must I write the code myself?
Don,
You will need to write code to do it yourself using BindUsing or some other approach. The binder doesn't (and shouldn't) assume anything about back references from a parent to a child. If these were GORM entities and the relationship was explicit, that is different, but in your case the binder should not assume that shippingHouse property in the ShippingRule class has anything to do with the shippingRules property in the ShippingHouse class.
Also note that lucke84 said that your "private" is implicit. Make sure you understand what that means if you are going to remove them. If you remove them the compiler is going to generate public getter and setter methods for those properties, which may or may not be what you want.
If you want to implement a 1:N relationship between the two classes, you should use the right grails approach. Something like this:
class ShippingHouse {
String name
String description
static hasMany = [shippingRules: ShippingRule]
}
class ShippingRule {
String name
static belongsTo = [shippingHouse: ShippingHouse]
}
Please note that semicolons are useless and the "private" declaration on class fields is implicit.
I Have 21 entities with the same structure.
Same Attribute too.
Every entity contains these Attributes :
AreaType
ID
IsActive
LangID
TXT
ModuleType
ID
IsActive
LangID
TXT
...
What I Need to perform a generic Crud. I already know that I need to create a generic repository. My problem is to perform a kind of generic ViewModel.
How can I create a generic View for the Create Form.
I Dont know what I need to pass in the Inherits of the view to be Generic.
... Inherits="System.Web.Mvc.ViewPage<...Dont know>"
Any Idea ?
A common approach this problem is to use ViewModels. This is where you create specific classes to be used as the models in your strongly typed views. These classes would not be the ones created by EF. The ViewModel classes can have a common base that encapulate your common fields. In your data access layer you would need to move data between your ViewModel classes and your EF classes. Things like AutoMapper (from CodePlex) work really well to reduce, if not eliminate, all of the the tedious "left-hand right-hand" coding.
Not too familiar with MVC, but (assuming it fits in with your hierarchy), I think you could create an abstract class which contains the properties you need, e.g.
public abstract class ViewableObject {
public abstract int ID {get; set;}
public abstract bool IsActive {get; set;}
// etc
}
Then implement that with your normal classes (AreaType and so on), e.g:
public class AreaType: ViewableObject{
public override int ID { get; set; }
public override bool IsActive{ get; set; }
}
and make the view use the abstract class.
... Inherits="System.Web.Mvc.ViewPage<ViewableObject>"
One idea is to simply change your underlying tables. Combine AreaType and ModuleType into a single "WhateverType" table that contains a field identifying exactly what type it is. Then when you codegen your classes you'll have exactly one class to deal with.
However, there are other concerns and you should only do this if it makes sense in your application.