none
Public readonly column RRS feed

  • Question

  • Let's say I have a table with three properties: ID, username, password. ID is an identity column so it will be autogenerated. Username and password must be set when the record is inserted. Now, username can never change from that point an on. That means it should be ignored during an update.

    Also the Serialization Mode of the DataContext is set to Unidirectional because my classes are exposed through a WCF Service. Since all objects are serialized I don't keep track of the properties changes, so I set all columns to Update Check = Never.

    My first try was setting the Read Only property of the column to true, but it doesn't seem to have any effect; I still can select the record, change the username, and when I call SubmitChanges I see the username property being updated with the new value.

    Is there a way to obtain the behavior I'm looking for? In a nutshell, I want to set the column's value when inserting, keep the property public so I can retrieve it and serialize it, but it should be ignored when updating.

    Thanks.

    Sunday, August 1, 2010 9:34 PM

Answers

  • Hi oscarmorasu,

     

    If the property is setted to Read Only and do not have the setter part, it will cause problems when deserialization, so after all the steps you have done, althrough the Read Only property of Customer.MiddleName is set to True, in the auto-generated code, the Customer.MiddleName property also has the setter part. That’s why you change the MiddleName, and call SubmitChanges you see MiddleName being updated with the new value.  One way is to change the setter part of the property, leave it to empty, however, it is also not suggestted to change the auto-generated code. Another way is to add a partial class for Customer, and add a property similar to the MiddleName  property and use this property instead of the MiddleName property, and a Constructor to initialize the MiddleName used when a new entity is firstly inserted. For example:

     

    public partial class Customer : INotifyPropertyChanging, INotifyPropertyChanged
    {
      public Customer(string cName)
      {
        this.Initialize();
        this._MiddleName = cName;
      }
      
      
      //Use this property instead of the MiddleName property
      public string MiddleNameInstead
      {
        get
        {
          return this. MiddleName; 
        }
        set
        {
          throw new Exception("Cannot set read-only property 'Id'");
        }
      } 
    }
    
    

     

    Best regards,

    Alex Liang

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Wednesday, August 4, 2010 2:39 AM
    Moderator

All replies

  • Hi oscarmorasu,

     

    You mean you have changed the Read Only property of the column to true, then you can still change the username ? As far as I know, if you change the Read Only property true, you can no longer change the property value, if you do that, you will get the compile error saying that the property is read only. So please check the property in your source code to see whether it is really been set to Read Only when you change the Read Only property of the column to true.

     

    Best regards,

    Alex Liang

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Monday, August 2, 2010 12:15 PM
    Moderator
  • I'm using VS2010 and .NET 4.0.

    This is what I did:

    1. I started from scratch with a console app, then added a Linq to SQL model
    2. Drag and drop the Customer table from the AdventureWorksLT2008 database into my model. At this point all properties are read/write. 
    3. I changed the Serialization Mode to Unidirectional and that adds the DataContract and DataMember attributes to all properties.
    4. I set Update Check = Never on all columns because I don't track changes in the instances.
    5.  Change the Customer.MiddleName column to ReadOnly = true. 

    I know where's the catch... If you set the Serialization Mode to unidirectional the setter is created. I think setters are required or the DataContractSerializer fails when serializing the DataContract.

    Let's say I can live with that limitation. The real issue I see is the property is included in the update statement. I'd like to have a way to ignore it on every update, and set it only once when inserting the record.

    Thanks.

    Tuesday, August 3, 2010 3:07 AM
  • Hi oscarmorasu,

     

    If the property is setted to Read Only and do not have the setter part, it will cause problems when deserialization, so after all the steps you have done, althrough the Read Only property of Customer.MiddleName is set to True, in the auto-generated code, the Customer.MiddleName property also has the setter part. That’s why you change the MiddleName, and call SubmitChanges you see MiddleName being updated with the new value.  One way is to change the setter part of the property, leave it to empty, however, it is also not suggestted to change the auto-generated code. Another way is to add a partial class for Customer, and add a property similar to the MiddleName  property and use this property instead of the MiddleName property, and a Constructor to initialize the MiddleName used when a new entity is firstly inserted. For example:

     

    public partial class Customer : INotifyPropertyChanging, INotifyPropertyChanged
    {
      public Customer(string cName)
      {
        this.Initialize();
        this._MiddleName = cName;
      }
      
      
      //Use this property instead of the MiddleName property
      public string MiddleNameInstead
      {
        get
        {
          return this. MiddleName; 
        }
        set
        {
          throw new Exception("Cannot set read-only property 'Id'");
        }
      } 
    }
    
    

     

    Best regards,

    Alex Liang

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Wednesday, August 4, 2010 2:39 AM
    Moderator
  • Thanks for the answer Liang,

    That solution partially works, but I the object still exposes a MiddleName setter. The programmer could use it to change the value. However, as I said before I don't mind having a setter in the property. I understand that required for serialization.

    I'd like to find a way to ignore the property when running an update. Something similar happens on identity columns. The query never updates those columns because it knows they are autogenerated by the database. In my case the column is only set at insert time, but can't be changed afterwards through an update.

    It looks like there's no workaround. The best I can do is remove the MiddleName property from the .dbml and add it in the partial class, just like you suggest, including all the L2S attributes so that it knows how to map it to the database. The downside is the dbml will be out of sync compared to the class.

    Thanks,

    Oscar

    Wednesday, August 4, 2010 5:45 AM