0

有一种明显的烧坏电路的气味从我的头上冒出来,所以请原谅我的无知。

我正在尝试在 S#arp Architecture 中建立一对一的关系(好吧,让 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 的另外两个映射似乎映射得很好。所以我猜它错过了建立一对一关系的一些东西。

我错过了什么?

4

1 回答 1

0

知道了。这确实是一个使用 Fluent NHibernate 语法解决的 NHibernate 问题,但它恰好与 S# 相关。

背景阅读:NHibernate MappingFluent NHibernate HasOne

您所做的是覆盖 User 的映射并为其提供两个 .HasOne 映射。然后在 Profile 和 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# 非常有用。

于 2010-12-07T14:45:31.427 回答