April 2008 Entries
LINQ - Cannot assign value to member XXX. It does not define a setter.

One of the great things about LINQ to SQL is that you can add additional properties to the auto-generated classes via partial classes.  However, occasionally people will run into this exception: System.InvalidOperationException: Cannot assign value to member 'XXX'. It does not define a setter.  Why does this sometimes happen whereas other times the "extra" properties added via the partial class work perfectly?  To answer this, let's take an example.

Suppose we have a contacts class (I've left out the gets/sets but assume properties in the code sample):

   1:  class Contact
   2:  {
   3:      public int ContactID;
   4:      public string FirstName;
   5:      public string LastName;
   6:  }

If you examine the auto-generated code that Visual Studio has produced for you, you'll notice that each property has been decorated with a [Column] attribute with the mapping to the appropriate database column and the class itself has been decorated with a [Table] attribute (I've left the attributes out for brevity).

Now suppose we want to add a new read-only property class FullName via a partial class like this:

   1:  partial class Contact
   2:  {
   3:      public string FullName
   4:      {
   5:          get
   6:          {
   7:              return FirstName + " " + LastName;
   8:          }
   9:      }

When you do this with in conjunction with the auto-generated code, everything works flawlessly.  

   1:  var contacts = from c in dataContext.Contacts
   2:                 select c;

However, suppose that you want to access the data with a stored procedure called GetContacts by dragging that stored procedure to the data context design surface so that you can return the rows like this:

   1:  var contacts = dataContext.GetContacts();

In this case, what you will notice is that the designer creates a class called GetContactsResult that will be returned by the stored procedure call and is very similar to the Contact class above with each attribute decorated by the [Column] attribute to map to the appropriate database column.  However, you will encounter the dreaded exception from above if you attempt to run the code with the following partial class:

   1:  partial class GetContactsResult
   2:  {
   3:      public string FullName
   4:      {
   5:          get
   6:          {
   7:              return FirstName + " " + LastName;
   8:          }
   9:      }
  10:  }

The important distinction is that in the first example, the designer decorated the Contact class with the [Table] attribute but in the second example the GetContactsResult class was not decorated with any attribute.  The LINQ mapper will allow the extra read-only properties when the class is decorated with this [Table] attribute but not in the case where the attribute is absent.  In this case, the mapper assumes that every property should be assigned.  If there is a property that does not have a corresponding value in the query, it will still try to map it but it will send in null to the setter.  If it does not have a setter, the exception above will be thrown.  So the easiest solution is to simply decorate your partial classes with the Table attribute:

   1:  [Table]
   2:  partial class GetContactsResult
   3:  {
   4:      public string FullName
   5:      {
   6:          get
   7:          {
   8:              return FirstName + " " + LastName;
   9:          }
  10:      }
  11:  }

This is all well and good but keep in mind that, if you're running into situations like this, then perhaps using the auto-generated code is not the best option.  You can manually handcraft your entity classes, use stored procedures, and still get plenty of power and benefit from LINQ in the column mappings, connection management, etc.

Posted On Sunday, April 20, 2008 10:27 PM | Comments (3)
CMAP Code Camp Spring 2008 - Code Samples

The code samples from my recent presentation at the Maryland CMAP code camp can be downloaded here:  LINQ to SQL

Posted On Sunday, April 20, 2008 9:40 PM | Comments (0)
Presentation at CMAP Code Camp Spring 2008
This Saturday I'll be giving a presentation on LINQ to SQL at the Spring 2008 Maryland CMAP Code Camp:
Posted On Thursday, April 10, 2008 10:02 PM | Comments (2)

View Steve Michelotti's profile on LinkedIn

profile for Steve Michelotti at Stack Overflow, Q&A for professional and enthusiast programmers

Google My Blog

Tag Cloud