属性或索引器'AnonymousType#1.FirstName'无法分配 - 它是只读的

时间:2014-11-13 19:19:23

标签: c# sql linq linq-to-sql

我正在尝试创建一个将查询结果值更改为文本框中值的函数。我可以运行LINQ查询,获取值,并且读取可以完美打印...但是当我尝试将查询的值更改为文本框值时,我收到以下错误:

Property or indexer 'AnonymousType#1.FirstName' cannot be assigned to -- it is read only

以下是代码:

    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;

我认为这可能是因为我正在尝试更改var类型,但我不知道如何更改类型并仍然更新值。有什么想法吗?

更新

我找到了一个终于适合我的解决方案。谢谢海报回复并让我走上正轨。我在下面的评论中详述了我的解决方案。

4 个答案:

答案 0 :(得分:3)

这是因为您正在尝试更改匿名类型的值 - 不存在var类型的内容;这只是告诉编译器从赋值运算符右侧的表达式推断变量的类型。匿名类型中的属性始终是只读的。您需要创建另一个实例:

editContact = new {
    editContact.Id,
    FirstName = firstNameBox1.Text,
    LastName = editContact.LastName,
    ...
};

请注意,您需要以相同的顺序指定具有相同类型的所有属性 - 这样两个匿名类型创建表达式将具有相同的类型。

答案 1 :(得分:1)

C#中的匿名类型是不可变的;换句话说,它们是无法改变的。他们没有财产集合方法。

如果有帮助,您可以使用值创建新的匿名类型。

答案 2 :(得分:0)

如果您的目的是编辑实体然后将其保存回来,则需要返回实体对象,而不是new {...}给您的匿名类型:

    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;

答案 3 :(得分:0)

我找到了我认为最能解决问题的方法。正如其他评论者指出的那样,主要问题是var类型是一种匿名类型。那么问题是,我可以使用哪种类型?好吧,我发现我实际上可以使用我的表作为一种类型,它比var更好用。以下代码段是lambda LINQ查询的示例:

    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);
}

这会运行3个单独的查询。联系人表中的查询使用提供的ContactID获取联系人行,联系人表中的查询使用Spouse列中的ID作为ContactID获取配偶信息,使用信息中的信息在Property表中查询属性ID的初始Contact查询的Property列。

执行这些查询后,我就可以直接从新创建的变量中引用数据。

    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;
    }

果然,它就像一个魅力。文本框填充完整。