我正在尝试使用db4o几天,但我遇到了问题。
想象一下这个班只是为了测试:
class Test
{
public string TestString
public int Number;
public Bitmap Bm;
public Test2 T2;
}
我正在保存整个类和所有子对象。 但是当我加载它时,我不希望加载Bm(只需将其保留为null)。我怎么能把它拿出来? 我需要保存它,因为在某些情况下,我需要加载它。 这是一个表演的事情,因为图片非常大。
答案 0 :(得分:0)
嗯,最简单的解决方案(恕我直言)是将BitMap类包装在另一个类中并使用db4o的transparent activation功能:
using System;
using System.IO;
using System.Linq;
using Db4objects.Db4o;
using Db4objects.Db4o.Activation;
using Db4objects.Db4o.TA;
namespace ActivationDepth
{
class Program
{
static void Main(string[] args)
{
var dbFilePath = Path.GetTempFileName();
using (var db = Db4oEmbedded.OpenFile(dbFilePath))
{
db.Store(new C1 { Name = "c1", Huge = new MyHugeClass("I am really huge....")});
}
var config = Db4oEmbedded.NewConfiguration();
config.Common.Add(new TransparentActivationSupport());
config.Common.ActivationDepth = 0;
using (var db = Db4oEmbedded.OpenFile(config, dbFilePath))
{
var item = db.Query<C1>().ElementAt(0);
Console.WriteLine("{0}", db.Ext().IsActive(item));
Console.WriteLine("[Huge] {0} : {1}", db.Ext().IsActive(item.huge), item.huge);
Console.WriteLine("[Huge] {0} : {1}", db.Ext().IsActive(item.Huge), item.Huge);
}
}
}
class C1 : IActivatable
{
public string Name
{
get
{
Activate(ActivationPurpose.Read);
return name;
}
set
{
Activate(ActivationPurpose.Write);
name = value;
}
}
public MyHugeClass Huge
{
get
{
Activate(ActivationPurpose.Read);
return huge;
}
set
{
Activate(ActivationPurpose.Write);
huge = value;
}
}
public override string ToString()
{
Activate(ActivationPurpose.Read);
return string.Format("[{0}] {1}", GetType().Name, name);
}
public void Bind(IActivator activator)
{
if (this.activator != null && activator != null)
{
throw new Exception("activation already set");
}
this.activator = activator;
}
public void Activate(ActivationPurpose purpose)
{
if (activator != null)
{
activator.Activate(purpose);
}
}
public MyHugeClass huge;
private string name;
[NonSerialized]
private IActivator activator;
}
class MyHugeClass : IActivatable
{
public string Name
{
get
{
Activate(ActivationPurpose.Read);
return name;
}
set
{
Activate(ActivationPurpose.Write);
name = value;
}
}
public MyHugeClass(string name)
{
this.name = name;
}
public override string ToString()
{
Activate(ActivationPurpose.Read);
return string.Format("[{0}] {1}", GetType().Name, name);
}
public void Bind(IActivator activator)
{
if (this.activator != null && activator != null)
{
throw new Exception("activation already set");
}
this.activator = activator;
}
public void Activate(ActivationPurpose purpose)
{
if (activator != null)
{
activator.Activate(purpose);
}
}
private string name;
[NonSerialized]
private IActivator activator;
}
}
请注意,即使我手动实现了IActivatable接口,我也不建议这样做;您可以使用db4otool自动为您实现它。
另一种可能的解决方案是为你的类型控制activation(当在db4o中没有激活一个对象时,它的引用是有效的,但它的所有字段都不会被初始化,不会占用任何空间。)
例如,您可以执行以下操作:
using System;
using System.IO;
using System.Linq;
using Db4objects.Db4o;
using Db4objects.Db4o.Events;
namespace ActivationDepth
{
class Program
{
static void Main(string[] args)
{
var dbFilePath = Path.GetTempFileName();
using (var db = Db4oEmbedded.OpenFile(dbFilePath))
{
db.Store(new C1 { name = "c1", c2 = new C2("c2"), huge = new MyHugeClass("I am really huge....")});
}
var config = Db4oEmbedded.NewConfiguration();
using (var db = Db4oEmbedded.OpenFile(config, dbFilePath))
{
var activate = false;
var fac = EventRegistryFactory.ForObjectContainer(db);
fac.Activating += (sender, eventArgs) =>
{
if (!activate && eventArgs.Object.GetType() == typeof(MyHugeClass))
{
Console.WriteLine("[{0}] Ignoring activation.", eventArgs.Object);
eventArgs.Cancel();
}
else
{
Console.WriteLine("[{0}] Activation will proceed.", eventArgs.Object);
}
};
var item = db.Query<C1>().ElementAt(0);
Console.WriteLine("[IsActive] {0}", db.Ext().IsActive(item.huge));
activate = true;
db.Activate(item.huge, 3);
Console.WriteLine("[IsActive] {0}", db.Ext().IsActive(item.huge));
}
}
}
class C1
{
public string name;
public C2 c2;
public MyHugeClass huge;
public override string ToString()
{
return string.Format("[{0}] {1}", GetType().Name, name);
}
}
class C2
{
public string name;
public C2(string name)
{
this.name = name;
}
public override string ToString()
{
return string.Format("[{0}] {1}", GetType().Name, name);
}
}
class MyHugeClass
{
public string text;
public MyHugeClass(string text)
{
this.text = text;
}
public override string ToString()
{
return string.Format("[{0}] {1}", GetType().Name, text);
}
}
}
您也可以使用activation depth。
希望得到这个帮助。