WCF Ria Services Insert problem

Posts   
 
    
KDL
User
Posts: 24
Joined: 25-Mar-2010
# Posted on: 02-May-2011 19:54:24   

LLBLGen 3.1 Final SQL Server 2008 LLBLGenPro Framework Self-Servicing .NET Framework 4.0

I'm trying to insert an entity using WCF Ria Services with LLBLGen. This is my first attempt at using ria services so I'm probably missing something fundamental. Any help is appreciated.

I followed the docs (http://www.llblgen.com/documentation/3.1/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/gencode_wcfriaservices.htm) for setting up the DomainService class including the config file.

The Asset entity is quite simple with the primary key being a SQL Server identity column (seed of 1).

DomainService:


Imports System.ServiceModel.DomainServices.Hosting
Imports System.ServiceModel.DomainServices.Server
Imports SD.LLBLGen.Pro.RiaSupportClasses
Imports Test.Library.HelperClasses
Imports Test.Library.EntityClasses
Imports Test.Library.Linq
Imports System.Linq

Namespace Web

    <EnableClientAccess()>
    Public Class TestDomainService
        Inherits LLBLGenProDomainService

        Protected Overrides Function CreateTransaction() As SD.LLBLGen.Pro.ORMSupportClasses.ITransaction
            Return New Transaction(System.Data.IsolationLevel.Serializable, "test")
        End Function

        Protected Overrides Sub UpdateEntity(toSave As SD.LLBLGen.Pro.ORMSupportClasses.IEntityCore)
            Me.UpdateEntity(toSave)
        End Sub

        Public Function GetAssets() As IQueryable(Of AssetEntity)
            Return New LinqMetaData(CreateTransaction).Asset
        End Function

        Public Sub InsertAsset(toInsert As AssetEntity)
            Me.InsertEntity(toInsert)
        End Sub

        Public Sub UpdateAsset(toUpdate As AssetEntity)
            Me.UpdateEntity(toUpdate)
        End Sub
    End Class
End Namespace

The SilverLight code:


        Dim ctx As New TestDomainContext

       Dim Asset As New AssetEntity()

        With Asset
            .OriginalFileName = "File Name"
            .FileId = Guid.NewGuid()
            .Name = "Other Name"
            .OriginalSizeKb = 100
            .OrganizationId = 7
        End With

        ctx.AssetEntities.Add(Asset)
        ctx.SubmitChanges()

When I run the Silverlight Business app and try to Add the Asset entity I get the following error (stack trace attached):

The field 'AssetId' is read-only and can't be changed.

BTW, GetAssets works fine so I am able to communicate with the service.

Thanks in advance for any help!

Attachments
Filename File size Added on Approval
StackTrace.txt 6,137 02-May-2011 19:54.54 Approved
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39908
Joined: 17-Aug-2003
# Posted on: 03-May-2011 15:29:11   

There are two problems: 1) the Selfservicing DomainService base class is incomplete it seems: the update method is missing (which you have noticed I think). 2) there's indeed something wrong with the PK fields. As in selfservicing the pk identity fields are readonly, you can't set a value to them. The stacktrace shows the problem: it tries to set all properties with a value (this is WCF code btw, not our code) and then it will pass that entity instance to the domain service. However, as the deserialization of the data in an entity instance fails, it never gets there.

We'll see if we need to add a specific attribute of some sort, as the field isn't to be set.

(edit). I hope it is fixable, but it might be it isn't: the PK value is needed on the service side, however if the value isn't settable inside the field through deserialization, (as the field is readonly), it's IMHO a bit difficult how to fix this. We'll see if we can add a readonly attribute, maybe this helps.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39908
Joined: 17-Aug-2003
# Posted on: 03-May-2011 16:13:42   

Nothing we can do at the WCF RIA front: the WCF RIA services runtime simply deserializes the object received from silverlight from xml to an entity class by setting public properties. There's no way (to our knowledge) to specify specific logic to be executed when setting the property when deserializing the property. This results in the exception you're seeing.

You can solve it using adapter on the service. This solves it right away. The service can't use lazy loading anyway, so there's no benefit in using selfservicing.

There's no other way to solve this other than that we change the behavior for Pk identity fields on selfservicing to mark them not to be readonly. We can't change that in the middle of a release cycle.

So our advice is to use adapter on the service if you use identity pk fields. It's a limitation of WCF ria services that it deserializes data this way, other frameworks (e.g. EF) have the same problem with readonly fields.

Frans Bouma | Lead developer LLBLGen Pro
KDL
User
Posts: 24
Joined: 25-Mar-2010
# Posted on: 03-May-2011 16:37:05   

Thanks for looking into this and for the suggestion to use adapter to get around this. I'm surprised RIA services doesn't handle this situation as it seems like it would be a common scenario (but I'll take that up with Microsoft).wink

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39908
Joined: 17-Aug-2003
# Posted on: 03-May-2011 17:51:49   

KDL wrote:

Thanks for looking into this and for the suggestion to use adapter to get around this. I'm surprised RIA services doesn't handle this situation as it seems like it would be a common scenario (but I'll take that up with Microsoft).wink

heh, well, they have a simple serialization strategy: they simply set properties. This works in most cases, but not in cases where the property can't be set to a value. Of course this is silly in some situations, but they apparently thought 'that's for v2!' wink

We've added a change request for the next v3.x version so setting pk fields in selfservicing is allowed, like it is in adapter, which will fix this problem.

Frans Bouma | Lead developer LLBLGen Pro