0

nHibernate に問題があります。エンティティが基本エンティティから継承する場合、この子エンティティは別のエンティティから参照できません。


次のように、データベースに継承階層があります。

  • VideoFeedありますVisualFeed
  • VideoFeed多くを持っていますPlaylistAssignment

これが(言い換えられた)SQL定義です

create table VisualFeed
(
    id BIGINT NOT NULL  -- Primary key
)

create table VideoFeed
(
   id BIGINT NOT NULL   -- Primary key, foriegn key references VisualFeed
)

create table PlaylistAssignment
(
   id BIGINT NOT NULL,   -- Primary key
   VideoFeed_Id BIGINT NOT NULL   -- Foreign key to VideoFeed
)

そして、クラス定義

public class VisualFeed 
{
    public virtual long? Id { get; set; }
}

public class VideoFeed : VisualFeed
{
    public virtual ISet<PlaylistAssignment> PlaylistAssignments { get; set; }
}

public class PlaylistAssignment
{
    public virtual long? Id { get; set; }
    public virtual VideoFeed VideoFeed { get; set; }
}

VisualFeed(親クラス)のマッピング コードは次のとおりです。

public static void Map(ModelMapper mapper)
{
mapper.Class<DATMedia.CMS.EntityLibrary.Entities.VisualFeed>(
        classMapper =>
        {
            classMapper.Table("cms_VisualFeed");
            classMapper.Id(
                            visualFeed => visualFeed.Id,
                            idMapper =>
                            {
                                idMapper.Column("Id");
                                idMapper.Generator(Generators.HighLow,
                                                    generatorMapper =>
                                                    {
                                                        generatorMapper.Params(

                                                            new
                                                            {
                                                                max_lo = 256,
                                                                column = "NextHi",
                                                                where = "TableName='VisualFeed'"
                                                            }
                                                        );
                                                    }
                                );
                            }
            );
    });
}

のマッピング コードは次のVideoFeedとおりです。

public static void Map(ModelMapper mapper)
{
    mapper.JoinedSubclass<DATMedia.CMS.EntityLibrary.Entities.VideoFeed>(
            joinedSubClassMapper =>
            {
                joinedSubClassMapper.Table("cms_VideoFeed");
                joinedSubClassMapper.Key(keyMapper =>
                    {
                        keyMapper.Column("Id");
                    }
                );


                joinedSubClassMapper.Set(
                    playerGroup => playerGroup.PlaylistAssignments,
                    setPropertiesMapper =>
                    {
                        setPropertiesMapper.Key(
                                keyMapper =>
                                {
                                    keyMapper.Column("VideoFeed_Id");
                                    keyMapper.PropertyRef(videoFeed => videoFeed.Id);
                                }
                            );
                        setPropertiesMapper.Cascade(Cascade.All | Cascade.DeleteOrphans);
                        setPropertiesMapper.Inverse(true);
                        setPropertiesMapper.OrderBy(playlistAssignment => playlistAssignment.AssignmentRank);
                    },
                    collectionElementRelation =>
                    {
                        collectionElementRelation.OneToMany();
                    }
                );    
            }
            );
}

「PlaylistAssignment」のマッピング コードは次のとおりです。

public static void Map(ModelMapper mapper)
{

    mapper.Class<DATMedia.CMS.EntityLibrary.Entities.PlaylistAssignment>(
            classMapper =>
            {
                classMapper.Table("cms_PlaylistAssignment");
                classMapper.Id(
                    playlistAssignment => playlistAssignment.Id,
                    idMapper =>
                    {
                        idMapper.Generator(Generators.Identity);
                    }

                    );

                classMapper.ManyToOne(
                        pa => pa.VideoFeed,
                        manyToOneMapper =>
                        {
                            manyToOneMapper.Column("VideoFeed_Id");
                            manyToOneMapper.Lazy(LazyRelation.Proxy);
                        }
                    );
           });
 };

を呼び出すときに例外がスローされModelMapper.CompileMappingForAllExplicitlyAddedEntitiesます。

例外は、ファイルKeyMapper.csの nHibernate コード内でスローされます。

public void PropertyRef(MemberInfo property)
{
   if (property == null)
   {
       mapping.propertyref = null;
       return;
   }
   if (!ownerEntityType.Equals(property.DeclaringType) && !ownerEntityType.Equals(property.ReflectedType))
   {
    throw new ArgumentOutOfRangeException("property", "Can't reference a property of another entity.");
   }
   mapping.propertyref = property.Name;
}

ownerEntityTypeReflectedTypeは「VideoFeed」に等しく、とは両方ともDeclaringType「VisualFeed」(親クラス名) に等しくなります。これはすべて正しいですが、ArgumentOutOfRangeExceptionがスローされます。


誰でも回避策を考えることができますか?


後で編集この問題は、への明示的な参照呼び出しが原因でしたsetPropertiesMapper。実際には、私が質問から省略した別の子クラスにありました(問題を単純化するための誤った試みで)。

実際の原因は、以下の「cms_VisualFeedAssignment」へのマッピングにあります。

        mapper.Class<DATMedia.CMS.EntityLibrary.Entities.VisualFeed>(
                classMapper =>
                {
                    classMapper.Table("cms_VisualFeed");
                    classMapper.Id(
                                    visualFeed => visualFeed.Id,
                                    idMapper =>
                                    {
                                        idMapper.Column("Id");
                                        idMapper.Generator(Generators.HighLow,
                                                            generatorMapper =>
                                                            {
                                                                generatorMapper.Params(

                                                                    new
                                                                    {
                                                                        max_lo = 256,
                                                                        column = "NextHi",
                                                                        where = "TableName='VisualFeed'"
                                                                    }
                                                                );
                                                            }
                                        );
                                    }
                    );
                 classMapper.Set<DATMedia.CMS.EntityLibrary.Entities.VisualFeedAssignment>(
                                    visualFeed => visualFeed.Assignments,
                                    bagPropertiesMapper =>
                                    {
                                        bagPropertiesMapper.Inverse(true);
                                        bagPropertiesMapper.Lazy(CollectionLazy.Lazy);
                                        bagPropertiesMapper.Key(
                                            keyMapper =>
                                            {
                                                keyMapper.Column("VisualFeed_Id");
                                                //keyMapper.PropertyRef<long?>(visualFeed => visualFeed.Id);
                                            }
                                        );
                                        bagPropertiesMapper.Table("cms_VisualFeedAssignment");
                                    },
                                    collectionElementRelation =>
                                    {
                                        collectionElementRelation.OneToMany();
                                    }
                                );
                        }
                    );
            }

呼び出しをコメントアウトするPropertyRefと、うまくいきました。

4

1 に答える 1

1

この行は必要ありません:

keyMapper.PropertyRef(videoFeed => videoFeed.Id);

VideoFeed.Id自動的に参照されます。その行を削除してみてください、それはうまくいくはずです。

于 2013-01-07T03:54:12.980 に答える