I am using Entity Framework 4.3.1, with auto-generated entities from the database.
From this, is there any way to set the default value to something? I don't want to put it in the auto-generated code since it will be overwritten.
I understand that it is possible to use partial classes, so I tried something like this, where entity is generated, and DESCRIPTION_ is the attribute I want to set to a default value.
namespace name.Models
{
public partial class ENTITY
{
public string DESCRIPTION_
{
set { _DESCRIPTION_ = "default string"; }
}
}
}
Maybe if somebody could give me an example that would be great!
The example you give means that DESCRIPTION can only ever be "default string"
You can set it in the constructor
namespace name.Models
{
public partial class ENTITY
{
private string defaultDescription = "some text";
public ENTITY() {
DESCRIPTION_ = defaultDescription;
}
}
}
or by switching your property to one with a backing field
namespace name.Models
{
public partial class ENTITY
{
private string _desc = "some default value";
public virtual string DESCRIPTION_ {get {return _desc} set {_desc = value;} }
}
}
You use OnCreated on the partial class:
public partial class ENTITY
{
partial void OnCreated()
{
DESCRIPTION_ = "default string";
}
}
Related
I am trying to use a custom attribute on a Entity class generated automatically by the Entity Framework.
The problem is how to add an property attribute on an existing field?
Here the point where I am right now:
// the custom attribute class
public class MyCustomAttribute : Attribute
{
public String Key { get; set; }
}
// Entity Framework class generated automatically
public partial class EntityClass
{
public String Existent { get; set; }
//...
}
// set a metadata class for my entity
[MetadataType(typeof(EntityClassMetaData))]
public partial class EntityClass
{
// if I add a new property to the entity, it works. This attribute will be read
[MyCustomAttribute(Key = "KeyOne" )]
public int newProp { get; set; }
}
public class EntityClassMetaData
{
// adding the custom attribute to the existing property
[MyCustomAttribute(Key = "keyMeta") ]
public String Existent { get; set; }
}
Running this test:
[TestMethod]
public void test1()
{
foreach (var prop in typeof(EntityClass).GetProperties())
{
var att = prop.GetCustomAttribute<MyCustomAttribute>();
if (att != null)
{
Console.WriteLine($"Found {att.Key}");
}
}
}
will produce:
Found KeyOne
Or the Metadata class store the attribute in a different way or only works for data annotations.
I am stuck here, how can I set and read custom attributes of the generated class without having to edit the generated file?
I came across this same problem today. I figured EF magic would do the trick and map the attribute across to each model property. Turns out it does, but only for EF data annotations and I couldn't find an answered solution to pull out custom attributes so made this function. Hope it helps dude.
private object[] GetMetadataCustomAttributes(Type T, string propName)
{
if (Attribute.IsDefined(T, typeof(MetadataTypeAttribute)))
{
var metadataClassType =
(T.GetCustomAttributes(typeof(MetadataTypeAttribute), true).FirstOrDefault() as
MetadataTypeAttribute).MetadataClassType;
var metaDataClassProperty = metadataClassType.GetProperty(propName);
if (metaDataClassProperty != null)
{
return metaDataClassProperty.GetCustomAttributes(true);
}
}
return null;
}
I believe if you want to set an attribute in the metadata class, you have to use this syntax:
public class EntityClassMetaData
{
// adding the custom attribute to the existing property
[MyCustomAttribute(Key = "keyMeta") ]
public String Existent;
}
You must not have { get; set; } on your pre-existing property - just the property with the correct name and datatype.
I have a string field name consoleServerPort, and I want to trim all the white spaces inside it before saving it. I use to do so inside my controller class, as follow:-
public ActionResult Edit(FirewallJoin fj, FormCollection formValues)
{
fj.ConsoleServerPort = !String.IsNullOrEmpty(fj.ConsoleServerPort) ? fj. ConsoleServerPort.Trim() : "";
But I have to repeat this step on every action method. So I found another way of doing so once at the model level inside an Ivalidatable method as follow:-
public partial class TMSFirewall : IValidatableObject
{
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(!String.IsNullOrEmpty(ConsoleServerPort)){
ConsoleServerPort = ConsoleServerPort.Trim();
}
So is my second approach sound valid? or it is better to use the first approach ?
Thanks
Edit
I am using entity Framework and i did the following
i tried the following inside my model class i added the following :-
[MetadataType(typeof(TMSSwitchPort_Validation))]
[Bind(Include = "PortNumber,SwitchID,TechnologyID")]
public partial class TMSSwitchPort //: IValidatableObject
{
}
then inside the MetadataType class i added the following :-
public class TMSSwitchPort_Validation
{
private string consoleServerPort;
[Required]
[StringLength(10)]
[Display(Name="Port Number1111")]
public String PortNumber
{
get { return this.consoleServerPort; }
set { this.consoleServerPort = value.Trim(); }
}
}
but the ConsoleServerPort will not be trimmed? can you advice what might be the problem ?
Thanks
Couldn't you do it on the property setter?
public class FirewallJoin
{
private string _consoleServerPort;
public string ConsoleServerPort
{
get
{
return _consoleServerPort;
}
set
{
_consoleServerPort = value.Trim();
}
}
}
Good day!
I have created an EF model from database using database first aproach,
and added myself several read only properties to entity class generated by EF which are not in database.
Every time I update my model adding data from new tables
I loose properties created, so I have to recreate them.
As an example in database I have property isFemale but in my class I've created
public string Gender
{
get
{
if(isFemale) return "female";
else return "male";
}
}
My question is there a way to update the model from database, leaving properties generated by me?
Thank you!
Add the properties on another Partial Class instead of the generated class. For example, if your generated class is of type Person, define another Partial class in the same project with the same namespace:
public partial class Person
{
public string Gender
{
get
{
if(isFemale) return "female";
else return "male";
}
}
}
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
read more
You could make your class partial and seperate it in two files, this is the way I use it with DatabaseFirst.
public partial class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public partial class Person
{
public string FullName {
get
{
return FirstName + " " + LastName;
}
}
}
I'm trying to create a simple database to use sqlce in a windows phone app.
I have a base class, and another set of classes that derive from it
Here's what i got
public abstract class EntityBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
private int id;
[Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
public int EntityId
{
get
{
return id;
}
set
{
if (id != value)
{
id = value;
OnPropertyChanged("Id");
}
}
}
}
[Table]
public class Derived : EntityBase
{
[Column]
public string Description
{
get;
set;
}
}
Then, I've got this class for datacontext purposes:
public class MyDataContext : DataContext
{
// Specify the connection string as a static, used in main page and app.xaml.
public static string DBConnectionString = "Data Source=isostore:/ToDo.sdf";
// Pass the connection string to the base class.
public MyDataContext(string connectionString)
: base(connectionString)
{ }
public Table<Derived> Deriveds;
}
And finally, here i'm trying to create the db :
private void Application_Launching(object sender, LaunchingEventArgs e)
{
using (MyDataContext db = new MyDataContext(MyDataContext.DBConnectionString))
{
if (db.DatabaseExists() == false)
{
//Create the database -> here's the error
db.CreateDatabase();
}
}
}
I'm getting the following error when trying to create the database :
Invalid column ID. [ EntityId ]
Yes, a very descriptive error message...
Any ideas on what's wrong? I've been tampering around with the attributes in the column but to no avail.
[EDIT] : for what i've been testing, if i put the EntityId property in the derived class, it doesn't crash. This can be 2 things.. one, that I'm missing something else in the base class, or the other one, that the column attribute for a primary key must belong to the class, and can't belong to the parent (which would be a extremely horrible design decision, we can't use inheritance???). if someone can confirm this that would be appreciated
Ok, i think i found what was happening. In this implementation of SQLCe, we need to do the following approach when using inheritance :
http://msdn.microsoft.com/en-us/library/bb399352(v=VS.100).aspx
I don't particularly like it very much, the tables that it generates aren't normalized, but well, it's true that we shouldn't be using huge and complex datastores for WP7 apps, it's more to store some basic info that's too much to handle by isolated storage on itself..
Following this approach, it worked. I have now a collection of the base class, and i can put into it any of it's derived children. Then to retrieve them back, I use the discriminator in a linq to sql query to get one derived class or another.
It's an EntLib-Validator-issue again. I'm playing with EntLib 5.0 in C# and .Net 4.0 on XP pro.
I have some business objects (partial classes) generated by T4 templates. So I decided to put their validation attributes in buddy-classes by using MetadataTypeAttribute as definitely recommended by the documentation of entLib 5.0 (msdn).
But the Validator object I get from the ValidatorFactory doesn't know about the validation attributes, defined in the metadata-class.
The business object is defined like this:
[MetadataType(typeof(PatientMetadata))]
public partial class Patient
{
private string _Name;
private int _DiagnosisCount;
public int DiagnosisCount
{
get
{
return _DiagnosisCount;
}
set
{
if (value != _DiagnosisCount)
{
_DiagnosisCount = value;
}
}
}
public string Name
{
get
{
return _Name;
}
set
{
if (value != _Name)
{
_Name = value;
}
}
}
}
And the metadata class like this, according to documentation:
public class PatientMetadata
{
[RangeValidator(4)]
public int DiagnosisCount { get; set; }
[StringLengthValidator(64, ErrorMessage = "Name must not exceed 64 chars.")]
public string Name { get; set; }
}
If I know try to do validation this way:
var factory = ValidationFactory.DefaultCompositeValidatorFactory;
var validator = factory.CreateValidator<Patient>();
...then watching into validator (during debugging) already says, that it's just an AndCompositeValidator without any children validators.
Again, if I put the validation attributes right in the Patient class, it works perfectly.
By now, I have no real idea, what I'm missing here, since I think doing everything according to the docs.
Thanks in advance to you guys!
The property names of the metadata class must match the property names of the main class.
In your case your metadata class should look like:
public class PatientMetadata
{
[RangeValidator(0, RangeBoundaryType.Inclusive, 10, RangeBoundaryType.Ignore)]
public int DiagnosisCount { get; set; }
[StringLengthValidator(6, ErrorMessage = "Name must not exceed 6 chars.")]
public string Name { get; set; }
}
Also, the docs indicate the accepted approach is to declare all return types as object. However, the docs also talk about using properties but in their example use fields so take it under advisement. :)