Zur Zeit wird gefiltert nach: dataannotation
Filter zurücksetzen

Entity Framework 4.1 und die DataAnnotations bei DB First

Mit der Stand alone - Installation von EF 4.1 steht auch eine einfache T4-Vorlage zur Verfügung, die den DbContext für die Verwendung mit dem Entity Designer ermöglicht. Ein hilfreiches Feature ist die Validierung mit den DataAnnotations, welche beim Code First-Ansatz auch Einfluss auf das Datenbankdesign haben.

Mit der T4-Vorlage werden jedoch nur die Klassen erstellt. Da die Datenbank besteht, werden die Pflichtfelder und die Eingabelänge bereits definiert sein.

Folgende Abbildungen verdeutlichen dies:

Abbildung 1
Abbildung 1: Eigenschaften mit den Einstellungen vom Datenbankdesign
Abbildung 2
Abbildung 2: Erstellte Klasse aus dem EDM für den DbContext

Es werden einfache POCO-Klassen erstellt. Wer die DataAnnonations auch erstellt haben will, der muss das Selbst tun. Mit T4 geht das auch einfach von der Hand. Der Vorteil dieser Variante ist ganz klar die Individualität, die dadurch erreicht werden kann. Gerade bei mehrsprachigen Anwendungen ist die Verwendung von Ressourcen sinnvoll. In manchen Fällen wurden prozessspezifische Anpassungen vorgenommen, sodass die neue T4-Vorlage auf diese Prozesse abgestimmt werden kann.

Meine Vorgehensweise ist sehr einfach. Ich habe eine Quick & Dirty - Vorlage erstellt, die aus den Angaben des Entity Designers die Infrastruktur für die Validierung erstellt. In ca. 10 min war ich damit auch fertig.

Als erstes habe ich den Inhalt aus der T4-Vorlage verwendet, die für die Erstellung der POCO's verantwortlich ist. Anschliessend habe ich den EntityFrameworkTemplateFileManager durch den TemplateFileManager ersetzt und die Klassenerstellung gemäss den DataAnnotations angepasst.

Die T4-Vorlage hat nun folgenden Aufbau:


<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".txt" #>
<#@ assembly name="Microsoft.CSharp" #>
<#@ include file="EF.Utility.CS.ttinclude"#>
<#@ include file="TemplateFileManager.CS.ttinclude" #>
<# 
var fileManager = TemplateFileManager.Create(this);

CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);

string inputFile = @"Model1.edmx";
EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();

foreach (var entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{
    fileManager.StartNewFile(entity.Name + ".DataAnnotations.cs");
    this.CreateDataAnnotationClass(code, entity, namespaceName);
}

foreach (var entity in ItemCollection.GetItems<ComplexType>().OrderBy(e => e.Name))
{
    fileManager.StartNewFile(entity.Name + ".DataAnnotations.cs");
    this.CreateDataAnnotationClass(code, entity, namespaceName);
}

fileManager.Process();
#>


<#+ 
void CreateDataAnnotationClass(CodeGenerationTools code, object entityType, string namespaceName)
{
	dynamic entity = entityType as EntityType;
	if (entity == null)	
		entity =  entityType as ComplexType;
#>
namespace <#= namespaceName #>
{
	using System.Data;
	using System.ComponentModel.DataAnnotations;
	
	[MetadataType(typeof(<#= entity.Name #>MetaData))]
	public partial class <#= entity.Name #>
	{
	}
	
	public class <#= entity.Name #>MetaData
	{
<#+ 
		foreach (var item in entity.Properties)
		{
#>
		<#= item.Nullable == false ? String.Empty : "[Required(ErrorMessage=\"Message Required\")]" #>
		<#= this.TransformStringLenghtAttribute(item) #>
		public object <#= item.Name #> {<#= code.SpaceAfter(Accessibility.ForGetter(item)) #> get;<#= code.SpaceAfter(Accessibility.ForSetter(item)) #> set; }
<#+ 
		}
#>
	}
}
<#+	
}

public string TransformStringLenghtAttribute(EdmProperty item)
{
	Facet f = item.TypeUsage.Facets.Where(t => t.Name == "MaxLength").FirstOrDefault();
	string sl = String.Empty;
	if (f != null)
	{
		string length = f.Value.ToString();
		if (length == "Max")
			length = Int32.MaxValue.ToString();
		
		sl = String.Format("[StringLength({0}, ErrorMessage=\"Too long\")]", length);
	}
	
	return sl;
}	
#>

Mit ein bisschen mehr Zeit kann die Vorlage auch besser umgesetzt und erweitert werden. So können zum Beispiel auch Validierungsmechanismen aus Datentypen oder Namen (Email) abgeleitet werden.

Die Klassen, die nun erstellt werden, haben folgenden Aufbau:

Abbildung 3
Abbildung 3 DataAnnotations, abgleitet aus Datenmodell

Der Vorteil dieser Variante ist auch, dass eine Kombination mit anderen Validierungsschnittstellen möglich wird. So liesse sich bspw. auch der Einsatz von Reflection reduzieren, aber das ist bekanntlich Geschmacksache.

Zurück

Translate this page

Kategorien

  • [-].NET Development (215)
  • [-]Datenbank (26)
  • HTML (1)
  • Konfiguration (12)
  • Mind Map (10)
  • Off-topic (9)
  • Open Source (3)
  • Qualität (7)
  • Sharepoint (6)
  • Sicherheit (2)

Archiv

Social Bookmarking

Bookmark bei: Mr. Wong Bookmark bei: Webnews Bookmark bei: Icio Bookmark bei: Oneview Bookmark bei: Linkarena Bookmark bei: Favoriten Bookmark bei: Seekxl Bookmark bei: Favit Bookmark bei: Social Bookmarking Tool Bookmark bei: Power Oldie Bookmark bei: Bookmarks.cc Bookmark bei: Newskick Bookmark bei: Newsider Bookmark bei: Linksilo Bookmark bei: Readster Bookmark bei: Folkd Bookmark bei: Yigg Bookmark bei: Digg Bookmark bei: Del.icio.us Bookmark bei: Reddit Bookmark bei: Simpy Bookmark bei: StumbleUpon Bookmark bei: Slashdot Bookmark bei: Netscape Bookmark bei: Furl Bookmark bei: Yahoo Bookmark bei: Spurl Bookmark bei: Google Bookmark bei: Blinklist Bookmark bei: Blogmarks Bookmark bei: Diigo Bookmark bei: Technorati Bookmark bei: Newsvine Bookmark bei: Blinkbits Bookmark bei: Ma.Gnolia Bookmark bei: Smarking Bookmark bei: Netvouz Information