我在数据库中有2个表。配方和成分。 它们具有多对多关系,因此我在db中有一个名为FormulaIngredient的关联表。
我正在使用C#.net和SQL server 2005。 我的FormulaIngredient表有ID,formulaID,ingredientID,ingredientAmount。 对于这个额外的ingredientAmount字段,我在C#中创建了一个关联类。 现在,我将在数据库中保存一个公式。之后我想在FOrmulaIngredient表中保存该公式的成分列表。 我该怎么做?我无法保存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 :(得分:1)
在获得除外键之外的额外列时(如在您的情况下为IngredientAmount列),总是应该映射一个assosiation表。有必要映射关联列不仅是为了保存额外列中的数据,而且还能够检索它。如果您将关联表保留为未映射状态,那么您无法轻松地从数据库中读取其额外数据(IngredientAmount列)。
虽然映射了关联表,但这意味着您必须从Formula创建一对多属性到关联表(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列。
保存到关联表的方法是首先保存公式对象,然后根据需要保存尽可能多的成分对象,然后使用保存的公式和成分对象的ID,您可以保存已填充的公式对象他们的IngredientAmount属性/列。
我相信如果有替代方案,它们将涉及复杂的机制(监听器,手动SQL插入语句等),只是为了保存和检索属于关联的数据而不是关联的主要实体,并将其作为主要实体的一部分获取实体(配方或成分)。
答案 1 :(得分: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。