首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用SQL Azure实现多对多流畅的NHibernate映射

使用SQL Azure实现多对多流畅的NHibernate映射
EN

Stack Overflow用户
提问于 2012-06-12 06:24:59
回答 4查看 1.3K关注 0票数 1

由于SQL Azure需要为每个表创建聚集索引以进行复制(请参阅此处的http://blogs.msdn.com/b/sqlazure/archive/2010/05/12/10011257.aspx),因此我在MsSqlConfiguration中添加了以下MsSqlAzureDialect:

代码语言:javascript
复制
public class MsSqlAzureDialect : MsSql2008Dialect
{
    public override string PrimaryKeyString
    {
        get { return "primary key CLUSTERED"; }
    }
}

然而,这并不能解决我目前在多对多表中遇到的问题。我目前有一种情况,我有一个角色的用户,一个角色的用户。因此,用户和角色之间存在多对多关系,并由NHibernate生成链接表。所以在我的UserAutomappingOverride中,我有这样的东西:

代码语言:javascript
复制
public class UserAutomappingOverride : IAutoMappingOverride<User>
{
    public void Override(AutoMapping<User> mapping)
    {
        mapping.HasManyToMany(x => x.Roles).Cascade.SaveUpdate();
    }
}

这会导致NHibernate创建一个名为RoleToUser的链接表。但是,此表没有主键,因此没有聚集索引。这是在SQL Azure中使用的无效表配置。

我尝试使用非流畅NHibernate中的数据库对象,如下所示:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<nhibernate-mapping>
    <database-object>
        <create>create clustered index ix on RoleToUser(User_id, Role_id)</create>
        <drop>drop index RoleToUser.ix</drop>
    </database-object>
</nhibernate-mapping>

但是,尝试将那些不流利的NHibernate代码组合到一个流畅的配置中是徒劳的。然而,它并没有起作用,因为有一个错误说“出于安全原因,DTD在这个XML文档中是被禁止的……”

注意:我使用fluent NHibernate来创建代码优先的数据库。因此,我实际上是使用我的实体和AutomappingOverrides在部署时生成数据库的模式。

任何帮助都将不胜感激。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-06-13 10:36:13

所以@Derek Greer的回答很棒。然而,我不希望有太多的混合nhibernate和流畅的nhibernate环境。

因此,我最终所做的是添加一个专门用于添加聚类索引的hbm文件,因为这些都是为SQL Azure添加链接表的小技巧。这样,无论何时在自动映射中流畅地将多对多关系添加到对象,开发人员都可以手动向文件中添加一行,如下所示。这实际上与我之前找到的答案非常接近,但我只是对不流畅的nhibernate了解不够多,不知道我在加载hbm文件时做错了什么。所以,它是这样的:

ManyToManyClusteredIndexes.hbm.xml

代码语言:javascript
复制
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="Bookstore.Data.HbmMappings"
assembly="Bookstore.Data.HbmMappings">
    <database-object>
        <create>create clustered index ix on RoleToUser(User_id, Role_id)</create>
        <drop>drop index RoleToUser.ix</drop>
    </database-object>
    <database-object>
        <create>create clustered index ix on RoleToRoleGroup(RoleGroup_id, Role_id)</create>
        <drop>drop index RoleToRoleGroup.ix</drop>
    </database-object>
</hibernate-mapping>
票数 1
EN

Stack Overflow用户

发布于 2012-06-12 07:20:55

我有一个这样的结构,它在Azure中工作

代码语言:javascript
复制
CREATE TABLE [dbo].[ClientLabel](
    [ClientId] [bigint] NOT NULL,
    [LabelId] [bigint] NOT NULL,
 CONSTRAINT [PK_ClientLabel] PRIMARY KEY CLUSTERED 
(
    [ClientId] ASC,
    [LabelId] ASC
) WITH (..) ON [PRIMARY]
) ON [PRIMARY]
票数 1
EN

Stack Overflow用户

发布于 2012-06-13 03:02:16

要使用主键生成映射表,可以使用和IBag。根据我的研究,Fluent NHibernate还不支持这一点,但是您可以使用Fluent NHibernate来映射hbm文件以及您的类映射和/或自动映射,以便获得Fluent NHibernate不直接支持的特性。

下面是一个将用户映射到角色的快速示例:

Program.cs

代码语言:javascript
复制
class Program
{
    static void Main(string[] args)
    {
        DatabaseContextFactory.CreateSchema();

        var user = new User();
        user.Roles = new List<Role>();
        var role = new Role();
        user.Roles.Add(role);

        ISessionFactory sessionFactory = DatabaseContextFactory.CreateSessionFactory();

        using (ISession session = sessionFactory.OpenSession())
        {
            using (ITransaction transaction = session.BeginTransaction())
            {
                session.SaveOrUpdate(role);
                session.SaveOrUpdate(user);
                transaction.Commit();
            }
        }
    }
}

DatabaseContextFactory.cs

代码语言:javascript
复制
public static class DatabaseContextFactory
{
    static ISessionFactory _sessionFactory;
    static Configuration _configuration;

    public static ISessionFactory CreateSessionFactory()
    {
        if (_sessionFactory == null)
        {
            _sessionFactory = Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2008.ConnectionString(cs => cs.FromConnectionStringWithKey("SurrogateExample")))
                .ExposeConfiguration(c => _configuration = c)
                .Mappings(cfg => cfg.HbmMappings.AddFromAssemblyOf<Program>())
                .BuildSessionFactory();
        }

        return _sessionFactory;
    }

    public static void CreateSchema()
    {
        CreateSessionFactory();
        new SchemaExport(_configuration).Execute(false, true, false);
    }
}

User.hbm.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                                     assembly="SurrogateManyToManyExample"
                   namespace="SurrogateManyToManyExample.Entities">
    <class name="User" table="[User]">
        <id name="Id">
            <generator class="guid.comb" />
        </id>

        <idbag name="Roles" table="UserInRole" lazy="true">
            <collection-id column="Id" type="Guid">
                <generator class="guid.comb" />
            </collection-id>
            <key column="UserId" />
            <many-to-many column="RoleId" class="Role" fetch="join" />
        </idbag>
    </class>
</hibernate-mapping>

Role.hbm.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                                     assembly="SurrogateManyToManyExample"
                   namespace="SurrogateManyToManyExample.Entities">
    <class name="Role" table="[Role]">
        <id name="Id">
            <generator class="guid.comb" />
        </id>       
    </class>
</hibernate-mapping>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10988331

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档