S#arp 架构中的一对一映射

发布于 2024-10-06 03:31:11 字数 1543 浏览 2 评论 0原文

我的头上有一股明显的电路烧毁的气味,所以请原谅我的无知。

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

我缺少什么?

There's a distinct smell of burned out circuits coming from my head, so forgive my ignorance.

I'm trying to setup a one-to-one relationship (well, let Automapper do it) in S#arp Architecture.

I have

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; }
    ...
}

And my db schema is

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,
    ...

When I run the unit test CanConfirmDatabaseMatchesMappings in MappingIntegrationTests I get the following error

NHibernate.ADOException : could not
execute query ...
System.Data.SqlClient.SqlException :
Invalid column name 'ProfileFk'.
Invalid column name 'BasketFk'.

and the sql it's trying to execute is

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

So it's looking for a ProfileFk and BasketFk field in the Users table.
I haven't setup any customer override mappings and as far as I can see I've followed the default conventions setup in S#.

The two other mappings for IList Orders and Roles seem to map fine. So I'm guessing that it've missed something for setting up a one-to-one relationship.

What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜心小果奶 2024-10-13 03:31:11

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

背景阅读:NHibernate 映射Fluent 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# 非常有用。

Got it. This is really an NHibernate problem to solve with Fluent NHibernate syntax, but it happens to be relevant for S#.

Background reading: NHibernate Mapping and Fluent NHibernate HasOne

What you do is override the mapping for User and give it two .HasOne mappings. Then set a unique reference to the user on the Profile and Basket class:

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
    }

As a side note, at the time of writing this, NHibernate 3 has just been released. There's a great book out called NHibernate 3.0 Cookbook which I've just bought and it looks extremely useful for working with S#.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文