2013-08-09 20 views
0

Я пытаюсь использовать материал db4o с нескольких дней, но у меня есть проблема.Запросить объект, но пропустить поле/Свойство (Soda)

Представьте себе этот класс только для теста:

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

} 

Я сохраняю весь класс и все дочерние объекты. Но когда я загружаю его, я не хочу, чтобы Bm загружался (просто оставьте его null). Как я могу это оставить? Мне нужно сохранить его, потому что в некоторых случаях мне нужно его загрузить. Это вещь исполнения, потому что картинки действительно большие.

ответ

0

Ну, самое простое решение (ИМХО), чтобы обернуть класс битмэп в transparent activation функции другого класса и использовать 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; 
    } 
} 

Обратите внимание, что даже если я реализовал 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.

Надеюсь, что эта помощь.