2009-11-05 8 views
0

J'ai 2 tables dans la base de données. Formule et ingrédient. Ils ont une relation many-to-many, donc j'ai une table d'association dans la base de données appelée FormulaIngredient. J'utilise C# .net et SQL Server 2005. Ma table FormulaIngredient a ID, formulaID, ingredientID, ingredientAmount. Pour ce champ supplémentaire de l'ingrédientAmount, j'ai créé une classe d'association en C#. Maintenant, je vais enregistrer une formule dans la base de données. et après cela, je veux sauvegarder la liste des ingrédients de cette formule dans le tableau FOrmulaIngredient. Comment puis-je le faire? Je ne peux pas enregistrer de données dans la table FormulaIngredient. Ma classe FormulaIngredient estComment insérer des données dans une table Association many-to-many en utilisant NHibernate

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace NutritionLibrary.Entity 
{ 



    public class FormulaIngredient 
    { 
     private int iD; 

     private Formula objFormula; 
     private Ingredient objIngredient; 
     private float ingredientAmount; 


     public FormulaIngredient() 
     { 

     } 


     public virtual int ID 
     { 
      get { return iD; } 
      set { iD = value; } 
     } 


     public virtual int IngredientID 
     { 
      get { return objIngredient.IngredientID; } 
      set { objIngredient.IngredientID = value; } 
     } 

     public virtual int FormulaID 
     { 
      get { return objFormula.FormulaID; } 
      set { objFormula.FormulaID = value; } 
     } 

     public virtual Ingredient ObjIngredient 
     { 
      get { return objIngredient; } 
      set { objIngredient = value; } 
     } 
    public virtual Formula ObjFormula 
     { 
      get { return objFormula; } 
      set { objFormula = value; } 
     } 
     public virtual float IngredientAmount 
     { 
      get { return ingredientAmount; } 
      set { ingredientAmount = value; } 
     } 
    } 
} 

est le fichier de mappage ici pour FormulaIngredient:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> 
    <class name="NutritionLibrary.Entity.FormulaIngredient, NutritionLibrary" table="NutrientIngredient" lazy="false"> 
    <id name="ID" column="ID" > 
     <generator class="native" /> 
    </id> 

    <many-to-one name="ObjIngredient" column="ingredientID" class="NutritionLibrary.Entity.Ingredient, NutritionLibrary" not-null="true" /> 
    <many-to-one name="ObjFormula" column="formulaID" class="NutritionLibrary.Entity.Formula, NutritionLibrary" not-null="true" /> 

    <property name="IngredientAmount" column="ingredientAmount" type="float" not-null="true" /> 


    </class> 
</hibernate-mapping> 

S'il vous plaît aider !!!!

+0

Assurez-vous de mettre en retrait votre code de 4 espaces lorsque vous postez afin qu'il soit correctement ramassé en tant que code. –

Répondre

0

Vous n'avez pas besoin de mapper votre table de jointure avec son propre type. Et aussi, vous ne devez pas exposer Formula.ID à partir d'une propriété d'une autre classe. Voici ce que vous avez besoin

3 base de données Tableaux

