I'm trying to make a function that changes the query result value to the values in a textbox. I can run the LINQ query, get the values, and read can print the perfectly... But when I try change the queried value to the textbox value, I get the following error:
Property or indexer 'AnonymousType#1.FirstName' cannot be assigned to -- it is read only
Here is the code:
private void editQuery(int contactID)
{
ContactLINQDataContext context = new ContactLINQDataContext("Data Source=WORK-PC;Initial Catalog=Steve Harvey Team;Integrated Security=True");
var editContact = (from Contacts in context.Contacts
join prop in context.Properties on Contacts.Address equals prop.PropertyID
join spouse in context.Contacts on Contacts.Spouse equals spouse.ContactID
where Contacts.ContactID == contactID
select new
{
ID = Contacts.ContactID,
FirstName = Contacts.FirstName,
LastName = Contacts.LastName,
FirstName2 = spouse.FirstName,
LastName2 = spouse.LastName,
Street = prop.Street,
City = prop.City,
State = prop.State,
ZIP = prop.ZIP,
Phone1 = Contacts.Phone,
Phone2 = Contacts.AltPhone,
Email = Contacts.Email,
ContactType = Contacts.Type,
Assets = Contacts.Assets,
Notes = Contacts.Notes,
}).First();
editContact.FirstName = firstNameBox1.Text;
I thought it might be because I am trying to change a var type, but I don't see how I could change the type and still update the value. Any ideas?
UPDATE
I found a solution that finally worked for me. Thank you posters who replied and set me on the right track. I detailed my solution in a comment below.
It's because you're trying to change the value of an anonymous type - there's not such thing as a var
type; that's just telling the compiler to infer the type of the variable from the expression on the right-hand side of the assignment operator. The properties in anonymous types are always read-only. You'll need to create another instance:
editContact = new {
editContact.Id,
FirstName = firstNameBox1.Text,
LastName = editContact.LastName,
...
};
Note that you need to specify all the properties, with the same types, in the same order - that way the two anonymous type creation expressions will be of the same type.
Anonymous types in C# are immutable; in other words, they cannot be changed. They don't have property set methods.
You can create a new anonymous type with the values if that helps.
If your intent is to edit an entity and then save it back, you need to return the entity object(s) rather then an anonymous type that new {...}
gives you:
ContactLINQDataContext context = new ContactLINQDataContext("Data Source=WORK-PC;Initial Catalog=Steve Harvey Team;Integrated Security=True");
var editContact = (from Contacts in context.Contacts
where Contacts.ContactID == contactID
select Contacts
}).First();
editContact.FirstName = firstNameBox1.Text;
I found what I find the be the best solution to my problem. The main problem, as the other commenters have pointed out, is that the var type is an anonymous type. So then the question is, what type can I use? Well, I found that I can actually use my tables as a type, which works even better than a var. The following snippet is an example of a lambda LINQ query:
using (ContactLINQDataContext context = new ContactLINQDataContext("Data Source=WORK-PC;Initial Catalog=Steve Harvey Team;Integrated Security=True"))
{
Contact contact = context.Contacts.SingleOrDefault(x => x.ContactID == contactID);
Contact spouse = context.Contacts.SingleOrDefault(x => x.ContactID == contact.Spouse);
Property property = context.Properties.SingleOrDefault(x => x.PropertyID == contact.Address);
}
This runs 3 separate queries. A query in the contact table to get the contact row using the ContactID provided, a query in the contact table to get the spouse information using the ID in the Spouse column as the ContactID, and a query in the Property table using the info in the Property column of the initial Contact query for the Property ID.
Once these queries were executed, I was able to reference the data directly from the newly created variables.
using (ContactLINQDataContext context = new ContactLINQDataContext("Data Source=WORK-PC;Initial Catalog=Steve Harvey Team;Integrated Security=True"))
{
Contact contact = context.Contacts.SingleOrDefault(x => x.ContactID == contactID);
Contact spouse = context.Contacts.SingleOrDefault(x => x.ContactID == contact.Spouse);
Property property = context.Properties.SingleOrDefault(x => x.PropertyID == contact.Address);
firstNameBox1.Text = contact.FirstName;
lastNameBox1.Text = contact.LastName;
firstNameBox2.Text = spouse.FirstName;
lastNameBox2.Text = spouse.LastName;
streetBox.Text = property.Street;
cityBox.Text = property.City;
stateBox.Text = property.State;
zipBox.Text = property.ZIP;
phoneBox.Text = contact.Phone;
altPhoneBox.Text = spouse.Phone;
emailBox.Text = contact.Email;
}
And sure enough, it works like a charm. The text boxes were populated perfectly.