2

数式を使用して ICollection 型のプロパティをマップしようとしていますが、マッピング nHibernate 内の型を決定するために使用するメソッドに関係なく、エラーがスローされます。

No parameterless constructor defined for this object.

ここにマッピングファイルがあります

this.Property(
  x => x.AllChildIds,
  m =>
    {
      m.Type<NHibernate.Type.ListType>();
      m.Access(Accessor.Field);
      m.Formula(@"(WITH [Child] ([Id], [ParentId])
           AS (SELECT [hs0].[Id],
                      [hs0].[ParentId]
               FROM   [Client].[dbo].[HierarchySet] [hs0] (NOLOCK)
               WHERE  [hs0].[ParentId] IN (SELECT [hs1].[Id]
                                     FROM   [Client].[dbo].[HierarchySet] [hs1] (NOLOCK)
                                     WHERE  [hs1].[Id] = Id /* @p0 */)
               UNION ALL


               SELECT [Children].[Id],
                      [Children].[ParentId]
               FROM   [Client].[dbo].[HierarchySet](NOLOCK) AS [Children]
                      JOIN [Child]
                        ON [Children].[ParentId] = [Child].[Id])


      SELECT [Child].[Id]
      FROM   [Child]
      )");
});

そして、ここに私のクラスがあります

private readonly ICollection<long> allChildIds;
public virtual IEnumerable<long> AllChildIds { get { return this.allChildIds; } }

マッピング ファイルのタイプを

m.Type<NHibernate.Type.GenericListType<NHibernate.Type.Int64Type>>();

その後、Could not determine type for: System.Collections.Generic.IEnumerableエラーが発生します

SQL が複雑であることは知っていますが、それは影響しないはずですか?

My NHibernate セッション構成の編集

private static Configuration ConfigureNHibernate()
{
  var configration = new Configuration();

  configration.SessionFactoryName("SessionFactoryName");
  configration.DataBaseIntegration(db =>
                                     {
                                       db.Dialect<MsSql2005Dialect>();
                                       db.Driver<SqlClientDriver>();

                                       db.IsolationLevel = IsolationLevel.ReadUncommitted;
                                       db.ConnectionStringName = "database";
                                       db.BatchSize = 20;
                                       db.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
                                     });

  if (ConfigurationManager.AppSettings["nhibernate-cache"] != null)
  {
    configration.Cache(
                       x =>
                         {
                           x.DefaultExpiration = 300;
                           x.UseMinimalPuts = true;
                           x.RegionsPrefix = "client-";
                           x.Provider<SysCacheProvider>();
                           x.UseQueryCache = true;
                         });
  }

  var mapper = new ModelMapper();
  mapper.AddMappings(typeof(MessageInMap).Assembly.GetTypes());
  var domainMapping = mapper.CompileMappingForAllExplicitlyAddedEntities();

  configration.AddMapping(domainMapping);

    configration.AddAuxiliaryDatabaseObject(new SimpleAuxiliaryDatabaseObject(@"
                            CREATE VIEW [Children]
                            AS 
                            WITH [Child] ([Id], [ParentId])
                            AS (
                                    SELECT 
                                            [hs0].[Id],
                                            [hs0].[ParentId]
                                    FROM   
                                            [isnapshot.Client].[dbo].[HierarchySet] (NOLOCK) AS [hs0]

                                    UNION ALL

                                    SELECT 
                                            [Children_].[Id],
                                            [Children_].[ParentId]
                                    FROM   
                                            [isnapshot.Client].[dbo].[HierarchySet] (NOLOCK) AS [Children_]
                                    JOIN [Child] ON [Children_].[ParentId] = [Child].[Id]
                            )
                            GO", "DROP VIEW [Children]"));

  return configration;
}
4

1 に答える 1

1

プロパティとしてではなく、コンポーネントのセット(バッグ、リストなど)としてマップする必要があります。次に、副選択を使用してフェッチします。

私の最初の仮定は、それを次のようにマッピングすることです

c.Set(m => m.ChildrenIds,
    x =>
        {
            x.Access(Accessor.Field);
            x.Key(k => k.Column("ParentId"));
            x.Subselect(@"WITH [Child] ([Id], [ParentId])
AS 
(
    SELECT 
        [hs0].[Id],
        [hs0].[ParentId]
    FROM   
        [HierarchySet] (NOLOCK) AS [hs0]

    UNION ALL

    SELECT 
        [Children].[Id],
        [Children].[ParentId]
    FROM   
        [HierarchySet] (NOLOCK) AS [Children]
    JOIN 
        [Child] ON [Children].[ParentId] = [Child].[Id]
)

SELECT *
FROM [Child]");
        },
    x => x.Element(e => e.Column("Id")));

ただし、WITH句が副選択内に含まれることを望まないため、機能しません。生成されたクエリ:

SELECT 
    childrenid0_.ParentId as ParentId0_, 
    childrenid0_.Id as Id0_ 
FROM ( WITH [Child] ([Id], [ParentId])
AS 
(
    SELECT 
        [hs0].[Id],
        [hs0].[ParentId]
    FROM   
        [HierarchySet] (NOLOCK) AS [hs0]

    UNION ALL

    SELECT 
        [Children].[Id],
        [Children].[ParentId]
    FROM   
        [HierarchySet] (NOLOCK) AS [Children]
    JOIN 
        [Child] ON [Children].[ParentId] = [Child].[Id]
)

SELECT *
FROM [Child] ) childrenid0_ 
WHERE childrenid0_.ParentId=@p0;@p0 = 2 [Type: Int32 (0)]

したがって、この場合の唯一の解決策は、ビューを作成し、それにマップすることです。

データベースオブジェクトを構成に追加します

configuration.AddAuxiliaryDatabaseObject(new SimpleAuxiliaryDatabaseObject(@"
    CREATE VIEW [Children]
    AS 
    WITH [Child] ([Id], [ParentId])
    AS (
        SELECT 
            [hs0].[Id],
            [hs0].[ParentId]
        FROM   
            [HierarchySet] (NOLOCK) AS [hs0]

        UNION ALL

        SELECT 
            [Children].[Id],
            [Children].[ParentId]
        FROM   
            [HierarchySet] (NOLOCK) AS [Children]
        JOIN [Child] ON [Children].[ParentId] = [Child].[Id]
    )

    SELECT *
    FROM [Child]", "DROP VIEW [Children]"));

SchemaExport /SchemaUpdate機能を使用してデータベーススキーマを作成/更新している場合-NHibernateはビューを作成します。SchemaExport / SchemaUpdate機能を使用していない場合は、ビューを手動で作成する必要があります。

CREATE VIEW [Children]
AS 
    WITH [Child] ([Id], [ParentId])
    AS (
        SELECT 
            [hs0].[Id],
            [hs0].[ParentId]
        FROM   
            [HierarchySet] (NOLOCK) AS [hs0]

        UNION ALL

        SELECT 
            [Children].[Id],
            [Children].[ParentId]
        FROM   
            [HierarchySet] (NOLOCK) AS [Children]
        JOIN [Child] ON [Children].[ParentId] = [Child].[Id]
    )

    SELECT *
    FROM   [Child]

マッピング:

c.Set(m => m.ChildrenIds,
    x =>
        {
            x.Access(Accessor.Field);
            x.Key(k => k.Column("ParentId"));
            x.Table("Children"); // or x.Subselect("select * from Children") 
        },
    x => x.Element(e => e.Column("Id")));
于 2013-03-20T23:38:54.150 に答える