如何做一个连贯NHibernate一对一的映射

如何做一个连贯NHibernate一对一的映射

本文介绍了如何做一个连贯NHibernate一对一的映射?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何做到这一点,我试图让一个一对一的映射。

 公共类设置
{
公共虚拟的Guid StudentId {搞定;组; }
公共虚拟DateFilters TaskFilterOption {搞定;组; }
公共虚拟字符串TimeZoneId {搞定;组; }
公共虚拟字符串TIMEZONENAME {搞定;组; }
公共虚拟的DateTime EndOfTerm {搞定;组; }
公共虚拟学生学生{搞定;组; }

}



//类映射

 公共SettingMap()
{
/// ID(Reveal.Member<设定>(StudentId))GeneratedBy。外国(StudentId);
// ID(X => x.StudentId);
地图(X => x.TaskFilterOption).DEFAULT(DateFilters.All.ToString())NvarcharWithMaxSize()Not.Nullable()。
地图(X => x.TimeZoneId)。.NvarcharWithMaxSize()Not.Nullable();
地图(X => x.TimeZoneName)。.NvarcharWithMaxSize()Not.Nullable();
图(X => x.EndOfTerm).DEFAULT(2011年5月21日)Not.Nullable();
HasOne(X => x.Student);
}



//学生的地图

 公共类StudentMap:ClassMap<的Student GT; 
{
公共StudentMap()
{
ID(X => x.StudentId);
HasOne(X => x.Setting).Cascade.All();

}
}

公共类学生
{
公共虚拟的Guid StudentId {搞定;私人集; }
公共虚拟设定设定{搞定;组; }
}

现在我尝试创建一个设置对象,并将其保存到每次数据库崩溃。

 设置设置=新设置
{
TimeZoneId = viewModel.SelectedTimeZone,
TIMEZONENAME = info.DisplayName,
EndOfTerm = DateTime.UtcNow.AddDays(-1),
=学生学生
};

INSERT语句冲突与外键约束FK_Settings_Students。冲突发生于数据库数据库,表dbo.Students,列StudentId。
语句已终止。
说明:当前Web请求的执行过程中发生未处理的异常。请检查堆栈跟踪有关该错误它起源于代码的更多信息和。

异常详细信息:System.Data.SqlClient.SqlException:INSERT语句冲突与外键约束FK_Settings_Students。冲突发生于数据库数据库,表dbo.Students,列StudentId。
语句已终止。



我缺少什么?



修改

 公共类StudentMap:ClassMap<的Student GT; 
{
公共StudentMap()
{
ID(X => x.StudentId).GeneratedBy.Guid();
HasOne(X => x.Setting)。.PropertyRef(学生)Cascade.All();
}
}

公共类SettingMap:ClassMap<设定>
{
公共SettingMap()
{
ID(X => x.StudentId).GeneratedBy.Guid();
地图(X => x.TaskFilterOption).DEFAULT(DateFilters.All.ToString())NvarcharWithMaxSize()Not.Nullable()。
地图(X => x.TimeZoneId)。.NvarcharWithMaxSize()Not.Nullable();
地图(X => x.TimeZoneName)。.NvarcharWithMaxSize()Not.Nullable();
图(X => x.EndOfTerm).DEFAULT(2011年5月21日)Not.Nullable();
引用(X => x.Student).Unique();
}
}

//尝试1

设置设置=新设置
{
TimeZoneId = viewModel.SelectedTimeZone,
TIMEZONENAME = info.DisplayName,
EndOfTerm = DateTime.UtcNow.AddDays(-1),
=学生学生
};
studentRepo.SaveSettings(设置);
studentRepo.Commit();

//尝试2

设置设置=新设置
{
TimeZoneId = viewModel.SelectedTimeZone,
TIMEZONENAME = info.DisplayName,
EndOfTerm = DateTime.UtcNow.AddDays(-1),
=学生学生
};

