2010-01-26 3 views
1

J'essaye de faire en sorte que Fluent NHibernate 1.0 RTM mette en correspondance une entité User pour que j'aie accès à UserId et UserName dans mon application ASP.NET MVC via NHibernate.Comment mapper une partie de la table aspnet_Users en utilisant Fluent NHibernate

J'ai:

public class User 
{ 
    public virtual Guid UserId { get; protected set; } 
    public virtual string UserName { get; protected set; } 
} 

Il représente la table aspnet_Users avec uniquement les colonnes pertinentes à cartographiés. C'est la seule entité qui n'est pas automappée. Voici ma correspondance:

public class UserMap : ClassMap<User> 
{ 
    public UserMap() 
    { 
     Id(x => x.UserId); 
     Map(x => x.UserName); 
     WithTable("aspnet_Users"); 
    } 
} 

Tout le reste est automapped avec des conventions.

Voici mon PrimaryKeyConvention et TableNameConvention:

public class PrimaryKeyConvention : IIdConvention 
{ 
    public void Apply(IIdentityInstance instance) 
    { 
     instance.Column(instance.Property.ReflectedType.Name + "Id"); 
     instance.UnsavedValue(System.Guid.Empty.ToString()); 
     instance.GeneratedBy.GuidComb(); 
    } 
} 

public class TableNameConvention : IClassConvention 
{ 
    public void Apply(IClassInstance instance) 
    { 
     instance.Table(Inflector.Net.Inflector.Pluralize(instance.EntityType.Name)); 
    } 
} 

Le processus de mappage échoue juste après l'exécution du code ClassMap (qui vient avant tout AutoMapping), suivi du code de TableNameConvention, suivi du code de PrimaryKeyConvention. L'échec est dans PrimaryKeyConvention, car instance.Property est null. J'ai essayé de faire un if (instance.Property! = Null) mais que termine le processus de mappage au début avec une erreur "l'attribut required 'class' missing". J'ai aussi eu un if (instance.EntityType! = Typeof (User)) dans le TableNameConvention, mais a sorti quand il ne faisait aucune différence.

Que se passe-t-il ici? Tout d'abord, pourquoi les processus AutoMapping appellent-ils les conventions pour ClassMap? Deuxièmement, pourquoi PrimaryKenConvention obtient-il une instance.Property == null? Comment puis-je faire en sorte que le processus de mappage se déplace et mappe le reste de mes entités en utilisant AutoMapping + conventions?

Remarque, j'ai tout cela fonctionné pendant des mois sous une version antérieure de FNH avant le refactor pour 1.0 RTM.

Répondre

1

J'ai trouvé la réponse à cette question.

public UserMap() 
{ 
    Id(x => x.UserId); 
    Map(x => x.UserName); 
    Table("aspnet_Users"); 
} 

public class PrimaryKeyConvention : IIdConvention 
{ 
    public void Apply(IIdentityInstance instance) 
    { 
     instance.Column(instance.EntityType.Name + "Id"); 
     instance.UnsavedValue(System.Guid.Empty.ToString()); 
     instance.GeneratedBy.GuidComb(); 
    } 
} 

public class TableNameConvention : IClassConvention 
{ 
    public void Apply(IClassInstance instance) 
    { 
     instance.Table(Inflector.Net.Inflector.Pluralize(instance.EntityType.Name)); 
    } 
} 

Notez que le PrimaryKeyConvention définit le nom de la colonne à l'aide instance.EntityName plutôt que instance.Property. Ce dernier était null pour UserMap, donc il planterait.

Cette approche est préférable à l'utilisation d'une instruction conditionnelle sur (null! = Instance.Property) et de garder la ligne instance.Property.ReflectedType.Name, mais les deux fonctionnent. Si vous choisissez d'utiliser cette route, vous devez définir explicitement les noms de colonne dans le UserMap:

public UserMap() 
{ 
    Id(x => x.UserId).Column("UserId") 
        .GeneratedBy.Assigned(); 
    Map(x => x.UserName).Column("UserName"); 
    Table("aspnet_Users"); 
} 
0

Je n'utilise pas l'auto-mappage moi-même, mais je pense que vous devez mapper l'utilisateur en implémentant IAutoMappingOverride. Quelque chose comme:

public class UserMap : IAutoMappingOverride<User> 
{ 
    public void Override(AutoMapping<User> mapping) 
    { 
     mapping.Id(x => x.UserId); 
     mapping.Map(x => x.UserName); 
     mapping.WithTable("aspnet_Users"); 
    } 
} 
+0

hi Jamie. Les remplacements sont uniquement pour les objets qui seront mappés en tant qu'entités par l'automapper. J'utilise un objet de base appelé Entity pour encapsuler Id, CreatedDate, etc. et toutes les entités en héritent. Cependant, mon objet User n'hérite d'rien, car il ne respecte pas les exigences de l'entité en voyant comment la conception est dictée par la table aspnet_Users. J'utilise .ignoreBase lors de la configuration de l'AutoMap. Par conséquent, je ne peux pas faire un remplacement comme vous le recommandiez depuis que l'utilisateur n'a jamais été mappé pour commencer. –

Questions connexes