Avec Nhibernate Fluent Automapper, on se rend vite compte que la dehors-de-le-boîte de comportement pour les colonnes varchar est pas l'idéal. Tout d'abord vous découvrir que chaque chaîne de propriété a été exporté en tant que varchar(255) et vous avez besoin de faire une colonne de type varchar(max). Mais, idéalement, vous ne devriez pas avoir à faire de chaque chaîne de type varchar(max), droit? Si vous vous dirigez vers le bas que bien battus de chemin de trouver la meilleure façon d'exercer un contrôle sur le processus, sans briser les différents modèles élégants à jouer...
Si vous voulez avoir votre base de données varchar colonnes spécifiées, à des longueurs différentes, vous regardez à la convention des classes pour y arriver. Vous pouvez essayer de créer le nom spécifique de conditions ou de façon générale, l'utilisation de certains modèle de nommage que vous avez détecté à l'intérieur de votre convention de classe.
Aucune n'est idéale. La surcharge d'un nom dans le but d'indiquer une intention de spec dans une autre partie du code est malheureux, votre nom doit être juste un nom. Vous ne devriez pas avoir à modifier le code de la convention chaque fois que vous avez besoin d'ajouter ou de modifier une limitée-durée de propriété de la classe. Alors, comment pouvez-vous écrire une convention de classe qui vous donne le contrôle et prévoit que le contrôle dans une façon simple et élégante?
Ce serait gentil si vous pouvez simplement décorer votre propriété comme je l'ai fait pour le Corps bien ici:
using System;
using MyDomain.DBDecorations;
namespace MyDomain.Entities {
[Serializable]
public class Message
{
public virtual string MessageId { get; set; }
[StringLength(4000)] public virtual string Body { get; set; }
}
}
Si cela pourrait fonctionner, nous aimerions avoir le contrôle sur chaque chaîne de façon indépendante, et nous serions en mesure de le spécifier directement dans notre entité.
Avant que je commence un maelström sur la séparation de la base de données de l'application, permettez-moi de souligner que ce n'est pas spécialement une base de données de la directive (j'ai fait un point de ne pas appeler l'attribut "Varchar"). Je préfère caractériser ce que l'augmentation de la Système.chaîne, et dans mon petit univers j'en suis heureux. Bas de ligne, je veux une commodité!
Pour ce faire, nous avons besoin de définir la décoration nous voulons utiliser:
using System;
namespace MyDomain.DBDecorations
{
[AttributeUsage(AttributeTargets.Property)]
public class StringLength : System.Attribute
{
public int Length = 0;
public StringLength(int taggedStrLength)
{
Length = taggedStrLength;
}
}
}
Enfin, nous avons besoin d'utiliser une chaîne de caractères de longueur de la convention pour l'emploi de l'entité est la décoration de la propriété. Cette partie peut ne pas sembler peu, mais il fait le travail, et la bonne nouvelle est que vous n'aurez pas à le regarder de nouveau!
StringColumnLengthConvention.cs:
using System.Reflection;
using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.AcceptanceCriteria;
using FluentNHibernate.Conventions.Inspections;
using FluentNHibernate.Conventions.Instances;
namespace MyMappings
{
public class StringColumnLengthConvention : IPropertyConvention, IPropertyConventionAcceptance
{
public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) { criteria.Expect(x => x.Type == typeof(string)).Expect(x => x.Length == 0); }
public void Apply(IPropertyInstance instance)
{
int leng = 255;
MemberInfo[] myMemberInfos = ((PropertyInstance)(instance)).EntityType.GetMember(instance.Name);
if (myMemberInfos.Length > 0)
{
object[] myCustomAttrs = myMemberInfos[0].GetCustomAttributes(false);
if (myCustomAttrs.Length > 0)
{
if (myCustomAttrs[0] is MyDomain.DBDecorations.StringLength)
{
leng = ((MyDomain.DBDecorations.StringLength)(myCustomAttrs[0])).Length;
}
}
}
instance.Length(leng);
}
}
}
Ajouter cette convention à votre mappant automatiquement la configuration et là vous l'avez - chaque fois que vous voulez une longueur spécifique de résultat au cours de ExportSchema, maintenant vous pouvez simplement décorer la propriété de chaîne -et uniquement celle du droit de propriété dans votre entité!