student.Setting =设定
studentRepo.CreateStudent(学生);
studentRepo.Commit();



我得到这些错误左右逢源

 无效此SqlParameterCollection以计数= 5索引5。说明:执行当前Web请求的执行过程中发生未处理的异常。请检查堆栈跟踪有关该错误它起源于代码的更多信息和。 

异常详细信息:System.IndexOutOfRangeException:无效的指数5此SqlParameterCollection以计数= 5。

源错误:

线76:使用(ITransaction事务= session.BeginTransaction()),77号线:{78行:器transaction.commit(); 79号线:} 80号线:}


解决方案

有两种基本方法如何映射在NH双向one-to-one关联。比方说,类看起来是这样的:

 公共类设置
{
公共虚拟的Guid标识{得到;组; }
公共虚拟学生学生{搞定;组; }
}

公共类学生
{
公共虚拟的Guid标识{搞定;组; }
公共虚拟设定设定{搞定;组; }
}



设置类是在协会主(聚合根)。这是相当不寻常,但是它依赖于问题域...



联合



 公共SettingMap()
{
ID(X => x.Id).GeneratedBy.Guid();
HasOne(X => x.Student).Cascade.All();
}

公共StudentMap()
{
ID(X => x.Id).GeneratedBy.Foreign(设置);
HasOne(X => x.Setting).Constrained();
}

和新设置的实例应该保存:

  VAR值=新设置(); 

setting.Student =新学生();
setting.Student.Name =student1;
setting.Student.Setting =设置;
setting.Name =设置1;

session.Save(设置);



外键关联



 公共SettingMap()
{
ID(X => x.Id).GeneratedBy.Guid();
引用(X => x.Student).Unique()Cascade.All()。
}

公共StudentMap()
{
ID(X => x.Id).GeneratedBy.Guid();
HasOne(X => x.Setting).Cascade.All()PropertyRef(学生)。
}

联合接近您的解决方案。主键协会应当你绝对相信,该协会将永远一对单只使用。需要注意的是AllDeleteOrphan级联不支持单对单的NH



编辑:欲了解更多详情,请参见:






How do I do this I am trying to make a one to one mapping.

public class Setting
{
    public virtual Guid StudentId { get; set; }
    public virtual DateFilters TaskFilterOption { get; set; }
    public virtual string TimeZoneId { get; set; }
    public virtual string TimeZoneName { get; set; }
    public virtual DateTime EndOfTerm { get; set; }
    public virtual Student Student { get; set; }

}

// class map

 public SettingMap()
        {
           /// Id(Reveal.Member<Setting>("StudentId")).GeneratedBy.Foreign("StudentId");
            //Id(x => x.StudentId);
            Map(x => x.TaskFilterOption).Default(DateFilters.All.ToString()).NvarcharWithMaxSize().Not.Nullable();
            Map(x => x.TimeZoneId).NvarcharWithMaxSize().Not.Nullable();
            Map(x => x.TimeZoneName).NvarcharWithMaxSize().Not.Nullable();
            Map(x => x.EndOfTerm).Default("5/21/2011").Not.Nullable();
            HasOne(x => x.Student);
        }

// student map

public class StudentMap : ClassMap<Student>
    {
        public StudentMap()
        {
            Id(x => x.StudentId);
            HasOne(x => x.Setting).Cascade.All();

        }
    }

  public class Student
    {
        public virtual Guid StudentId { get; private set; }
        public virtual Setting Setting { get; set; }
    }

Now every time I try to create a settings object and save it to the database it crashes.

   Setting setting = new Setting
                                          {
                                              TimeZoneId = viewModel.SelectedTimeZone,
                                              TimeZoneName = info.DisplayName,
                                              EndOfTerm =  DateTime.UtcNow.AddDays(-1),
                                              Student = student
                                          };

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Settings_Students". The conflict occurred in database "Database", table "dbo.Students", column 'StudentId'.
The statement has been terminated.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Data.SqlClient.SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Settings_Students". The conflict occurred in database "Database", table "dbo.Students", column 'StudentId'.
The statement has been terminated.

