我的脑袋里传来一股明显的烧焦气味,请原谅我的无知。
我正试图在S#arp架构中建立一对一的关系(好吧,让Automapper这样做)。
我有
public class User : Entity
{
public virtual Profile Profile { get; set; }
public virtual Basket Basket { get; set; }
public virtual IList<Order> Orders { get; set; }
public virtual IList<Role> Roles { get; set; }
...
}
public class Basket : Entity
{
public virtual User User { get; set; }
...
}
public class Profile : Entity
{
public virtual User User { get; set; }
...
}
我的数据库架构是
CREATE TABLE [dbo].[Users](
[Id] [int] IDENTITY(1,1) NOT NULL,
...
CREATE TABLE [dbo].[Profiles](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserFk] [int] NULL,
...
CREATE TABLE [dbo].[Baskets](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserFk] [int] NULL,
...
当我在MappingIntegrationTests中运行单元测试CanConfirmDatabaseMatchesMappings时,我收到以下错误
NHibernate.ADOException:不能 执行查询... System.Data.SqlClient.SqlException: 列名称“ProfileFk”无效。 列名称'BasketFk'无效。
和它试图执行的sql是
SELECT TOP 0
this_.Id AS Id6_1_ ,
..
user2_.ProfileFk AS ProfileFk9_0_ ,
user2_.BasketFk AS BasketFk9_0_
FROM
Profiles this_
LEFT OUTER JOIN Users user2_
ON this_.UserFk = user2_.Id
所以它正在寻找Users表中的ProfileFk和BasketFk字段。 我没有设置任何客户覆盖映射,据我所知,我已遵循S#中的默认约定设置。
IList Orders和Roles的另外两个映射似乎映射得很好。所以我猜它已经错过了建立一对一关系的东西。
我错过了什么?
答案 0 :(得分:0)
知道了。这实际上是一个用Fluent NHibernate语法解决的NHibernate问题,但它恰好与S#有关。
背景阅读:NHibernate Mapping 和Fluent NHibernate HasOne
您所做的是覆盖User的映射,并为其提供两个.HasOne映射。然后在Profile and Basket类中为用户设置唯一引用:
public class UserMap : IAutoMappingOverride<User>
{
#region Implementation of IAutoMappingOverride<User>
/// <summary>
/// Alter the automapping for this type
/// </summary>
/// <param name="mapping">Automapping</param>
public void Override(AutoMapping<User> mapping)
{
mapping.HasOne(u => u.Profile);
mapping.HasOne(u => u.Basket);
}
#endregion
}
public class ProfileMap : IAutoMappingOverride<Profile>
{
#region Implementation of IAutoMappingOverride<Profile>
/// <summary>
/// Alter the automapping for this type
/// </summary>
/// <param name="mapping">Automapping</param>
public void Override(AutoMapping<Profile> mapping)
{
mapping.References(p => p.User).Unique().Column("UserFk");
}
#endregion
}
public class BasketMap : IAutoMappingOverride<Basket>
{
#region Implementation of IAutoMappingOverride<Basket>
/// <summary>
/// Alter the automapping for this type
/// </summary>
/// <param name="mapping">Automapping</param>
public void Override(AutoMapping<Basket> mapping)
{
mapping.References(b => b.User).Unique().Column("UserFk");
}
#endregion
}
作为旁注,在撰写本文时,NHibernate 3刚刚发布。我刚刚买了一本名为NHibernate 3.0 Cookbook的好书,它对于使用S#非常有用。