【问题标题】:Property or indexer 'AnonymousType#1.FirstName' cannot be assigned to -- it is read only无法将属性或索引器“AnonymousType#1.FirstName”分配给 - 它是只读的
【发布时间】:2014-11-13 19:19:23
【问题描述】:

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

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 类型,但我不知道如何更改类型并仍然更新值。有什么想法吗?

更新

我找到了一个最终对我有用的解决方案。感谢那些回复并让我走上正轨的海报。我在下面的评论中详细说明了我的解决方案。

【问题讨论】:

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


    【解决方案1】:

    这是因为您试图更改 anonymous 类型的值 - 没有 var 类型这样的东西;这只是告诉编译器从赋值运算符右侧的表达式推断变量的类型。匿名类型中的属性始终是只读的。您需要创建另一个实例:

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

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

    【讨论】:

    • 但是如果我创建另一个实例,我该如何将更改提交回数据库? LINQ 不也只跟踪原始查询分配的对象吗?
    • @Corvertbibby:我不希望你能够将匿名类型提交回数据库,尽管我可能是错的......
    【解决方案2】:

    C# 中的匿名类型是不可变的;换句话说,它们不能改变。他们没有属性设置方法。

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

    【讨论】:

      【解决方案3】:

      如果您的意图是编辑实体然后将其保存回来,则需要返回实体对象而不是 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;
      

      【讨论】:

        【解决方案4】:

        我找到了解决问题的最佳方法。正如其他评论者指出的那样,主要问题是 var 类型是匿名类型。那么问题来了,我可以使用什么类型?好吧,我发现我实际上可以将我的表用作一种类型,它比 var 更有效。以下 sn-p 是 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 的初始联系人查询的属性列。

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

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

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

        【讨论】:

        • var 不是类型。它是一个关键字,告诉编译器找出类型应该是什么并改用它。 editContact 的类型是 IEnumrable<T>,其中 T 是匿名类型。使用var 只是防止您需要输入它(这很方便,因为是匿名的,没有办法输入真实类型的名称;它没有名称)。
        猜你喜欢
        • 1970-01-01
        • 2013-08-22
        • 1970-01-01
        • 2023-03-20
        • 1970-01-01
        • 1970-01-01
        • 2017-08-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多