none
Automatic properties: DBSet vs ObjectSet RRS feed

  • Question

  • hi

    Why are we able to use automatic properties with DBSet, but not with ObjectSet:

        public class SomeContext : DbContext
        {        
            public DbSet<Address> Addresses { get; set; }
                     ...
        }


    Thank you

    Wednesday, April 18, 2012 6:57 PM

Answers

  • On 4/19/2012 3:32 PM, KlemS100 wrote:
    > If you look inside automatically generated class ( say SampleContext )
    > created by default code generation, you'll see no events are raised in
    > the getter/setter of SampleContext.Addresses, for example. There's only
    > a call to ObjectSet.CreateObjectSet<TEntity>() and that's it:
    >
    >      public partial class SampleEntities : ObjectContext
    >      {
    >                       ...
    >          public ObjectSet<Address>  Addresses
    >          {
    >              get
    >              {
    >                  if ((_Addresses == null))
    >                  {
    >                      _Addresses = base.CreateObjectSet<Address>("Addresses");
    >                  }
    >                  return _Addresses;
    >              }
    >          }
    >       }
     
    Events raised or NOT there is code in that getter. An event, if calling
    an event,  would have code in the getter to raise the event or the
    setter would have code to raise an event. It doesn't have code raising
    an event in your example. The fact that the property's accessors have
    code - period - in one or both of the getter/setter makes it not an
    auto-property candidate.
     
    Don't you get it? There can be no code in the getter or setter -- in
    regards to it having the feasibility of being an auto-property.
     
    In addition to that, the getter is pointing to a   private backing
    variable in the class called _Addresses, which again makes the property
    not an auto-property candidate.
     public string Help {get; set;}  --  auto-property.
     NOT AN auto-property or the feasibility of it being an auto-property
     
    private string _help;
    public string Help
    {
        get
        {
          return _help;
        }
        set
        {
           if(value != NULL)
              _help = value;
        }
    }
     
     
    <copied>
     
    READ THE SENTENCE  --  (In C# 3.0 and later, auto-implemented properties
    make property-declaration more concise when "no additional logic is
    required in the property accessors.")
     
    They also enable client code to create objects. When you declare a
    property as shown in the following example, the compiler creates a
    private, anonymous backing field that can only be accessed through the
    property's get and set accessors.
     
    <end>
     
    In addition to this, that example you have provided doesn't have a
    'set'. So how can it be an auto-property with no 'set'?
     Now something like Reshaper would look at the properties and if it saw this.
     
    private string _help;
    public string Help
    {
        get
        {
          return _help;
        }
        set
        {
          _help = value;
        }
    }
     
    Reshaper would ask do you want to convert the property to an
    auto-property? If you want to convert, then it would convert the above
    to this.
     
    public string Help {get; set;}
     
    Reshaper would get rid of all the code dealing with the property and
    turn it into an auto-property.
     
    Thursday, April 19, 2012 8:22 PM
  • Hi KlemS100,

    As you can see from the code you pasted, the ObjectSet properties are designed by default to lazily instantiate the ObjectSet when the property is accessed. DbContext on the other hand uses reflection to discover the DbSet<T> properties and instantiate them when the DbContext is instantiated. If you were to convert the ObjectContext's properties to auto-properties then obviously they'd be null when you try to access them since they are never instantiated. You can implement the same logic as the DbContext with the ObjectContext, but since it isn't implemented by default using reflection you'd have to do the custom code yourself. Like so:

    public partial class SampleEntities : ObjectContext { public SampleEntities() { Addresses = base.CreateObjectSet<Address>("Addresses");

    }

    public ObjectSet<Address> Addresses { get; set; } }

    Regards,

    Tyler

    Saturday, April 21, 2012 1:37 PM

All replies

  • On 4/18/2012 2:57 PM, KlemS100 wrote:
    > hi
    >
    > Why are we able to use automatic properties with DBSet, but not with
    > ObjectSet:
    >
    >      public class SomeContext : DbContext
    >      {
    >          public DbSet<Address>  Addresses { get; set; }
    >                   ...
    >      }
    >
     Auto properties uses a internal backing variable for the getter/setter,
    which means no events or special code will be in the getter/setter.
     
    If one is not using a auto property, one has custom code in the
    getter/setter, like raising events on the setter,  and a created backing
    variable the getter/setter is pointing to.
     
    Wednesday, April 18, 2012 7:17 PM
  • hi

    I'm aware of how automatic properties work, but I'm curious about what exactly is preventing ObjectSet from being able to use automatic properties?

    Wednesday, April 18, 2012 7:38 PM
  • On 4/18/2012 3:38 PM, KlemS100 wrote:
    > hi
    >
    > I'm aware of how automatic properties work, but I'm curious about what
    > exactly is preventing ObjectSet from being able to use automatic properties?
    >
     
    Because events are being raised  on the setter or the getter or both in
    the getter and setter code in ObjectSet. What those events are you are
    going to have to look them up.
     
    If you know about auto properties, then no events no special code no
    nothing  is in the get/set of the auto properties, because they just do
    a simple set or get on an automatic backing variable created for the
    auto property.
     
     
    Wednesday, April 18, 2012 10:01 PM
  • If you look inside automatically generated class ( say SampleContext  )  created by default code generation, you'll see no events are raised in the getter/setter of SampleContext.Addresses, for example. There's only a call to ObjectSet.CreateObjectSet<TEntity>() and that's it:

        public partial class SampleEntities : ObjectContext
        {
                         ...
            public ObjectSet<Address> Addresses
            {
                get
                {
                    if ((_Addresses == null))
                    {
                        _Addresses = base.CreateObjectSet<Address>("Addresses");
                    }
                    return _Addresses;
                }
            }
         }


    Thursday, April 19, 2012 7:32 PM
  • On 4/19/2012 3:32 PM, KlemS100 wrote:
    > If you look inside automatically generated class ( say SampleContext )
    > created by default code generation, you'll see no events are raised in
    > the getter/setter of SampleContext.Addresses, for example. There's only
    > a call to ObjectSet.CreateObjectSet<TEntity>() and that's it:
    >
    >      public partial class SampleEntities : ObjectContext
    >      {
    >                       ...
    >          public ObjectSet<Address>  Addresses
    >          {
    >              get
    >              {
    >                  if ((_Addresses == null))
    >                  {
    >                      _Addresses = base.CreateObjectSet<Address>("Addresses");
    >                  }
    >                  return _Addresses;
    >              }
    >          }
    >       }
     
    Events raised or NOT there is code in that getter. An event, if calling
    an event,  would have code in the getter to raise the event or the
    setter would have code to raise an event. It doesn't have code raising
    an event in your example. The fact that the property's accessors have
    code - period - in one or both of the getter/setter makes it not an
    auto-property candidate.
     
    Don't you get it? There can be no code in the getter or setter -- in
    regards to it having the feasibility of being an auto-property.
     
    In addition to that, the getter is pointing to a   private backing
    variable in the class called _Addresses, which again makes the property
    not an auto-property candidate.
     public string Help {get; set;}  --  auto-property.
     NOT AN auto-property or the feasibility of it being an auto-property
     
    private string _help;
    public string Help
    {
        get
        {
          return _help;
        }
        set
        {
           if(value != NULL)
              _help = value;
        }
    }
     
     
    <copied>
     
    READ THE SENTENCE  --  (In C# 3.0 and later, auto-implemented properties
    make property-declaration more concise when "no additional logic is
    required in the property accessors.")
     
    They also enable client code to create objects. When you declare a
    property as shown in the following example, the compiler creates a
    private, anonymous backing field that can only be accessed through the
    property's get and set accessors.
     
    <end>
     
    In addition to this, that example you have provided doesn't have a
    'set'. So how can it be an auto-property with no 'set'?
     Now something like Reshaper would look at the properties and if it saw this.
     
    private string _help;
    public string Help
    {
        get
        {
          return _help;
        }
        set
        {
          _help = value;
        }
    }
     
    Reshaper would ask do you want to convert the property to an
    auto-property? If you want to convert, then it would convert the above
    to this.
     
    public string Help {get; set;}
     
    Reshaper would get rid of all the code dealing with the property and
    turn it into an auto-property.
     
    Thursday, April 19, 2012 8:22 PM
  • Hi KlemS100,

    As you can see from the code you pasted, the ObjectSet properties are designed by default to lazily instantiate the ObjectSet when the property is accessed. DbContext on the other hand uses reflection to discover the DbSet<T> properties and instantiate them when the DbContext is instantiated. If you were to convert the ObjectContext's properties to auto-properties then obviously they'd be null when you try to access them since they are never instantiated. You can implement the same logic as the DbContext with the ObjectContext, but since it isn't implemented by default using reflection you'd have to do the custom code yourself. Like so:

    public partial class SampleEntities : ObjectContext { public SampleEntities() { Addresses = base.CreateObjectSet<Address>("Addresses");

    }

    public ObjectSet<Address> Addresses { get; set; } }

    Regards,

    Tyler

    Saturday, April 21, 2012 1:37 PM
  • This post from the team who created the ObjectSet

    http://msdn.microsoft.com/en-us/magazine/gg232765.aspx


    JP Cowboy Coders Unite!

    Saturday, April 21, 2012 2:23 PM