Orchardcms Orchard CMS-迁移后未更新新属性

Orchardcms Orchard CMS-迁移后未更新新属性,orchardcms,Orchardcms,我正在编写一个自定义模块,使用注入的IRepository直接从Orchard DB检索和推送数据 在我需要更新内容部分之前,这一切都很正常。我在migrations类中添加了一个更新,该更新将通过(使用默认值更新的DB schema)运行,但是我无法通过IRepository更新任何新值。我必须进入NHibernate.I会话以刷新更改 这一切都适用于新创建的配方,只有当我改变一个部分。以下是关键代码片段: public class TranslationsPartRecord : Conte

我正在编写一个自定义模块,使用注入的IRepository直接从Orchard DB检索和推送数据

在我需要更新内容部分之前,这一切都很正常。我在migrations类中添加了一个更新,该更新将通过(使用默认值更新的DB schema)运行,但是我无法通过IRepository更新任何新值。我必须进入NHibernate.I会话以刷新更改

这一切都适用于新创建的配方,只有当我改变一个部分。以下是关键代码片段:

public class TranslationsPartRecord : ContentPartRecord
{
    internal const string DefaultProductName = "Product";

    public TranslationsPartRecord()
    {
        ProductName = DefaultProductName;
    }

    public virtual string ProductName { get; set; }
}

public class TranslationsPart : ContentPart<TranslationsPartRecord>
{
    public string ProductName
    {
        get { return Record.ProductName; }
        set { Record.ProductName = value; }
    }
}

public class TranslationsHandler : ContentHandler
{
    public TranslationsHandler(IRepository<TranslationsPartRecord> repository)
    {
        Filters.Add(StorageFilter.For(repository));
    }
}

public class Migrations : DataMigrationImpl
{
    public int Create()
    {
        SchemaBuilder.CreateTable("TranslationsPartRecord", table => table
            .Column<int>("Id", column => column.PrimaryKey().Identity())
            .Column("ProductName", DbType.String, column => column.NotNull().WithDefault(TranslationsPartRecord.DefaultProductName))
        );

        return 1;
    }

    public int UpdateFrom1()
    {
        SchemaBuilder.AlterTable("TranslationsPartRecord", table => table.AddColumn("ProductDescription", DbType.String, column => column.NotNull().WithDefault(TranslationsPartRecord.DefaultProductDescription)));

        return 2;
    }
}
公共类TranslationPartRecord:ContentPartRecord
{
内部常量字符串DefaultProductName=“产品”;
公共TranslationPartRecord()
{
ProductName=DefaultProductName;
}
公共虚拟字符串ProductName{get;set;}
}
公共类TranslationPart:ContentPart
{
公共字符串产品名称
{
获取{return Record.ProductName;}
设置{Record.ProductName=value;}
}
}
公共类TranslationHandler:ContentHandler
{
公共TranslationHandler(IRepository存储库)
{
Filters.Add(StorageFilter.For(repository));
}
}
公共类迁移:DataMigrationImpl
{
公共int创建()
{
CreateTable(“translationPartRecord”,table=>table
.Column(“Id”,Column=>Column.PrimaryKey().Identity())
.Column(“ProductName”,DbType.String,Column=>Column.NotNull().WithDefault(translationPartRecord.DefaultProductName))
);
返回1;
}
public int UpdateFrom1()
{
SchemaBuilder.AlterTable(“TranslationPartRecord”,table=>table.AddColumn(“ProductDescription”,DbType.String,column=>column.NotNull().WithDefault(TranslationPartRecord.DefaultProductDescription)));
返回2;
}
}
在本例中,当我添加第二个属性“ProductDescription”时,更新运行后,列将显示在数据库中,但我无法更新它们,直到我重新创建Orchard配方(blat App_数据并重新启动)

以下是我尝试更新的方式:

// ctor
    public AdminController(IRepository<TranslationsPartRecord> translationsRepository)
    {
        _translationsRepository = translationsRepository;
    }

