【问题标题】:Orchard 1-N relationships (stops Content Item from updating)Orchard 1-N 关系(阻止内容项更新)
【发布时间】:2013-08-14 12:47:31
【问题描述】:

上下文:http://docs.orchardproject.net/Documentation/Creating-1-n-and-n-n-relations

这是我的Track Part的模型:

    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)
    );

一个 Content Item 附加 Track Part(形成 1-n 关系)并且 Track 记录有一个 Session 记录列表。

当您添加曲目时,问题就开始了。添加的第一个轨道被添加。第一次更新后(添加第一首曲目,还没有会话),我不再能够更新内容项上的任何内容。当我浏览代码时,我没有收到任何错误或任何异常(可能它们在 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_SessionInformationRecord SET TrackInformationRecord_id = null WHERE TrackInformationRecord_id = @p0

它从哪里得到列名 TrackInformationRecord_id?

任何帮助或建议将不胜感激。

【问题讨论】:

    标签: c# asp.net-mvc nhibernate orchardcms orchardcms-1.6


    【解决方案1】:

    是的,应该用斜杠命名,类型可以用记录类名代替int。您还应该将 Datetime 设置为可为空:Datetime?

    【讨论】:

      【解决方案2】:

      你能不能这样试试(为了简单起见,我省略了会话,但你可以复制相同的):

      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")
                 );
      

      【讨论】:

        【解决方案3】:
        public class TrackInformationRecord
        {
            public virtual IList<SessionInformationRecord> Sessions { get; set; }
        }
        

        ... 说父母TrackInformationRecord 有很多孩子Sessions。我猜 Orchard 在幕后使用 Fluent NHibernate 的自动映射来生成 NHibernate 映射。 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.
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多