Con Fluent Nhibernate Automapper, uno se da cuenta rápidamente de que el comportamiento fuera de la caja para columnas varchar es menos que ideal. Primero descubre que cada propiedad de cadena se exportó como varchar (255) y necesita hacer que una columna sea varchar (max). Pero idealmente, no tendrías que hacer que cada cadena sea varchar (max), ¿verdad? De modo que puede seguir ese camino trillado para encontrar la mejor forma de ejercer control sobre el proceso sin romper los diversos patrones elegantes en juego ...
Si desea que las columnas varchar de la base de datos resultantes se especifiquen en diferentes longitudes, busca en las clases de convenciones para hacerlo realidad. Puede tratar de crear condiciones específicas de nombre o, en general, usar algún patrón de denominación que haya detectado dentro de su clase de convención.
Ninguno es ideal. Sobrecargar un nombre con el propósito de indicar una especificación prevista en otra parte del código es desafortunado; su nombre debería ser simplemente un nombre. Tampoco debe modificar el código de convención cada vez que necesite agregar o modificar una propiedad de clase de longitud limitada. Entonces, ¿cómo puedes escribir una clase de convención que te dé el control y te brinde ese control de una manera simple y elegante?
Sería dulce si sólo puede decorar su propiedad como lo hice para la propiedad Body aquí:
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 esto podría funcionar, tendríamos el control sobre cada cuerda de forma independiente , y podríamos especificarlo directamente en nuestra entidad.
Antes de comenzar una vorágine de separación de la base de datos de la aplicación, permítanme señalar que esta no es específicamente una directiva de base de datos (me referí a no llamar al atributo 'Varchar'). Prefiero caracterizar esto como un aumento de System.string, y en mi pequeño universo estoy contento con eso. En resumen, quiero una conveniencia!
Para ello, es necesario definir la decoración que queremos utilizar:
using System;
namespace MyDomain.DBDecorations
{
[AttributeUsage(AttributeTargets.Property)]
public class StringLength : System.Attribute
{
public int Length = 0;
public StringLength(int taggedStrLength)
{
Length = taggedStrLength;
}
}
}
Por último, tenemos que utilizar una convención de longitud de la cadena de usar la decoración propiedad de la entidad. Esta parte puede no parecer bonita, pero cumple su función, ¡y la buena noticia es que no tendrá que volver a mirarla!
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);
}
}
}
Añadir esta convención a la configuración automapping y ahí lo tienes IT siempre que lo desee una longitud específica que resulte durante ExportSchema, ahora sólo puede decorar la propiedad de cadena -y sólo esa propiedad, ¡justo en tu entidad!
Justo lo que estaba buscando, ah y para cualquier otra persona Agregue esta línea al método GetConventions() en el archivo utoPersistenceModelGenerator c.Add(); –
TheAlbear