What am I missing?

Edit

public class StudentMap : ClassMap<Student>
{
    public StudentMap()
    {
        Id(x => x.StudentId).GeneratedBy.Guid();
        HasOne(x => x.Setting).PropertyRef("Student").Cascade.All();
    }
}

public class SettingMap : ClassMap<Setting>
{
    public SettingMap()
    {
        Id(x => x.StudentId).GeneratedBy.Guid();
        Map(x => x.TaskFilterOption).Default(DateFilters.All.ToString()).NvarcharWithMaxSize().Not.Nullable();
        Map(x => x.TimeZoneId).NvarcharWithMaxSize().Not.Nullable();
        Map(x => x.TimeZoneName).NvarcharWithMaxSize().Not.Nullable();
        Map(x => x.EndOfTerm).Default("5/21/2011").Not.Nullable();
        References(x => x.Student).Unique();
    }
}

// try 1

      Setting setting = new Setting
                                          {
                                              TimeZoneId = viewModel.SelectedTimeZone,
                                              TimeZoneName = info.DisplayName,
                                              EndOfTerm =  DateTime.UtcNow.AddDays(-1),
                                              Student = student
                                          };
     studentRepo.SaveSettings(setting);
     studentRepo.Commit();

// try 2

  Setting setting = new Setting
                                          {
                                              TimeZoneId = viewModel.SelectedTimeZone,
                                              TimeZoneName = info.DisplayName,
                                              EndOfTerm =  DateTime.UtcNow.AddDays(-1),
                                              Student = student
                                          };

student.Setting = setting
studentRepo.CreateStudent(student);
studentRepo.Commit();

I get these error for both ways

Invalid index 5 for this SqlParameterCollection with Count=5. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.IndexOutOfRangeException: Invalid index 5 for this SqlParameterCollection with Count=5.

Source Error:

Line 76:             using (ITransaction transaction = session.BeginTransaction()) Line 77:   { Line 78:                 transaction.Commit(); Line 79:         } Line 80:         }
解决方案

There are two basic ways how to map bidirectional one-to-one association in NH. Let's say the classes look like this:

public class Setting
{
    public virtual Guid Id { get; set; }
    public virtual Student Student { get; set; }
}

public class Student
{
    public virtual Guid Id { get; set; }
    public virtual Setting Setting { get; set; }
}

Setting class is a master in the association ("aggregate root"). It is quite unusual but it depends on problem domain...

Primary key association

public SettingMap()
{
    Id(x => x.Id).GeneratedBy.Guid();
    HasOne(x => x.Student).Cascade.All();
}

public StudentMap()
{
    Id(x => x.Id).GeneratedBy.Foreign("Setting");
    HasOne(x => x.Setting).Constrained();
}

and a new setting instance should be stored:

        var setting = new Setting();

        setting.Student = new Student();
        setting.Student.Name = "student1";
        setting.Student.Setting = setting;
        setting.Name = "setting1";

        session.Save(setting);

Foreign key association

public SettingMap()
{
    Id(x => x.Id).GeneratedBy.Guid();
    References(x => x.Student).Unique().Cascade.All();
}

public StudentMap()
{
    Id(x => x.Id).GeneratedBy.Guid();
    HasOne(x => x.Setting).Cascade.All().PropertyRef("Student");
}

Primary key association is close to your solution. Primary key association should be used only when you are absolutely sure that the association will be always one-to-one. Note that AllDeleteOrphan cascade is not supported for one-to-one in NH.

EDIT: For more details see:

http://fabiomaulo.blogspot.com/2010/03/conform-mapping-one-to-one.html

http://ayende.com/blog/3960/nhibernate-mapping-one-to-one

这篇关于如何做一个连贯NHibernate一对一的映射?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 20:28