2017-04-13 2 views
0

Un peu contexte:Fluent NHibernate: Comment les clés étrangères sont-elles définies avec HasMany, insérées ou mises à jour?

J'ai de nombreux cas de SomeCollection qui stockent beaucoup Rule informations qui doit être persisté à la base de données. Chaque Rule dans la base de données a un ID incrémenté automatiquement (PK) et un RuleId personnalisé. La table Rule contient également une clé étrangère, qui est l'ID de la collection. La table Rule contient une contrainte unique sur RuleId et CollectionId.


Question:

  1. Comment les clés étrangères insérées dans les tables lors de la projection avec HasMany, est à jour après que l'enfant est inséré? Je demande comme null est montré dans les messages ci-dessous, mais je sais que les valeurs sont définies

  2. Si ce qui précède est vrai ou faux, comment puis-je appliquer une contrainte unique multi-colonne et éviter le problème détaillé ci-dessous.

Quand je mets appliquer la contrainte unique dans SomeCollectionMapping, je reçois la violation suivante:

détectée FCE: System.Data.SqlClient.SqlException (0x80131904): Violation de contrainte UNIQUE KEY ' UQ__supporte__4D7ABD34DC8C8A20 '. Impossible d'insérer une clé dupliquée dans l'objet 'dbo.rules'. La valeur de clé dupliquée est (123, NULL).

Les données est d'essayer encartage est:

123, myId1 
123, myId2 

Si je laisse de côté les lignes: part.Not.Nullable() et part.UniqueKey("uniqueRef") les données sont insérées avec succès dans les deux tables, mais ne l'applique pas unique.

Même si l'insertion utilisant Fluent NHibernate échoue, je peux insérer des données à l'aide de Microsoft SQl Server Management Studio sans problèmes, et la contrainte multi-colonnes fonctionne correctement.



SomeCollection.cs

internal class SomeCollection 
{ 
    public SomeCollection() 
    { 
     this.CollectionId = string.Empty; 
     this.CollectionName = string.Empty; 
     this.Rules = new List<Rule>(); 
    } 

    public virtual string CollectionId { get; set; } 

    public virtual string CollectionName { get; set; } 

    public virtual IList<Rule> Rules { get; set; } 
} 

Rule.cs

internal class Rule 
{ 
    public Rule() 
    { 
     this.DisplayName = string.Empty; 
     this.RuleId = string.Empty; 
     this.MyValue = 0; 
    } 

    public virtual string DisplayName { get; set; } 

    public virtual string RuleId { get; set; } 

    public virtual int MyValue { get; set; } 
} 

SomeCollectionMapping.cs

internal sealed class SomeCollectionMapping : ClassMap<SomeCollection> 
{ 
    private const string TableName = "some_collections"; 

    public SomeCollectionMapping() 
    { 
     this.Table(TableName); 

     this.Id(x => x.CollectionId) 
      .Not.Nullable() 
      .Column("collectionId") 
      .UniqueKey("abc123"); 

     this.Map(x => x.CollectionName) 
      .Column("name") 
      .Not.Nullable(); 

     this.HasMany<Rule>(x => x.Rules) 
      .KeyColumns.Add("collectionId", part => 
      { 
       // No violations if I omit these two lines 
       part.Not.Nullable(); 
       part.UniqueKey("uniqueRef"); 
      }) 
      .Cascade.All(); 
    } 
} 

RuleMapping.cs

internal sealed class RuleMapping : ClassMap<Rule> 
{ 
    private const string TableName = "rules"; 

    public RuleMapping() 
    { 
     this.Table(TableName); 

     this.Id().GeneratedBy.Increment().Unique(); 

     this.Map(x => x.RuleId) 
      .Not.Nullable() 
      .UniqueKey("uniqueRef") 
      .Column("ruleId"); 

     this.Map(x => x.DisplayName) 
      .Column("name") 
      .Not.Nullable(); 

     this.Map(x => x.MyValue) 
      .Column("myValue") 
      .Not 
      .Nullable(); 
    } 
} 

Nhibernate 4.1.1 FluentNHibernate 2.0.3.0 SQLServer

+0

Ajouté ma propre réponse qui semble avoir corrigé tous les problèmes, mais il ne répond pas vraiment à ma question principale de pourquoi. N'hésitez pas à continuer à contribuer. Merci. – BlackBox

+0

Avez-vous vu [this] (/ q/11468668/1178314)? –

Répondre

0

droit. Après des essais aléatoires, j'ai ajouté Not.KeyNullable() à la chaîne HasMany. Les données sont maintenant correctement insérées et aucune exception n'est levée. Les contraintes uniques et not null fonctionnent correctement.

Cela semble être une solution, mais si quelqu'un d'autre veut répondre avec plus de détails, je serai heureux de les recevoir et de les accepter à la place.