查询对象但错过了字段/属性(苏打)

时间:2013-08-09 06:32:25

标签: c# database db4o soda

我正在尝试使用db4o几天,但我遇到了问题。

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

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

}

我正在保存整个类和所有子对象。 但是当我加载它时,我不希望加载Bm(只需将其保留为null)。我怎么能把它拿出来? 我需要保存它,因为在某些情况下,我需要加载它。 这是一个表演的事情,因为图片非常大。

1 个答案:

答案 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

希望得到这个帮助。