Orchard 1-N关系(停止更新内容项)
本文关键字:更新 新内容 1-N 关系 Orchard | 更新日期: 2023-09-27 18:27:42
上下文:http://docs.orchardproject.net/Documentation/Creating-1-n-and-n-n-relations
这是我的轨道部分的模型:
public class TrackPartRecord : ContentPartRecord
{
public virtual IList<TrackInformationRecord> Tracks { get; set; }
}
public class TrackPart : ContentPart<TrackPartRecord>
{
public IList<TrackInformationRecord> Tracks
{
get { return Record.Tracks; }
}
}
public class TrackInformationRecord
{
public virtual int Id { get; set; }
public virtual int TrackPartId { get; set; }
public virtual string Title { get; set; }
public virtual string Description { get; set; }
public virtual bool IsDeleted { get; set; }
public virtual IList<SessionInformationRecord> Sessions { get; set; }
}
public class SessionInformationRecord
{
public virtual int Id { get; set; }
public virtual int TrackId { get; set; }
public virtual string Title { get; set; }
public virtual string Description { get; set; }
public virtual DateTime Timeslot { get; set; }
public virtual bool HasEvaluation { get; set; }
public virtual bool IsDeleted { get; set; }
}
下面是我的迁移,用于创建3个表(2个信息记录和1个部分记录):
// Creating table TrackInformationRecord
SchemaBuilder.CreateTable("TrackInformationRecord", table => table
.Column("Id", DbType.Int32, column => column.PrimaryKey().Identity())
.Column("TrackPartId", DbType.Int32)
.Column("Title", DbType.String)
.Column("Description", DbType.String)
.Column("IsDeleted", DbType.Boolean)
);
// Creating table TrackPartRecord
SchemaBuilder.CreateTable("TrackPartRecord", table => table
.ContentPartRecord()
);
ContentDefinitionManager.AlterPartDefinition("TrackPart", builder => builder.Attachable());
// Creating table SessionInformationRecord
SchemaBuilder.CreateTable("SessionInformationRecord", table => table
.Column("Id", DbType.Int32, column => column.PrimaryKey().Identity())
.Column("TrackId", DbType.Int32)
.Column("Title", DbType.String)
.Column("Description", DbType.String)
.Column("Timeslot", DbType.DateTime)
.Column("HasEvaluation", DbType.Boolean)
.Column("IsDeleted", DbType.Boolean)
);
"内容项"附加"跟踪部分"(形成1-n关系),"跟踪记录"具有会话记录列表。
添加轨迹时,问题就开始了。添加的第一个轨迹即被添加。在第一次更新(添加了第一首曲目,还没有会话)之后,我无法再更新内容项上的任何内容。当我浏览代码时,我没有遇到任何错误或异常(也许它们在Orchard中埋得太深了,没有抛出任何明显的东西)。
当我直接转到数据库并删除与内容项相关的跟踪记录时,我可以再次更新所有内容。
我检查了日志,发现了这个:
2013-08-14 14:15:00,882 [30] NHibernate.AdoNet.AbstractBatcher - Could not execute command: UPDATE Ignite_EventsAgenda_SessionInformationRecord SET TrackInformationRecord_id = null WHERE TrackInformationRecord_id = @p0
System.Data.SqlServerCe.SqlCeException (0x80004005): The column name is not valid. [ Node name (if any) = ,Column name = TrackInformationRecord_id ]
at System.Data.SqlServerCe.SqlCeCommand.ProcessResults(Int32 hr)
at System.Data.SqlServerCe.SqlCeCommand.CompileQueryPlan()
at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommand(CommandBehavior behavior, String method, ResultSetOptions options)
at System.Data.SqlServerCe.SqlCeCommand.ExecuteNonQuery()
at NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd)
2013-08-14 14:15:00,888 [30] NHibernate.Util.ADOExceptionReporter - System.Data.SqlServerCe.SqlCeException (0x80004005): The column name is not valid. [ Node name (if any) = ,Column name = TrackInformationRecord_id ]
at System.Data.SqlServerCe.SqlCeCommand.ProcessResults(Int32 hr)
at System.Data.SqlServerCe.SqlCeCommand.CompileQueryPlan()
at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommand(CommandBehavior behavior, String method, ResultSetOptions options)
at System.Data.SqlServerCe.SqlCeCommand.ExecuteNonQuery()
at NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd)
at NHibernate.Persister.Collection.AbstractCollectionPersister.Remove(Object id, ISessionImplementor session)
2013-08-14 14:15:00,891 [30] NHibernate.Util.ADOExceptionReporter - The column name is not valid. [ Node name (if any) = ,Column name = TrackInformationRecord_id ]
2013-08-14 14:15:00,894 [30] NHibernate.Event.Default.AbstractFlushingEventListener - Could not synchronize database state with session
NHibernate.Exceptions.GenericADOException: could not delete collection: [Ignite.EventsAgenda.Models.TrackInformationRecord.Sessions#1][SQL: UPDATE Ignite_EventsAgenda_SessionInformationRecord SET TrackInformationRecord_id = null WHERE TrackInformationRecord_id = @p0] ---> System.Data.SqlServerCe.SqlCeException: The column name is not valid. [ Node name (if any) = ,Column name = TrackInformationRecord_id ]
首先,我不知道为什么我会遇到"列名无效"的问题。
其次,我没有得到这行:UPDATE Ignite_EventsAgenda_SessionInformation Record SET TrackInformationRecord_id=null WHERE TrackInformationRecords_id=@p0
它从哪里获得列名TrackInformationRecord_id?
如有任何帮助或建议,我们将不胜感激。
是的,应该用斜线命名,类型可以用记录类名而不是int。您还应该将Datetime设置为nullable:Datetime?
你能这样试试吗(为了简单起见,我省略了会话,但你可以复制相同的):
public class TrackPartRecord : ContentPartRecord
{
public virtual IList<TrackInformationRecord> Tracks { get; set; }
}
public class TrackInformationRecord
{
// Own properties
public virtual int Id { get; set; }
public virtual string Title { get; set; }
public virtual string Description { get; set; }
public virtual bool IsDeleted { get; set; }
// Relations properties
public virtual TrackPartRecord TrackPartRecord { get; set; }
}
在迁移中:
SchemaBuilder.CreateTable("TrackPartRecord", t => t
.ContentPartRecord()
);
SchemaBuilder.CreateTable("TrackInformationRecord", t => t
.Column<int>("Id", column => column.PrimaryKey().NotNull())
.Column<int>("TrackPartRecord_Id")
.Column<string>("Title", c => c.WithLength(50).NotNull())
.Column<string>("Description", c => c.NotNull())
.Column<bool>("IsDeleted")
);
public class TrackInformationRecord
{
public virtual IList<SessionInformationRecord> Sessions { get; set; }
}
表示父CCD_ 1具有许多子CCD_。我猜Orchard在封面下使用Fluent NHibernate的自动映射来生成NHibernat映射。FluentNH一对多关系的默认列名是{classNameOfParent}_id
。因此产生了TrackInformationRecord_id
,也因此产生了错误——您从未创建过具有该名称的列。
我不熟悉Orchard,所以我不知道它是否提供了一种自定义这种行为的方法。FluentNH提供了一种方法(https://github.com/jagregory/fluent-nhibernate/wiki/Auto-mapping#overrides),但Orchard是否向您公开了该功能,我不知道。如果你找到了一个放置映射覆盖的地方,这样的东西应该可以工作:
public class TrackInformationRecordOverride
: IAutoMappingOverride<TrackInformationRecord>
{
public void Override(AutoMapping<TrackInformationRecord> mapping)
{
mapping.HasMany(x => x.Sessions)
.KeyColumn("TrackId"); // ... assuming TrackId is the column you wanted.
}
}