locked
Setting a scaffolded column value RRS feed

  • Question

  • User1122474757 posted

    OK - I'm pretty sure that there's an easy way to accomplish this, but I'm not formulating the right searches to find my answer. I think my scenario would be pretty common in production systems.

    I'm using a replicated record audit table scheme. Everytime a record is updated or modified, a trigger at the database layer fires to store the original value in an audit table.

    I have a field, called "LastModifiedBy" which, in theory, would store the username of the person from the ASP.NET application who performed the operation. (Basically, User.Identity.Name)

     

    I can't seem to make the LastModifiedBy column store the UserName (or any other scaffolded column, for that matter...) work, or I can't figure out the right place to put it. I've only worked with Dynamic Data for a couple of days, but it seems stellar. I'm pretty sure I could do this using a Custom UI field template, but there's something about sending this all the way up to the UI layer that seems a bit... cheesy?

    Where can I put:

    LastModifiedBy = User.Identity.Name ? And have it make sense.

    Thanks!

    Monday, November 24, 2008 5:54 PM

Answers

  • User-330204900 posted

    Hi RudyK, have a look at this article from my blog: DynamicData - Automatic Column Update but not this works for Linq to SQL but needs to be changed for Entity Framework which I've not got around to yet.

    for EF look at these:

    How to: Execute Business Logic During Property Changes (Entity Framework)
    How to: Execute Business Logic When Saving Changes (Entity Framework)
    How to: Change Relationships Between Objects (Entity Framework)

    Hope this helps [:D]

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 25, 2008 3:31 AM
  • User-330204900 posted

    Excelent I will get around to doing an article for EF as well [:D]

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 25, 2008 11:39 AM
  • User-1005219520 posted

    For EF you set the property values in the SavingChanges event handler. Here is a sample using the AWLT DB. Instead of userID and dateModified, I'm setting the passwordHash and passwordSalt.

    You must first add the SavingChanges event handler to your partial class. In the SavingChanges handler set the properties.

     

    namespace AWLT08Model {
    
        public partial class AWLT08Entities {
            partial void OnContextCreated() {
                this.SavingChanges += new EventHandler(OnSavingChanges);
            }
    
            private static void OnSavingChanges(object sender, EventArgs e) {
    
                // This will populate the PasswordHash and PasswordSalt fields
                var stateManager = ((AWLT08Entities)sender).ObjectStateManager;
                var changedEntities = stateManager.GetObjectStateEntries(EntityState.Added);
    
                foreach (ObjectStateEntry stateEntryEntity in changedEntities) {
                    if (stateEntryEntity.Entity is Customer) {
                        Customer cust = (Customer)stateEntryEntity.Entity;
                        cust.PasswordHash = SHC.getHashedPassword();
                        cust.PasswordSalt = new Random().ToString();
                    }
                }
    
    
            }
        }
     
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 25, 2008 6:52 PM

All replies

  • User-1005219520 posted

    You could map the update to a stored procedure. Use ScaffoldColumn(false) to hide the user field. In the OnValidate  (L2) or OnSavingChanges (EF) set the user field to User.Identity.Name

    You're right, this would make a great sample. I'll add it to my to-do list.

    DynamicDataSProc shows how to use stored procs with L2S. I'll look for an EF sample.

    Monday, November 24, 2008 7:11 PM
  • User-330204900 posted

    Hi RudyK, have a look at this article from my blog: DynamicData - Automatic Column Update but not this works for Linq to SQL but needs to be changed for Entity Framework which I've not got around to yet.

    for EF look at these:

    How to: Execute Business Logic During Property Changes (Entity Framework)
    How to: Execute Business Logic When Saving Changes (Entity Framework)
    How to: Change Relationships Between Objects (Entity Framework)

    Hope this helps [:D]

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 25, 2008 3:31 AM
  • User1122474757 posted

     I got it working great - thanks sjnaughton. I used your article and it almost word-for-word matched my scenario :)

     My code looks kinda like this:

     

    public partial class MyDataContext : System.Data.Linq.DataContext
    {
        partial void InsertThingy(Thingy instance)
        {
            string UserName = HttpContext.Current.User.Identity.Name;
            instance.LastModifiedBy = UserName;
            instance.UpdateDT = DateTime.Now;
    
            this.ExecuteDynamicInsert(instance);
        }
    }
     The "partial" keyword allows you to tack on additional code to the generated classes. So, in this case, we attach an additional function by using the partial keyword on the function.
    Tuesday, November 25, 2008 10:22 AM
  • User-330204900 posted

    Excelent I will get around to doing an article for EF as well [:D]

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 25, 2008 11:39 AM
  • User-1005219520 posted

    For EF you set the property values in the SavingChanges event handler. Here is a sample using the AWLT DB. Instead of userID and dateModified, I'm setting the passwordHash and passwordSalt.

    You must first add the SavingChanges event handler to your partial class. In the SavingChanges handler set the properties.

     

    namespace AWLT08Model {
    
        public partial class AWLT08Entities {
            partial void OnContextCreated() {
                this.SavingChanges += new EventHandler(OnSavingChanges);
            }
    
            private static void OnSavingChanges(object sender, EventArgs e) {
    
                // This will populate the PasswordHash and PasswordSalt fields
                var stateManager = ((AWLT08Entities)sender).ObjectStateManager;
                var changedEntities = stateManager.GetObjectStateEntries(EntityState.Added);
    
                foreach (ObjectStateEntry stateEntryEntity in changedEntities) {
                    if (stateEntryEntity.Entity is Customer) {
                        Customer cust = (Customer)stateEntryEntity.Entity;
                        cust.PasswordHash = SHC.getHashedPassword();
                        cust.PasswordSalt = new Random().ToString();
                    }
                }
    
    
            }
        }
     
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 25, 2008 6:52 PM
  • User-578366845 posted

    Hi Rick,

    Thanks for the great code sample covering Dynamic Data with EF.

    How about the following scenario, just to extend further your code sample.
    PasswordHash and PasswordSalt fields are not visible through the Use of ScaffoldColumn(false) for both of them.
    Using the technique from your post above we assigned values to them. 
    At this point, is it possible to use stored procedures for modification of the Customer entity, i.e Insert/Update/Delete operations?
    The question is how to map PasswordHash and PasswordSalt values plus the rest of the Customer entity attributes to the stored procedure parameters?

    Regards,
    Yitzhak

    Tuesday, November 25, 2008 11:56 PM