Ingredients: PK:ID(Identity(1,1), Name, Description 
Formula: PK:ID(Identity(1,1), Name, Description 
IngredientFormulaJoin: FK:IngredientID, FK:FormulaID 

create table dbo.Ingredients(id int primary key identity(1,1), Name varchar(100)) 
create table dbo.formulas(id int primary key identity(1,1), Name varchar(100)) 
create table dbo.ingredientformulajoin(ingredientid int foreign key references dbo.ingredients(id), formulaid int foreign key refernces dbo.formula(id)) 

public class Forumula() { 
    public Formula(){ 
    Ingredients = new List<Ingredient>(); 
} 
    public int PK:ID(Identity(1,1) { get; set; } 
    public IList<Ingredient> Ingredients{ get; set; } 
} 

public class Ingredient() { 
public Ingredient(){ 
    Formulas = new List<Formula> 
} 


    public int ID { get; set; } 
    public IList<Forumula> Formulas { get; set; } 
} 

Voici le mapping:

<class name="App.Core.Domain.Ingredient, App.Core" table="ingredients"> 
    <set name="Formulas" table="formulaingredientjoin" inverse="false" cascade="all"> 
     <key column="ingredientid"/> 
     <many-to-many class="App.Core.Domain.Forumula, App.Core" column="formulaid"/> 
    </set> 
</class> 


<class name="App.Core.Domain.Formula, App.Core" table="formulas"> 
    <set name="Ingredients" table="formulaingredientjoin" inverse="false" cascade="all"> 
     <key column="formulaid"/> 
     <many-to-many class="App.Core.Domain.Ingredient, App.Core" column="ingredientid"/> 
    </set> 
</class> 

Ajouter aux collections comme celle-ci:

Formula formula = new Formula(); 
formula.Ingredients.Add(ingredient1) 
formula.Ingredients.Add(ingredient2) 
formula.Ingredients.Add(ingredient3) 
session.Save(formula); 
session.Flush(); 

Ingredient ingredient = new Ingredient(); 
ingredeient.Formulas.Add(formula1); 
ingredeient.Formulas.Add(formula2); 
session.Save(ingredient); 
session.Flush(); 

Vous ne devriez jamais avoir à Mappez une table de jointure en tant que sa propre classe. Autorisez également les classes à encapsuler leurs propres types. La seule chose qui devrait renvoyer un ID de formule est une formule. Vous ne mettriez pas 'FormulaID' dans les ingrédients par exemple, appelez formula.ID.

+1

Et si j'ai un champ supplémentaire dans la table FormulaIngredientJoin? J'ai un champ appelé IngredientAmount dans la table FormulaIngredientJoin. C'est pourquoi j'avais besoin de mapper la table de jointure avec sa propre classe. Je vais essayer d'implémenter la partie sauvegarde comme vous l'avez mentionné. Je vous ferai savoir si j'ai réussi. – user203212

1

Une table d'assosiation doit TOUJOURS être mappée au moment où elle reçoit une colonne supplémentaire autre que les clés étrangères (comme dans votre cas la colonne IngredientAmount). Il est nécessaire de mapper la colonne d'association non seulement pour sauvegarder les données dans la colonne supplémentaire, mais aussi pour pouvoir les récupérer. Si vous laissez la table d'association non mappée, vous n'avez aucun moyen facile de lire ses données supplémentaires (colonne IngredientAmount) à partir de la base de données. Si la table d'association est mappée, cela signifie que vous devez créer une propriété un-à-plusieurs de Formula à la table d'association (FormulaIngredient), puis vous pouvez également inclure ou non cette option (à vous de choisir)) la propriété many-to-many de la table Ingrédients. L'enregistrement des données peut se faire en cascade ou manuellement (encore une fois votre choix).

Si vous utilisez la propriété Ingredients pour enregistrer des objets Ingredient en cascade, vous ne pourrez pas enregistrer de données dans la colonne IngredientAmount de la table d'association (FormulaIngredient). Pour enregistrer dans la table d'association, vous devez d'abord enregistrer l'objet Formula, puis enregistrer autant d'objets Ingredient que vous le souhaitez, puis utiliser les ID des objets Formula et Ingredient enregistrés pour enregistrer les objets FormulaIngredient que vous avez renseignés. également leur propriété/colonne IngredientAmount.Je crois que s'il y a des alternatives ils impliqueront des mécanismes compliqués (Auditeurs, instructions d'insertion SQL manuelles etc) juste pour enregistrer et récupérer les données qui appartiennent à l'association et NON les entités principales associées et les récupérer dans le cadre de l'une des entités principales (Formule ou Ingrédient).

Questions connexes