[HttpPost]
    public ActionResult Translations(TranslationsViewModel translationsViewModel)
    {
        var translations = _translationsRepository.Table.SingleOrDefault();
        translations.ProductName = translationsViewModel.ProductName;
        translations.ProductDescription = translationsViewModel.ProductDescription;

        _translationsRepository.Update(translations);
        _translationsRepository.Flush();
    }
//ctor
公共AdminController(IRepository translationsRepository)
{
_translationsRepository=translationsRepository;
}
[HttpPost]
公共行动结果翻译(翻译视图模型翻译视图模型)
{
var translations=_translationsRepository.Table.SingleOrDefault();
translations.ProductName=TranslationViewModel.ProductName;
translations.ProductDescription=TranslationViewModel.ProductDescription;
_translationsRepository.Update(翻译);
_translationsRepository.Flush();
}
这是NHibernate的“修复”:

var session=\u sessionLocator.For(typeof(translationpartrecord));
var translations=_translationsRepository.Table.SingleOrDefault();
//是翻译。Id总是1吗?
var dbTranslations=session.Get(translations.Id);
dbTranslations.ProductName=TranslationViewModel.ProductName;
dbTranslations.ProductDescription=TranslationViewModel.ProductDescription;
更新(数据库翻译);
session.Flush();
这看起来有点笨拙

干杯

ps我还在运行Orchard 1.3.9


pps经过更多的测试,NHibernate修复程序现在已经停止工作,所以我最初的发现可能是在转移视线。在更新/检索时,内容部分的新属性似乎被NHibernate完全忽略了——就好像对象定义被缓存在某个地方……

如果映射没有被更新,这很奇怪。您可以尝试通过删除app_data文件夹中的mappings.bin并重新启动应用程序来强制执行此操作。Orchard应重新创建nhibernate映射并另存为mappings.bin

我遇到了同样的问题,我能找到的唯一解决方法是删除mappings.bin(我不需要禁用和重新启用模块)。事实上,这就是我从Bertrand那里得到的答案,当我问为什么会发生这种情况时


我已将此作为问题记录在。如果你能投票支持这一点,那么我们可能会更快地看到它。

这似乎是一个类似于我所看到的问题。。。我发现,当您启用一个模块时,它会在运行迁移之前运行NHibernate映射


Josh

更新PersistenceConfiguration类中ComputingHash方法中的哈希值, 更新哈希值可能会重新创建mappings.bin文件

    public class PersistenceConfiguration : ISessionConfigurationEvents
    {
      public void Created(FluentConfiguration cfg, AutoPersistenceModel defaultModel)
      {
          DoModelMapping(cfg, defaultModel);
      }

      public void ComputingHash(Hash hash)
      {
          hash.AddString("Some_strings_to_update_hash");
      }

      private void DoModelMapping(FluentConfiguration cfg, AutoPersistenceModel defaultModel)
      {

             // mappings here....
      }

      public void Prepared(FluentConfiguration cfg) { }

      public void Building(Configuration cfg) { }

      public void Finished(Configuration cfg) { }
    }

感谢您提供的信息,我不知道映射在这里被持久化了。删除此文件,然后禁用/启用模块就成功了,尽管我不相信这就是我要寻找的答案:)我只是想知道这样做是否绕过了Orchard过程?我发现我遇到了同样的问题,您的解决方案也起了作用,但就像@mikesimons一样,我发现这种方法是一种奇怪的方法。这真的是最好的方法吗?仅供参考-我正在使用Orchard 1.6。我正在运行Orchard 1.10,刚刚在我的
ContentPart
中添加了一个属性,发现我还必须删除映射文件。这是一个担忧,因为我想释放我的模块,这将使升级困难。
    public class PersistenceConfiguration : ISessionConfigurationEvents
    {
      public void Created(FluentConfiguration cfg, AutoPersistenceModel defaultModel)
      {
          DoModelMapping(cfg, defaultModel);
      }

      public void ComputingHash(Hash hash)
      {
          hash.AddString("Some_strings_to_update_hash");
      }

      private void DoModelMapping(FluentConfiguration cfg, AutoPersistenceModel defaultModel)
      {

             // mappings here....
      }

      public void Prepared(FluentConfiguration cfg) { }

      public void Building(Configuration cfg) { }

      public void Finished(Configuration cfg) { }
    }