2009-11-05 61 views
0

我在數據庫中有2個表。配方和成分。 他們有多對多的關係,所以我有一個名爲FormulaIngredient的db關聯表。如何使用NHibernate將數據插入多對多關聯表中

我正在使用C#.net和SQL服務器2005. 我的FormulaIngredient表具有ID,formulaID,ingredientID,ingredientAmount。 對於這個額外的成分,我在C#中創建了一個關聯類。 現在,我將在數據庫中保存一個公式。之後我想將該配方的成分列表保存在FOrmulaIngredient Table中。 我該怎麼做?我無法在FormulaIngredient表中保存任何數據。 我FormulaIngredient類是

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; } 
     } 
    } 
} 

這裏是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> 

請幫助!!!!

+0

確保在發佈時將代碼縮進4個空格,以便代碼正確拾取。 – 2009-11-05 08:46:47

回答

0

您不需要將連接表映射到它自己的類型。此外,您不應該公開其他類的屬性中的Formula.ID。以下是你需要什麼

3數據庫中的表

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; } 
} 

這裏是映射:

<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> 

添加到這樣的集合:

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(); 

你不應該需要將連接表映射爲自己的類。也允許類封裝他們自己的類型。唯一應該返回公式ID的是公式。例如,您不會將「FormulaID」放入配料中,而是調用formula.ID。

+1

如果我在FormulaIngredientJoin表中有一些額外的字段,該怎麼辦?我在FormulaIngredientJoin Table中有一個名爲IngredientAmount的字段。這就是爲什麼我需要將連接表映射到它自己的類。我會盡量實現你提到的保存部分。如果我成功了,我會告訴你。 – user203212 2009-11-10 16:30:08

1

一個協調錶應該總是被映射在它得到一個額外的列而不是外鍵的時刻(就像在你的例子中爲IngredientAmount列一樣)。有必要映射關聯列,不僅爲了保存額外列中的數據,而且還能夠檢索它。如果您不關聯關聯表,那麼您就沒有簡單的方法從數據庫中讀取其額外數據(IngredientAmount列)。

將關聯表映射到其中但意味着您必須創建一個從公式到關聯表(FormulaIngredient)的一對多屬性,然後您可以選擇包含或不包含(由您決定)成分表中的多對多屬性。

<bag name="FormulaIngredients" lazy="true" inverse="true" cascade="all-delete-orphan"> 
    <key column="FormulaID" /> 
    <one-to-many class="FormulaIngredient" /> 
</bag> 

<bag name="Ingredients" table="FormulaIngredient" lazy="true" cascade="all"> 
    <key column="FormulaID" /> 
    <many-to-many column="IngredientID" class="Ingredient" /> 
</bag> 

通過級聯或手動(再次選擇)保存數據。

如果使用Ingredients屬性來使用級聯保存Ingredient對象,則無法將任何數據保存到關聯表(FormulaIngredient)的IngredientAmount列中。

保存到關聯表中的方法是首先保存Formula對象,然後根據需要保存許多成分對象,然後使用已保存的Formula和Ingredient對象的ID,您可以保存已填充的FormulaIngredient對象還有他們的IngredientAmount屬性/列。

我相信如果有替代方案,他們會涉及複雜的機制(聽衆,手動SQL插入語句等),只是爲了保存和檢索屬於該關聯的數據而不是關聯的主要實體,並將其作爲其中一個主要實體(配方或成分)。

相關問題