Add Data Annotations to a Class Generated by Entity Framework

Add data annotations to a class generated by entity framework

The generated class ItemRequest will always be a partial class. This allows you to write a second partial class which is marked with the necessary data annotations. In your case the partial class ItemRequest would look like this:

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

//make sure the namespace is equal to the other partial class ItemRequest
namespace MvcApplication1.Models
{
[MetadataType(typeof(ItemRequestMetaData))]
public partial class ItemRequest
{
}

public class ItemRequestMetaData
{
[Required]
public int RequestId {get;set;}

//...
}
}

How to add data annotation for entities automatically created by Data-First?

Okay, here is the answer.

The trick is, the auto-generated classes are all partial classes. The compilation process will combine all partial classes with the same name.

If we have public partial class Concept generated by DbContext, all we need to do is to create another one started with public partial class Concept. This new partial class can be created in a different folder, but we need to its namespace should be updated into the same as the auto-generated partial class.

In this newly created partial class, we can add all kinds of data-annotations such as

[Required(ErrorMesssage="This Field is required")]

Or, we can even add new properties like

FullName {get {return string.Format("{0} {1}", FirstName, LastName);}}

If the model is updated from the database again, only the auto-generated partial classes will be updated. Those newly manually added partial classes, which contain our annotations and other manipulations will remain intact.

How to automatically add data annotations to generated Entities?

With some more research and some trial and error I managed to do it. Basically it involves editing the T4 template generated by Entity Framework.

After you add the ADO.NET Entity Data Model > EF Designer from data..., you get an EDMX file, and if you expand it on Visual Studio there's a .tt file with the same name as the .edmx file.

On that file, I added under <#=codeStringGenerator.UsingDirectives(inHeader: false)#> the using statement for data annotations:

using System.ComponentModel.DataAnnotations;

Then, a few lines below, after the simpleProperties declaration, in the foreach I added the following:

foreach (var edmProperty in simpleProperties) // <-- Original foreach statement
{
if(edmProperty.Nullable == false)
{
#> [Required]
<#
}
if(edmProperty.MaxLength != null)
{
#> [StringLength(<#=edmProperty.MaxLength#>)]
<#
}
//Rest of the auto-generated code...

Saving this file will update the auto-generated .cs files accordingly:

namespace MyNamespace
{
using System;
using System.Collections.Generic;

using System.ComponentModel.DataAnnotations;

public partial class MyModel
{
[Required]
public int Id { get; set; }
[Required]
[StringLength(20)]
public string MyField { get; set; }
}
}

Using DataAnnotations with Entity Framework

A buddy class is more or less the direction your code snippet is journeying, except your manually coded partial Person class would have an inner class, like:

[MetadataType(typeof(Person.Metadata))]
public partial class Person {
private sealed class MetaData {
[RegularExpression(...)]
public string Email { get; set; }
}
}

Or you could have your manually partial Person class and a separate Meta class like:

[MetadataType(typeof(PersonMetaData))]
public partial class Person { }

public class PersonMetaData {
[RegularExpression(...)]
public string Email;
}

These are workarounds and having a mapped Presentation class may be more suitable.

Entity Framework 6 Add Data Annotations on referenced class

There are fluent APIs for this purpose.

EDIT

About your mapping you have to override OnModelCreating

public class TestContext : DbContext
{
public DbSet<User> Users { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{

modelBuilder.Entity<User>()
.ToTable("user")
.HasKey(_ => _.Id);

modelBuilder.Entity<User>()
.Property(_ => _.Id).HasColumnName("id");

modelBuilder.Entity<User>()
.Property(_ => _.UserName).HasColumnName("username"); // Add also HasMaxLength here
}
}

(if your database already exists and it's not created by EF on your model you need to disable also migrations)

EDIT

If you installed SQL Server with a CI codepage, column name casing is not important. So you need only to specify HasMaxLength

Data Annotations with Entity Framework 5.0 (database first)

Although it's somewhat painful, you need to create a class to use as the MetadataType for your model class.

[MetadataType(typeof(PayrollMarkupMetadata))
public partial class PayrollMarkup_State
{
...
}

public class PayrollMarkupMetadata
{
[UIHint("StatesEditor")]
public string State; // Has to have the same type and name as your model
// etc.
}

Adding annotation [key] in metaDataClass for an entity generated by EF database first

Can you please make sure that both your partial class definitions are in the same namespace?
For multiple partial definitions to be combined into one class, all those definitions have to share the same namespace.

These should be in the same project too. When you press F12(or choose go to defintion) while highlighting the class name, it should ask you which partial definition you want to go to. That way, you can verify that these two are linked.

Otherwise try declaring public int personId { get; set; } in your empty partial class and see if that raises an error.

Data Annotations to Entity Framework generated class

I found the solution here:
http://ryanhayes.net/blog/data-annotations-for-entity-framework-4-entities-as-an-mvc-model/
basically i had to make this:

    [MetadataType(typeof(Proc_ResultMetaData))]
public partial class Proc_Result
{
// Note this class has nothing in it. It's just here to add the class-level attribute.
}

public partial class Proc_ResultMetaData
{
public int Id { get; set; }
[DisplayName("Registeration Number")]
public string RegistrationNumber { get; set; }
public string Name { get; set; }

[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public Nullable<System.DateTime> DateOfEntry { get; set; }
public string Drawer { get; set; }
}

That got it working.



Related Topics



Leave a reply



Submit