我正在编写一个自定义模块,该模块使用注入的IRepository直接从Orchard DB检索和推送数据。
这很好,直到我需要更新一个内容部分。我在迁移类中添加了一个更新,更新将贯穿始终(使用默认值更新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"时,更新运行后,列会出现在DB中,但在重新创建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();
这看起来有点混乱。。。
干杯。
ps我仍然在运行Orchard 1.3.9
经过更多的测试,NHibernate修复程序现在已经停止工作,所以也许我最初的发现只是转移注意力。在更新/检索时,内容部分的新属性似乎被NHibernate完全忽略了——就好像对象定义缓存在某个地方。。。
如果映射没有更新,那就很奇怪了。您可以尝试通过删除app_data文件夹中的mappings.bin并重新启动应用程序来强制执行此操作。Orchard应该重新创建nhibernate映射并保存为mappings.bin.
我也遇到过同样的问题,唯一能找到的方法就是删除mappings.bin(我不需要禁用和重新启用该模块)。事实上,这是我从Bertrand那里得到的答案,当我问为什么会发生这种情况时。
我已将此作为问题记录在http://orchard.codeplex.com/workitem/19306.如果你能投赞成票,那么我们可能会更快地看到它。
这似乎是一个类似于我所看到的问题。。。我看到,当您启用一个模块时,它会在运行迁移之前运行NHibernate映射。。
https://orchard.codeplex.com/workitem/19603
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) { }
}