locked
Using Extensibility Method Definitions RRS feed

  • Question

  • User1265544268 posted

     I just saw one of the new videos on these methods and it being used for validation/busness logic.  The question is, how do I manipulate the data.  For example, most of my tables have a last modified column containing the date and time.  The default is set to 'getDate()' in the database so the initial insert is handled.  However, I would like all updates to set the last modified as well.  Ideally, the last modified column would be read only with the system updating the date and time just not sure how to go about it.

    <code>

    Partial Public Class JobTracker4DataContext

        Private Sub UpdateClient(ByVal instance As Client)
            instance.LastModified = Now
        End Sub
    End Class

    <MetadataType(GetType(Client_Metadata))>  _
    Partial Public Class Client

    End Class

    Public Class Client_Metadata

    End Class

    </code>

    Thanks for the help!

    Monday, December 15, 2008 2:29 PM

All replies

  • User-1005219520 posted

    Add StoreGeneratedPattern="Computed"  to the CSDL. You don't want to add the timestamp on the client side - let the DB do its job.

    Monday, December 15, 2008 2:51 PM
  • User1265544268 posted

     Not sure what you mean here.  The DB is doing its job when the record is created.  The getDate() default does not fire on updates though.  Are you saying I should write a trigger instead and not use the code behind to update the value.  I understand how helpful it is to apply business logic here and throw an exception if the data is not valid, but it would be nice to be able to do something with the data from here.

    Monday, December 15, 2008 3:03 PM
  • User-1005219520 posted

    Sure it does, if you mark the CSDL. Every table in AdventureWorks and AdventureWorksLT has a rowguid and a dateTime field (for last modified).  You should use StoreGeneratedPattern="Identity" for those fields you only want generated on insert and  StoreGeneratedPattern="Computed" for those you want updated on every update. You don't need a trigger unless you are using SQL 2000 or earlier.

     Here is the ProductCategory Entity  I've marked up for the AWLT DB:

    <EntityType Name="ProductCategory">
              <Key>
                <PropertyRef Name="ProductCategoryID" />
              </Key>
              <Property Name="ProductCategoryID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
              <Property Name="ParentProductCategoryID" Type="int" />
              <Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="50" />
             <Property Name="rowguid" Type="uniqueidentifier" Nullable="false" StoreGeneratedPattern="Identity"/>
             <Property Name="ModifiedDate" Type="datetime" Nullable="false" StoreGeneratedPattern="Computed"/>
            </EntityType>
     
    Monday, December 15, 2008 3:29 PM
  • User1265544268 posted

    Ah, so this for the entity framework.  I am not using that.  I have a VB file generated from the data model and VB file generated from when I first fired it up and walked through the wizard.  Neither file has a reference like that.

    Lets say we wanted to do something similar like add in a user Id from session state.  I wrote out similar code with no results.

    instance.LastModifiedBy = Session("UserId")

    Monday, December 15, 2008 3:57 PM
  • User-1005219520 posted

    Are you using the Linq to SQL (L2S)  data model then? Right now Dynamic Data supports L2S and EF.

    I can't seem to get the dateTime to update automatically without triggers. Triggers are one solution.

    Monday, December 15, 2008 4:26 PM
  • User1265544268 posted

    Yes, I am using Linq to SQL.  What I am talking about is the fact that a data context class is automatically generated for your data model. There is a class for each table.  It seems to be very common practive to extend this.  Since there is an event that automatically fires - UpdateClient - and passes in an instance of the record, it seems like this would be the best and only place to address it.  The clients table, like most all of my tables, doesn't have a custom page.  And it doesn't make sense to do something table specific on a list or details page.

    Here was the original example from the tutorial.  It would be nice to extend this and do something the record being updated.

    <code>

    Partial Public Class JobTracker4DataContext

        Private Sub UpdateClient(ByVal instance As Client)
            If Not Char.IsUpper(instance.Company(0)) Then
                Throw New ValidationException("Please be sure to capitalize the company name!")
            End If
        End Sub

    End Class

    <MetadataType(GetType(Client_Metadata))>  _
    Partial Public Class Client

    End Class

    Public Class Client_Metadata
    .........

    </code>

    Monday, December 15, 2008 7:02 PM
  • User-1005219520 posted

    You're in the right place. Just set the properties you would like to update in the update partial method.

    >> It seems to be very common practive to extend this.  --  it seems like this would be the best and only place to address it. 

    No - you should create a your own file that contains the partial classes/methods you want to over ride. That way your changes remain when you generate a new model. See To create partial class for validation in http://msdn.microsoft.com/en-us/library/cc488527.aspx

    You can simply copy the partial class declaration from the model to another file.

    Monday, December 15, 2008 7:12 PM
  • User1265544268 posted

    OK - Thanks for the help, glad to know I am in the right place.  I should have mentioned the file I am modifying is the one generated from the wizard.  It runs when first create the project and does not run again.  This in addition to the one that runs everytime the data model is updated.

    I thought I was changing the property with 'instance.LastModified = Now()'  I don't see anything like 'instance.Save()' to run after my updates.  Or are you saying to create a new object like 'Dim oClient as New Client(instance)' or something?

    Monday, December 15, 2008 7:43 PM
  • User-1005219520 posted

    >>  file I am modifying is the one generated from the wizard

    You should not modify that file. Look at your model.designer.vb file - each entity (table) has an insert/update/delete declaration you can implement in a partial class in another file. Review  http://msdn.microsoft.com/en-us/library/cc488527.aspx

    in the partial method you assign the property.

    this.LastModified = Now()

    For timestamp updates I still recommend you let the DB server do the updating (via trigger or other mechanisms) - but some properties you will need to set on the asp.net side.

    Monday, December 15, 2008 9:11 PM
  • User-330204900 posted

    I don't see anything like 'instance.Save()'

    It's  

    ExecuteDynamicInsert(instance);
    Hope this helps [:D]
    Tuesday, December 16, 2008 2:20 AM
  • User1265544268 posted

    Thank you!  I had actual just found this code before chacking back here.

    Me.ExecuteDynamicUpdate(instance)

    I read the article linked up above, but it was basically the same article I was referencing.  I just needed to be able to do something with the 'instance' aside from reading it.  Maybe I wasn't conveying my point well enough.

    Tuesday, December 16, 2008 1:24 PM