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):

class Contact
{
    public int ContactID;
    public string FirstName;
    public string LastName;
}

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:

partial class Contact
{
    public string FullName
    {
        get
        {
            return FirstName + " " + LastName;
        }
    }
} 

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

var contacts = from c in dataContext.Contacts
               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:

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:

partial class GetContactsResult
{
    public string FullName
    {
        get
        {
            return FirstName + " " + LastName;
        }
    }
}

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:

[Table]
partial class GetContactsResult
{
    public string FullName
    {
        get
        {
            return FirstName + " " + LastName;
        }
    }
}

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.

Tweet Post Share Update Email RSS