I am starting to know and work with Entity Framework. And I am trying to do some simple spikes to know how it works.
My first question is what is the right way to intercept values from the client UI and change it before persist them.
In example we have this Person model automatically generated by EF 4.x DbContext Generator template:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
namespace EFModelDatabaseFirst
{
public partial class Person
{
#region Primitive Properties
public virtual int Id { get; set; }
public virtual string FullName { get; set; }
public virtual string LastName { get; set; }
#endregion
}
}
I would like to modify the FullName setter to always set it in UpperCase. For example in this way:
public partial class Person
{
private string fullname;
#region Primitive Properties
public virtual int Id { get; set; }
public virtual string FullName {
get { return fullname; }
set { fullname = value.ToUpper(); }
public virtual string LastName { get; set; }
#endregion
}
But I must to continue working on the model and when I do the ‘Add Code Generation Item…’ again from that modified model all my hand written modifications will be lost when the template rewrite all files.
What is the best approach to implement this ?
Thanks.
edit:
=== ANSWER FROM @Codeulike ===
if I try to create a partial class in this way:
public partial class Person
{
partial void OnFullNameChanging(string value)
{
this.FullName = value.ToUpper();
}
}
Then I have an Infinite loop and so a stackoverflow exception. And I must to delete POCO Classes and activate the model.edmx with Code Generation Strategy: Default
Generating again POCO Classes and trying to create a partial class in this another way:
public partial class Person
{
private string fullname;
partial string FullName
{
get
{
return fullname;
}
set
{
fullname = value.ToUpper();
}
}
}
The compiler gives me an error, because Class Person already contains a definition for ‘FullName’.
The only way to get it to run fine is deleting property on POCO Class Person. But if I re-generate again the POCO Classes all changes are lost.
edit:
=== ANSWER FROM @Codeulike + @Guvante addings ===
At last I have created a partial class in this way:
public partial class Person { partial void OnFullNameChanging(string value) { // _FullName is the backend field EF generates. this._FullName = value.ToUpper(); } }
but this doesn’t run and FullName value (on database) is not changed to UpperCase. I have had to do in this another way and it runs fine:
public partial class Person
{
partial void OnFullNameChanged()
{
this._FullName = this.FullName.ToUpper();
}
}
Regards.
The generated Entity classes are Partial classes.
You can create your bits in separate .cs files, and it will all get compiled together. This lets you add stuff without getting it overwritten by the code generator.
See here for further details.
edit: ok, I see your problem with getters and setters. Apparently this is the way to do it:
How to: Execute Business Logic During Scalar Property Changes
http://msdn.microsoft.com/en-us/library/cc716747.aspx
There are some partial methods for each property that you can write code for. You just have to implement the appropriate partial method in your partial class and it will get called.
e.g.
edit: Entity framework uses private fields inside the public properties to hold values. They are typically named
_<property name>– check your generated code to see what its using. So the code to capitalise FullName would look something like: