Fluent NHibernate多对一映射

Fluent NHibernate多对一映射,nhibernate,nhibernate-mapping,fluent,Nhibernate,Nhibernate Mapping,Fluent,我不熟悉冬眠世界。这可能是一个愚蠢的问题,但我无法解决它。我正在测试表的多对一关系,并尝试插入记录。我有部门表和员工表。员工和部门在这里有多对一关系。我正在使用Fluent NHibernate添加记录。所有代码如下。请帮忙 SQL代码 create table Dept ( Id int primary key identity, DeptName varchar(20), DeptLocation varchar(20) ); create table Employ

我不熟悉冬眠世界。这可能是一个愚蠢的问题,但我无法解决它。我正在测试表的多对一关系,并尝试插入记录。我有部门表和员工表。员工和部门在这里有多对一关系。我正在使用Fluent NHibernate添加记录。所有代码如下。请帮忙

SQL代码

create table Dept (
    Id int primary key identity,
    DeptName varchar(20),
    DeptLocation varchar(20)
);

create table Employee (
    Id int primary key identity,
    EmpName varchar(20),
    EmpAge int,
    DeptId int references Dept(Id)
);
类文件

public partial class Dept
{
    public virtual System.String DeptLocation { get; set; }
    public virtual System.String DeptName { get; set; }
    public virtual System.Int32 Id { get; private  set; }
    public virtual IList<Employee> Employees { get; set; }
}

public partial class Employee
{
    public virtual System.Int32 DeptId { get; set; }
    public virtual System.Int32 EmpAge { get; set; }
    public virtual System.String EmpName { get; set; }
    public virtual System.Int32 Id { get; private set; }
    public virtual Project.Model.Dept Dept { get; set; }
}
public class DeptMapping : ClassMap<Dept>   
{
    public DeptMapping()
    {
        Id(x => x.Id);
        Map(x => x.DeptName);
        Map(x => x.DeptLocation);
        HasMany(x => x.Employees).Inverse().Cascade.All();
    }
}

public class EmployeeMapping : ClassMap<Employee>
{
    public EmployeeMapping()
    {
        Id(x => x.Id);
        Map(x => x.EmpName);
        Map(x => x.EmpAge);
        Map(x => x.DeptId);
        References(x => x.Dept).Cascade.None();
    }
}
公共部分类部门
{
公共虚拟系统.String DeptLocation{get;set;}
公共虚拟系统.String DeptName{get;set;}
public virtual System.Int32 Id{get;private set;}
公共虚拟IList雇员{get;set;}
}
公共部分类雇员
{
public virtual System.Int32 DeptId{get;set;}
public virtual System.Int32 EmpAge{get;set;}
公共虚拟系统。字符串EmpName{get;set;}
public virtual System.Int32 Id{get;private set;}
公共虚拟项目.Model.Dept部门{get;set;}
}
映射文件

public partial class Dept
{
    public virtual System.String DeptLocation { get; set; }
    public virtual System.String DeptName { get; set; }
    public virtual System.Int32 Id { get; private  set; }
    public virtual IList<Employee> Employees { get; set; }
}

public partial class Employee
{
    public virtual System.Int32 DeptId { get; set; }
    public virtual System.Int32 EmpAge { get; set; }
    public virtual System.String EmpName { get; set; }
    public virtual System.Int32 Id { get; private set; }
    public virtual Project.Model.Dept Dept { get; set; }
}
public class DeptMapping : ClassMap<Dept>   
{
    public DeptMapping()
    {
        Id(x => x.Id);
        Map(x => x.DeptName);
        Map(x => x.DeptLocation);
        HasMany(x => x.Employees).Inverse().Cascade.All();
    }
}

public class EmployeeMapping : ClassMap<Employee>
{
    public EmployeeMapping()
    {
        Id(x => x.Id);
        Map(x => x.EmpName);
        Map(x => x.EmpAge);
        Map(x => x.DeptId);
        References(x => x.Dept).Cascade.None();
    }
}
公共类部门映射:类映射
{
公共部门映射()
{
Id(x=>x.Id);
Map(x=>x.DeptName);
Map(x=>x.DeptLocation);
HasMany(x=>x.Employees).Inverse().Cascade.All();
}
}
公共类EmployeeMapping:ClassMap
{
公共雇员映射()
{
Id(x=>x.Id);
Map(x=>x.EmpName);
Map(x=>x.EmpAge);
Map(x=>x.DeptId);
引用(x=>x.Dept.Cascade.None();
}
}
我要添加的代码

        try
        {
            Dept dept = new Dept();
            dept.DeptLocation = "Austin";
            dept.DeptName = "Store";

            Employee emp = new Employee();
            emp.EmpName = "Ron";
            emp.EmpAge = 30;

            IList<Employee> empList = new List<Employee>();
            empList.Add(emp);
            dept.Employees = empList;
            emp.Dept = dept;

            IRepository<Dept> rDept = new Repository<Dept>();
            rDept.SaveOrUpdate(dept);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
试试看
{
Dept=新部门();
dept.DeptLocation=“奥斯汀”;
dept.DeptName=“商店”;
员工emp=新员工();
emp.EmpName=“Ron”;
emp.EmpAge=30;
IList empList=新列表();
雇主添加(emp);
部门员工=员工;
emp.Dept=部门;
IRepository rDept=新存储库();
rDept.保存或更新(部门);
}
捕获(例外情况除外)
{
控制台写入线(例如消息);
}
在这里,我得到了一个错误

InnerException={“无效列名'Dept_id'。”} Message=“无法插入:[Project.Model.Employee][SQL:插入到[Employee](EmpName、EmpAge、DeptId、DeptId)值(?、、?、?);选择范围标识()

问题是(正如错误消息告诉您的)您没有名为“Dept_id”的列。您的列名改为“DeptId”。fluent nhibernate的默认约定是名称应带有下划线。要解决此问题,可以更改数据库中列的名称,也可以覆盖映射文件中的约定,让它改用列名。这可以通过以下方式实现:

//EmployeeMapping
References(x => x.Dept).ForeignKey("DeptId").Cascade.None();

//DeptMapping
HasMany(x => x.Employees).KeyColumn("DeptId").Inverse() .Cascade.All();

Mattias的答案几乎正确,但ForeignKey用于模式生成。请尝试下面的映射。此外,您还使用CascadeAll映射了Employees集合。如果删除部门,这将删除员工记录,这可能是不可取的

public class DeptMapping : ClassMap<Dept>
    { 
        public DeptMapping() 
        {
            Id(x => x.Id); 
            Map(x => x.DeptName); 
            Map(x => x.DeptLocation); 
            HasMany(x => x.Employees).KeyColumn("DeptId").Inverse().Cascade.All(); 
        } 
    }

public class EmployeeMapping : ClassMap<Employee>
{ 
    public EmployeeMapping() 
    { 
        Id(x => x.Id); 
        Map(x => x.EmpName); 
        Map(x => x.EmpAge); 
        Map(x => x.DeptId); 
        References(x => x.Dept, "DeptId").Cascade.None(); 
   } 
}
公共类部门映射:类映射
{ 
公共部门映射()
{
Id(x=>x.Id);
Map(x=>x.DeptName);
Map(x=>x.DeptLocation);
HasMany(x=>x.Employees).KeyColumn(“DeptId”).Inverse().Cascade.All();
} 
}
公共类EmployeeMapping:ClassMap
{ 
公共雇员映射()
{ 
Id(x=>x.Id);
Map(x=>x.EmpName);
Map(x=>x.EmpAge);
Map(x=>x.DeptId);
引用(x=>x.Dept,“DeptId”).Cascade.None();
} 
}
调用该方法的代码

try
{
    Dept dept = new Dept();
    dept.DeptLocation = "Austin";
    dept.DeptName = "Store";

    Employee emp = new Employee();
    emp.EmpName = "Ron";
    emp.EmpAge = 30;


    dept.AddEmployees(emp); 


    IRepository<Dept> rDept = new Repository<Dept>();
    rDept.Add(dept);
}
试试看
{
Dept=新部门();
dept.DeptLocation=“奥斯汀”;
dept.DeptName=“商店”;
员工emp=新员工();
emp.EmpName=“Ron”;
emp.EmpAge=30;
员工部(emp);
IRepository rDept=新存储库();
rDept.Add(部门);
}

我做了您提到的更改。我仍然得到同样的错误。public DeptMapping(){Id(x=>x.Id);Map(x=>x.DeptName);Map(x=>x.DeptLocation);HasMany(x=>x.Employees)。KeyColumn(“DeptId”).Inverse().Cascade.All();}public EmployeeMapping(){Id(x=>x.Id);Map(x=>x.EmpName);Map(x=>x.EmpAge);Map(x=>x.DeptId);References(x=>x.Dept).ForeignKey(“DeptId”).Cascade.None();}Jamie,感谢您的更正,我能够将记录插入Dept表。但它并不是在Employee表中插入记录。看起来我调用SaveOrUpdate部分的编码有一些错误。我几乎做到了,但不是最后。行
dept.Employees=employist,更改集合引用。您需要通过
dept.Employees.add(emp)将员工添加到集合中。我将dept.Employees=empList替换为dept.Employees.Add(emp),它提供了对象引用而不是对象的set实例。这是正确的,因为EmployeeColleciton为空。该员工是IList集合,在向其添加项目之前需要先设置它。因此它将不起作用。第二件事,集合引用是如何更改的?您应该在Dept的构造函数中初始化集合:
Employees=new List()
。在回答第二个问题时,NHibernate为IList提供了自己的集合实现,因此当您分配
deptEmployees=employist
时,引用从NHibernate的列表更改为您的列表。哦,上帝!为什么很多人突然被称为“参考人”?我想因为浪费我的时间而责骂流利的Nhibernate作者。请查看此链接。它的建立非常重要。