【发布时间】:2011-12-04 18:23:18
【问题描述】:
使用 db4o 客户端/服务器,更新不适用于对象的集合属性。我正在使用透明的持久性,但这没有帮助。然后,我将我的 Collection 属性更改为 ActivatableCollection,但没有成功。
这是服务器设置:
private void StartDatabase()
{
IServerConfiguration serverConfiguration = Db4oClientServer.NewServerConfiguration();
serverConfiguration.Networking.MessageRecipient = this;
serverConfiguration.Common.Add(new TransparentActivationSupport());
serverConfiguration.Common.Add(new TransparentPersistenceSupport());
string db4oDatabasePath = AppDomain.CurrentDomain.BaseDirectory;
string db4oDatabaseFileName = ConfigurationManager.AppSettings["db4oDatabaseFileName"];
int databaseServerPort = Convert.ToInt32(ConfigurationManager.AppSettings["databaseServerPort"], CultureInfo.InvariantCulture);
_db4oServer = Db4oClientServer.OpenServer(serverConfiguration, db4oDatabasePath + db4oDatabaseFileName, databaseServerPort);
string databaseUser = ConfigurationManager.AppSettings["databaseUser"];
string databasePassword = ConfigurationManager.AppSettings["databasePassword"];
_db4oServer.GrantAccess(databaseUser, databasePassword);
}
这是我要保存的实体:
public class Application : ActivatableEntity
这是 Application 实体中的属性:
public ActivatableCollection<TaskBase> Tasks { get; private set; }
这是更新集合中每个对象的客户端代码:
Application application = (from Application app in db
where app.Name == "Foo"
select app).FirstOrDefault();
foreach (TaskBase task in application.Tasks)
{
task.Description += ".";
}
db.Store(application);
奇怪的是,db.Commit() 也不起作用。
有两种解决方法,但我宁愿以“正确”的方式进行。
解决方法 1:在进行更改时对每个任务调用 db.Store(task)。
解决方法 2:在调用 db.Store() 之前,执行以下操作:
db.Ext().Configure().UpdateDepth(5);
谁能告诉我为什么列表没有更新?
如果有帮助,这里是 ActivatableCollection 类:
public class ActivatableCollection<T> : Collection<T>, IActivatable
{
[Transient]
private IActivator _activator;
/// <summary>
/// Activates the specified purpose.
/// </summary>
/// <param name="purpose">The purpose.</param>
public void Activate(ActivationPurpose purpose)
{
if (this._activator != null)
{
this._activator.Activate(purpose);
}
}
/// <summary>
/// Binds the specified activator.
/// </summary>
/// <param name="activator">The activator.</param>
public void Bind(IActivator activator)
{
if (_activator == activator) { return; }
if (activator != null && null != _activator) { throw new System.InvalidOperationException(); }
_activator = activator;
}
}
【问题讨论】:
-
经过大量的反复试验和 RTFM,我进展缓慢。我发现我没有使用透明持久性。看来服务器和客户端配置需要TransparentPersistenceSupport 配置。而且我错过了必须在每个实体中的每个 GETTER 和 SETTER 上调用激活的地方。不是很透明...
-
这样做意味着我必须为每个属性实现手动获取器和设置器。域实体应该对持久层一无所知,但是这种方法在每个实体上都有 db4o 代码。显式保存每个对象可能更容易。如果我能弄清楚为什么将新对象添加到现有列表不会保持对象和父对象之间的关联,我会这样做。例如:Foo 具有属性 List
。当我执行 Bars.Add(new Bar()) 时,新 Bar 被存储,但它与 Foo 无关。
标签: db4o