2009-11-05 53 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插入语句等),只是为了保存和检索属于该关联的数据而不是关联的主要实体,并将其作为其中一个主要实体(配方或成分)。

相关问题