2010-01-02 89 views
1

我一直在努力研究如何完成我的任务,实际上我甚至不确定我要进入的方向确实是一个不好的方面我的SQL表 - 但它是我能够想到的最简洁的。NHibernate映射 - 如何实现这个

我的问题描述起来相当简单。我有一个包含注释的表,其中有一个外键用于我的用户表(表示评论的作者)。为了正确支持匿名用户,我决定让这个外键可以为空 - 我还提供了3列用于指定姓名,电子邮件和网站,我希望在用户匿名的情况下存储相关信息 - 这些字段也是空。

因此,在短期

  • 如果用户登录,外键将包含用户名的ID,电子邮件地址和网站将为空。
  • 如果用户未登录,则外键将为空,名称,电子邮件和网站将包含有关用户的数据。

在我的域模型中,我希望将其映射到User类(属性Author,在我的评论类)。这个User类有一个名为“IsAnonymous”的属性 - 应该相应地设置它。

理想情况下,我会设置一些映射设置,根据外键的值映射此Author属性并正确指定这些属性。我已经有一个映射到我的用户类映射到用户表,但我不知道我会如何做到另一种方式。

我已经试过调查IUserType接口,但我不能完全理解我会如何在这个问题上不得不从2个不同的表中读取。

有没有一种合理的方式来做到这一点使用我当前的数据库结构 - 或者我应该考虑切换我的布局,如果是这样,到什么?

我从我的用户表中有一个简单的列切换指示一个匿名用户,但是当名称列设置为唯一键时,这开始给我提出问题。我希望注册用户拥有唯一的名称,但不是匿名用户。

谢谢你的时间。

编辑:阅读了这一点,决定也许一些ASCII /伪SQL图会派上用场

User 
----- 
UserId Guid PRIMARY KEY 
Name nvarchar(200) UNIQUE KEY NOT NULL 
Email nvarchar(200) NOT NULL 
Website nvarchar(200) NOT NULL 

Comment 
------- 
CommentId Guid PRIMARY KEY 
UserId GUID - FK-USER 
Name nvarchar(200) 
Email nvarchar(200) 
Website nvarchar(200) 

回答

1

我有类似的东西

//map this in NH 
public virtual User LoggedInCreator {get;set;} 
//Not mapped 
public virtual User CreatorInformation { 
    get { 
     if(LoggedInCreator != null) return LoggedInCreator; 
     return new User { 
       Name = AnonymousCommenterName, 
       Email = AnonymousCommenterEmail, 
       Website= AnonymousCommenterWebsite 
      }; 
    } 
} 
public void SetAnonymouscommenter(string name, string email, string website) 
{ 
    LoggedInCreator = null; 
    AnonymousCommenterName = name; 
    AnonymousCommenterEmail = email; 
    AnonymousCommenterWebsite = website; 
} 

但是,如果你想在更干净的方式,你会使用NHibernate的一个伟大的功能,它可以映射字段并映射属性,它们的值存储在字段中。
这里是一个更清洁的实现会是什么:

protected User _commenter; 
public virtual User Commenter 
{ 
    get { 
     if(_commenter != null) return _commenter; 
     return new User { 
       Name = AnonymousCommenterName, 
       Email = AnonymousCommenterEmail, 
       Website= AnonymousCommenterWebsite 
     }; 
    } 
    set { 
     bool isAnonymous = value.Id == 0; 
     _commenter = isAnonymous ? null : value; 
     AnonymousCommenterName = isAnonymous ? value.Name : null; 
     AnonymousCommenterEmail = isAnonymous ? value.Email : null; 
     AnonymousCommenterWebsite = isAnonymous ? value.Website : null; 
    } 
} 

你可以看到它们在本质虽然同样的想法,只是一些清理使用NHibernate特点。

+0

这可以工作!我目前正在研究一种方法,将我的评论类继承到我的NHibernate特定用例中,并仅在我的NHibernate代码中使用它。一旦我完成测试,看看它是否可以工作,我会返回。 – kastermester 2010-01-02 22:16:15

+0

谢谢你,你的建议让我以一种似乎有效的方式行事。在NH层中实现它有点代码,但另一方面,它使得它可以在其他地方工作,并且以我头脑中有意义的方式存储在数据库中:) – kastermester 2010-01-03 01:48:43