views:

232

answers:

5

I have a constructor something like the following:

using Microsoft.Data.Extensions;

public class Complaint
{
  public int Id {get; set;}
  public int Transcript {get; set;}
  //... etc. ... Lots more properties

  public Complaint(int id)
  {
    var command = dataContext.CreateStoreCommand(
                     "dbo.stp_Complaint_Get", 
                     CommandType.StoredProcedure, 
                     new SqlParameter("Id", id));

    var complaint = command.Materialize(x =>
                        new Complaint
                        {
                          Id = x.Field<int>("Id"),
                          Transcript = x.Field<string>("Transcript");
                          //... etc. ... Lots more fields from db

                        }

    this.Id = complaint.Id;
    this.Transcript = complaint.Transcript;
    //... etc. ... Lots more properties to set

  }

}

Is there a syntax in C# that would allow me to carry out the last part in one step instead of two? i.e. conceptually something like this:

this = command.Materialize(x =>
                   new Complaint
                   {
                      Id = x.Field<int>("Id"),
                      Transcript = x.Field<string>("Transcript");
                   }
A: 

Not inherently. You could store the complaint object inside the class, and have all the properties point off that rather than setting them all from the constructor.

eg

public class Complaint
{
    private readonly {type of complaint} m_Complaint;        

    public int Id
    {
         get { return m_Complaint.Id; }
    }

    // ...etc
}

You could get more complicated if you don't have a setter on m_Complaint - keeping nullable backing fields, and check that before you access the m_Complaint properties

thecoop
+3  A: 

Well, you could use a static method instead of a constructor:

public static Complaint FromId(int id)
{
   var command = dataContext.CreateStoreCommand(
                 "dbo.stp_Complaint_Get", 
                 CommandType.StoredProcedure, 
                 new SqlParameter("Id", id));

   return command.Materialize(x =>
                    new Complaint
                    {
                      Id = x.Field<int>("Id"),
                      Transcript = x.Field<string>("Transcript");
                      //... etc. ... Lots more fields from db

                    });
}
Jon Skeet
Yup. Breaks away from my current pattern but I think I might do that.
Martin
A: 

I believe you may try something like this:


var currentInstance = this;
var complaint = command.Materialize(x =>
                        new Complaint
                        {
                          Id = currentInstance.Id = x.Field("Id"),
                          Transcript = currentInstance.Transcript = x.Field("Transcript");
                          //... etc. ... Lots more fields from db

                        });

I don't think you can capture this in the closure, so using that currentInstance trick should help, however it may as well turn out to be redundant. Besides, code such as that one is sort of obfuscated compared to your current solution. I believe that your code is pretty fine as it is.

emaster70
This had my hopes up, but unfortunately produces the error "An expression tree may not contain an assignment operator".
Martin
A: 

I gather that you're trying to avoid setting all of those properties twice, because any change to the structure requires you to update the properties in two places, is that correct?. You could try to use some reflection to copy the properties from one instance to another.

var complaint = command.Materialize(x =>
                        new Complaint
                        {
                          Id = x.Field<int>("Id"),
                          Transcript = x.Field<string>("Transcript");
                          //... etc. ... Lots more fields from db

                        }

foreach (var prop in typeof(Complaint).GetProperties())
    ...
Adam Ruth
Yes that's exactly my need - to avoid the maintenance burden caused by the duplication.Reflection seems a rather heavy tool for the problem - was hoping there was a syntax trick. Thanks anyway.
Martin
A: 

Have the complaint object as a member variable and the get/set properties accesses the underlying complaint's properties?

Unsliced