我正在编写一个自定义模块,使用注入的IRepository直接从Orchard DB检索和推送数据。
这可以正常工作,直到我需要更新内容部分。我在迁移类中添加了更新,并且更新运行(使用默认值更新的数据库模式),但是我无法通过IRepository更新任何新值。我必须进入NHibernate.ISession来刷新更改。
这一切都适用于新创建的食谱,只有当我改变一个部分时才会这样。以下是关键代码段:
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;
}
}
当我在此示例中添加第二个属性“ProductDescription”时,在运行更新后,列将显示在数据库中但我无法更新它们,直到我重新创建Orchard配方(blat App_Data并重新开始)。
这是我试图更新的方式:
// 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();
}
这里是NHibernate“修复”:
var session = _sessionLocator.For(typeof(TranslationsPartRecord));
var translations = _translationsRepository.Table.SingleOrDefault();
// is translations.Id always 1?
var dbTranslations = session.Get<TranslationsPartRecord>(translations.Id);
dbTranslations.ProductName = translationsViewModel.ProductName;
dbTranslations.ProductDescription = translationsViewModel.ProductDescription;
session.Update(dbTranslations);
session.Flush();
这看起来有点像kludgey ......
干杯。
ps我还在运行Orchard 1.3.9
经过更多测试后,pps pps现在已经停止工作,所以也许我最初的发现是红鲱鱼。似乎NHibernate在更新/检索时完全忽略了内容部分的新属性 - 好像对象定义被缓存在某个地方......答案 0 :(得分:8)
如果您的映射没有更新,那很奇怪。您可以尝试通过删除app_data文件夹中的mappings.bin并重新启动应用程序来强制它。 Orchard应该重新创建nhibernate映射并保存为mappings.bin。
答案 1 :(得分:2)
我遇到了同样的问题,我能找到的唯一方法是删除mappings.bin(我不需要禁用并重新启用该模块)。事实上,当我问到为什么会发生这种情况时,这就是我从伯特兰那里得到的答案。
我已在http://orchard.codeplex.com/workitem/19306将此记录为问题。如果你可以投票,那么我们可能会更快地看到它。
答案 2 :(得分:1)
在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) { }
}
答案 3 :(得分:0)
这看起来像我看到的类似问题......我看到当你启用一个模块时,它会在运行迁移之前运行NHibernate映射。
https://orchard.codeplex.com/workitem/19603
约什