查询对象,但遗漏字段/属性(Soda)

本文关键字:属性 Soda 字段 对象 查询 | 更新日期: 2023-09-27 18:26:54

几天以来,我一直在尝试使用db4o,但遇到了一个问题。

想象一下,这个类只是为了测试:

    class Test
{
  public string TestString
  public int Number;
  public Bitmap Bm;
  public Test2 T2;
}

我正在保存整个类和所有子对象。但当我加载它时,我不希望Bm被加载(只需将其留空)。我怎么能忽略它呢?我需要保存它,因为在某些情况下,我需要加载它。这是一个表演的东西,因为图片真的很大。

查询对象,但遗漏字段/属性(Soda)

好吧,最简单的解决方案(IMHO)是将BitMap类封装在另一个类中,并使用db4o的透明激活功能:

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;
    }
}

注意,即使我已经手动实现了IActivable接口,我也不建议这样做;您可以使用db4otool为您自动实现它。

另一个可能的解决方案是控制类型的激活(当对象在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);
        }
    }
}

你也可以玩激活深度。

希望得到帮助。