1

SQL Azureでは、レプリケーションのためにすべてのテーブルにクラスター化インデックスが必要なため(http://blogs.msdn.com/b/sqlazure/archive/2010/05/12/10011257.aspxを参照)、次のMsSqlAzureDialectをMsSqlConfigurationに追加しました。

public class MsSqlAzureDialect : MsSql2008Dialect
{
    public override string PrimaryKeyString
    {
        get { return "primary key CLUSTERED"; }
    }
}

しかし、それは私が現在多対多のテーブルで抱えている問題を解決しません。現在、ロールを持つユーザーとユーザーを持つロールがある状況があります。したがって、ユーザーとロールの間には多対多の関係があり、NHibernateによって生成されたリンクテーブルがあります。したがって、私のUserAutomappingOverrideには、次のようなものがあります。

public class UserAutomappingOverride : IAutoMappingOverride<User>
{
    public void Override(AutoMapping<User> mapping)
    {
        mapping.HasManyToMany(x => x.Roles).Cascade.SaveUpdate();
    }
}

これにより、NHibernateはRoleToUserと呼ばれるリンクテーブルを作成します。ただし、このテーブルにはPKがないため、クラスター化インデックスはありません。これは、SQLAzureで使用するには無効なテーブル構成です。

私は次のように非流暢なNHibernateからのデータベースオブジェクトを使用しようとしました:

<?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コードを組み合わせようとする暗闇の中でのショットでした。ただし、「セキュリティ上の理由から、このXMLドキュメントではDTDが禁止されています...」というエラーが発生したため、機能しませんでした。

注:コードファーストデータベースの作成には、流暢なNHibernateを使用しています。そのため、実際にはエンティティとAutomappingOverridesを使用して、展開時にデータベースのスキーマを生成しています。

どんな助けでも大歓迎です。

4

4 に答える 4

1

私はAzureで動作するこのような構造を持っています

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]
于 2012-06-11T23:20:55.180 に答える
1

主キーを使用してマッピングテーブルを生成するには、およびIBagを使用できます。私の調査によると、Fluent NHibernateはまだこれをサポートしていませんが、Fluent NHibernateを使用して、クラスマッピングや自動マッピングとともにhbmファイルをマッピングし、FluentNHibernateでは直接サポートされていない機能を利用できます。

ユーザーをロールにマップする簡単な例を次に示します。

Program.cs

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

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

<?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

<?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>
于 2012-06-12T19:02:16.270 に答える
1

だから@DerekGreerの答えは素晴らしかった。しかし、私は、ハイブリッドなnhibernateと流暢なnhibernate環境が多すぎるという混乱を望んでいませんでした。

とにかくSQLAzureのリンクテーブルにクラスター化インデックスを追加するための小さなハックであるため、私がやったことは、クラスター化インデックスの追加専用のhbmファイルを追加することでした。このように、自動マッピングで多対多の関係がオブジェクトに流暢に追加されるときはいつでも、開発者は以下に示すようにファイルに手動で行を追加できます。これは実際には以前に見つけた答えに非常に近いですが、hbmファイルをロードする際に何が間違っているのかを知るために、流暢でないnhibernateについて十分に知りませんでした。だから、ここにあります:

ManyToManyClusteredIndexes.hbm.xml

<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>
于 2012-06-13T02:36:13.363 に答える
0

私はこのテーマについて長い間研究していましたが、流暢なnhibernateとnhibernateコードを変更したくなかったので、この回避策を作成することにしました。

私はすでにdb環境(ローカルまたはazure)を初期化するコンソールアプリを持っていました。流暢なnhibernate dbの作成が終わった後、ManyToManyテーブルを削除し、azureが期待するようにそれらを再作成しました。

drop table ProfileLikes
CREATE TABLE ProfileLikes(
    [ProfileID] [bigint] NOT NULL,
    [LikeID] [bigint] NOT NULL,
    PRIMARY KEY CLUSTERED 
(
    [ProfileID],[LikeID]  ASC
)
) 

ALTER TABLE ProfileLikes  WITH CHECK ADD  CONSTRAINT [FK6FB4BC1C85106EB3] FOREIGN KEY([LikeID])
REFERENCES [dbo].[Likes] ([Id])
ALTER TABLE ProfileLikes CHECK CONSTRAINT [FK6FB4BC1C85106EB3]

ALTER TABLE ProfileLikes  WITH CHECK ADD  CONSTRAINT [FK6FB4BC1CA12A6EC5] FOREIGN KEY([ProfileID])
REFERENCES Profiles ([Id])

ALTER TABLE ProfileLikes CHECK CONSTRAINT [FK6FB4BC1CA12A6EC5]

それが役に立てば幸い。アミール

于 2012-06-24T11:40:22.460 に答える