Nhibernate Orchard CMS ISessionConfigurationEvents和1:N,N:N关系?

Nhibernate Orchard CMS ISessionConfigurationEvents和1:N,N:N关系?,nhibernate,fluent-nhibernate,many-to-many,orchardcms,one-to-many,Nhibernate,Fluent Nhibernate,Many To Many,Orchardcms,One To Many,我花了很多天的时间试图在OrchardCMS1.9.1中实现自定义ContentPart之间的关系,但没有成功。 互联网上散布着许多试图实现同样目标的人,他们也失败了;给我一个不可能的印象? 尽管最近我在:上读到一篇文章,给人的印象是,在Orchard内,所有使用流利的Nhibernate可能实现的事情都应该是可能的 因此,我实施了: public class DbMapping : ISessionConfigurationEvents { public void Created(Fl

我花了很多天的时间试图在OrchardCMS1.9.1中实现自定义ContentPart之间的关系,但没有成功。 互联网上散布着许多试图实现同样目标的人,他们也失败了;给我一个不可能的印象? 尽管最近我在:上读到一篇文章,给人的印象是,在Orchard内,所有使用流利的Nhibernate可能实现的事情都应该是可能的

因此,我实施了:

public class DbMapping : ISessionConfigurationEvents
{
    public void Created(FluentConfiguration cfg, AutoPersistenceModel defaultModel)
    {
        defaultModel.UseOverridesFromAssemblyOf<ProfilePartRecord>().Alterations(x => x.AddFromAssemblyOf<ProfileOverride>());
        defaultModel.UseOverridesFromAssemblyOf<LocationPartRecord>().Alterations(x => x.AddFromAssemblyOf<LocationOverride>());
    }

    public void Prepared(FluentConfiguration cfg) { }
    public void Building(Configuration cfg) { }
    public void Finished(Configuration cfg) { }
    public void ComputingHash(Hash hash) { }
}



public class LocationOverride : IAutoMappingOverride<LocationPartRecord>
{
    public void Override(AutoMapping<LocationPartRecord> mapping)
    {
        //[ Profile ] <--> [ Location ]
        //mapping.Id(x => x.Id, "LocationPartRecord_id"); //As it's not in the model due to being a contentPart, NH will throw an error because of such.
        mapping.Map(x => x.Type);
        mapping.Map(x => x.Name);
        mapping.References(x => x.ProfilePartRecord, "ProfilePartRecord_id");
    }
}


public class ProfileOverride : IAutoMappingOverride<ProfilePartRecord>
{
    public void Override(AutoMapping<ProfilePartRecord> mapping)
    {
        //[ Profile ] 0.1 <---> N [ Location ]
        //NEW
        mapping.HasMany(x => x.Locations)
            .Inverse()
            //.KeyColumn("ProfilePartRecord_id")
            .Cascade.All()
            .ForeignKeyCascadeOnDelete() 
            .ForeignKeyConstraintName("FK_Location__Profile"); 
    }
}
公共类DbMapping:ISessionConfigurationEvents
{
已创建公共void(FluentConfiguration cfg、AutoPersistenceModel defaultModel)
{
defaultModel.UseOverridesFromAssemblyOf().Changes(x=>x.AddFromAssemblyOf());
defaultModel.UseOverridesFromAssemblyOf().Changes(x=>x.AddFromAssemblyOf());
}
已准备公共无效(FluentConfiguration cfg){}
公共无效建筑(配置cfg){}
公共无效已完成(配置cfg){}
公共void计算哈希(哈希哈希){}
}
公共类LocationOverride:IAutoMappingOverride
{
公共无效替代(自动映射)
{
//[简介][地点]
//mapping.Id(x=>x.Id,“LocationPartRecord_Id”);//由于它是contentPart而不在模型中,因此NH将抛出一个错误。
Map.Map(x=>x.Type);
Map.Map(x=>x.Name);
引用(x=>x.ProfilePartRecord,“ProfilePartRecord_id”);
}
}
公共类ProfileOverride:IAutoMappingOverride
{
公共无效替代(自动映射)
{
//[配置文件]0.1 N[位置]
//新的
mapping.HasMany(x=>x.Locations)
.Inverse()
//.KeyColumn(“ProfilePartRecord\u id”)
.Cascade.All()
.ForeignKeyCascadeOnDelete()
.ForeignKeyConstraintName(“FK_位置__档案”);
}
}
型号:

public class ProfilePartRecord : ContentPartRecord
{
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }

    [CascadeAllDeleteOrphan]
    public virtual IList<LocationPartRecord> Locations { get; set; }
    public ProfilePartRecord()
    {
        Locations = new List<LocationPartRecord>();
    }
}


public class LocationPartRecord : ContentPartRecord
{
    public virtual string Type { get; set; }
    public virtual string Name { get; set; }

    //For HasMany
    [CascadeAllDeleteOrphan]
    public virtual ProfilePartRecord ProfilePartRecord { get; set; }
}
公共类ProfilePartRecord:ContentPartRecord
{
公共虚拟字符串FirstName{get;set;}
公共虚拟字符串LastName{get;set;}
[级联删除孤儿]
公共虚拟IList位置{get;set;}
公共档案部分记录()
{
位置=新列表();
}
}
公共类LocationPartRecord:ContentPartRecord
{
公共虚拟字符串类型{get;set;}
公共虚拟字符串名称{get;set;}
//对很多人来说
[级联删除孤儿]
公共虚拟档案PartRecord档案PartRecord{get;set;}
}
迁移:

        SchemaBuilder.CreateTable("ProfilePartRecord",
            table => table
                .ContentPartRecord()
                //PK: ProfilePartRecord_id
                .Column<string>("FirstName")
                .Column<string>("LastName")
                //System
                .Column<DateTime>("CreatedAt")
            );

        ContentDefinitionManager.AlterPartDefinition("ProfilePart",
            builder => builder.Attachable());

        ContentDefinitionManager.AlterTypeDefinition("Profile", t => t
            .WithPart(typeof(ProfilePart).Name)
            .WithPart("UserPart")
            );

        ContentDefinitionManager.AlterTypeDefinition("User", t => t
            .WithPart("ProfilePart")
            );



        SchemaBuilder.CreateTable("LocationPartRecord",
            table => table
                .ContentPartRecord()
                //PK: LocationPartRecord_id
                //FK:
                .Column<int>("ProfilePartRecord_id")
                .Column<string>("Type")
                .Column<string>("Name")
                //System
                .Column<DateTime>("CreatedAt")
            );

        ContentDefinitionManager.AlterPartDefinition("LocationPart",
            builder => builder.Attachable());

        ContentDefinitionManager.AlterTypeDefinition("Location", type => type
            .WithPart("CommonPart")
            .WithPart("LocationPart")
            .Creatable()
            .Listable());
schemabilder.CreateTable(“ProfilePartRecord”,
表=>表
.ContentPartRecord()
//PK:ProfilePartRecord\u id
.栏(“名字”)
.列(“姓氏”)
//系统
.列(“创建数据”)
);
ContentDefinitionManager.AlterPartDefinition(“ProfilePart”,
builder=>builder.Attachable());
ContentDefinitionManager.AlterTypeDefinition(“Profile”,t=>t
.WithPart(类型(ProfilePart).名称)
.WithPart(“用户部分”)
);
ContentDefinitionManager.AlterTypeDefinition(“用户”,t=>t
.WithPart(“ProfilePart”)
);
SchemaBuilder.CreateTable(“LocationPartRecord”,
表=>表
.ContentPartRecord()
//PK:LocationPartRecord\u id
//FK:
.列(“ProfilePartRecord\u id”)
.栏(“类型”)
.栏(“名称”)
//系统
.列(“创建数据”)
);
ContentDefinitionManager.AlterPartDefinition(“LocationPart”,
builder=>builder.Attachable());
ContentDefinitionManager.AlterTypeDefinition(“位置”,类型=>type
.带部分(“公共部分”)
.带零件(“位置零件”)
.createable()
.Listable());
但是,唉,我仍然无法在这两个实体之间建立关系。我可以通过迁移来实现这一点,但这是非常有限的——比如,我不能将关系设置为级联


有谁能解释一下这是否可能,如果可能,如何实现?谢谢

这可能不会让你一劳永逸,但我相信它会有所帮助。出于性能原因以及在数据库级别建立部件之间的关系,我所做的一件事是在迁移中使用“CreateForeignKey”和“CreateIndex”。下面是一个适合您的示例

// Add foreign key
SchemaBuilder.CreateForeignKey(
    "FK_LocationProfile",
    "LocationPartRecord", new[] { "ProfilePartRecord_id" },
    "ProfilePartRecord", new[] { "Id" });

// Add index
SchemaBuilder.AlterTable("LocationPartRecord",
    table => table
        .CreateIndex("IDX_ProfilePartRecord_Id", "ProfilePartRecord_Id")
    );
定义了这些关系后,我想知道这是否会以任何方式影响您正在进行的NHibernate工作


至于我们是如何实现我认为您正在努力实现的总体目标的,您可以在“LocationPart”处理程序中监视“ProfilePart”“Delete”事件,并在那里应用您自己的级联删除逻辑,以确保没有“LocationPart”遗留下来。

这可能无法实现全部目标,但我相信它会有所帮助。出于性能原因以及在数据库级别建立部件之间的关系,我所做的一件事是在迁移中使用“CreateForeignKey”和“CreateIndex”。下面是一个适合您的示例

// Add foreign key
SchemaBuilder.CreateForeignKey(
    "FK_LocationProfile",
    "LocationPartRecord", new[] { "ProfilePartRecord_id" },
    "ProfilePartRecord", new[] { "Id" });

// Add index
SchemaBuilder.AlterTable("LocationPartRecord",
    table => table
        .CreateIndex("IDX_ProfilePartRecord_Id", "ProfilePartRecord_Id")
    );
定义了这些关系后,我想知道这是否会以任何方式影响您正在进行的NHibernate工作


至于我们是如何实现我认为您正在努力实现的总体目标的,您可以在“LocationPart”处理程序中监视“ProfilePart”“Delete”事件,并在那里应用您自己的级联删除逻辑,以确保没有“LocationPart”遗留下来。

是的,以上就是我提到的“通过迁移”时所指的内容–但遗憾的是,这无助于事业;我认为这是徒劳的。因为这似乎是一个很大的工作,可能没有太多的“功能增益”。因此,我认为您的概念最终应该是我的方向……您是否有任何关于处理程序方面的示例代码?我已经说过了