Including Value Types in Derived Models Update Method

Posts   
 
    
Puromtec
User
Posts: 76
Joined: 22-Jun-2005
# Posted on: 09-Mar-2018 18:13:37   

LLBL Gen Version: 5.3.4

I do not see generated code in the update extension methods for copying Value Type field values from a dto (derived model) to the root entity. Would it make sense to generate code to that does this?

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 10-Mar-2018 07:07:43   

Hi Puromtec,

What do you mean by 'methods for copying Value Type field from dto to the root entity'? Could you please post an example of what you are looking for?

David Elizondo | LLBLGen Support Team
Puromtec
User
Posts: 76
Joined: 22-Jun-2005
# Posted on: 11-Mar-2018 00:57:54   

The Derived Model Persistent classes do not contain mappings between the "embedded element" for Value Types and the corresponding root entity's fields in the Persistent Update methods.

Here is an example of an Update method which only contains mappings for fields that use standard types. Note that Origin and RightDirection, for example are not mapped in this method.

public static void UpdateFromView(this Fab.Data.EntityClasses.View toUpdate, Fab.Data.Dto.DtoClasses.ViewDto dto)
        {
            if((toUpdate == null) || (dto==null))
            {
                return;
            }
            toUpdate.Guid = dto.Guid;
            toUpdate.Name = dto.Name;
            toUpdate.ViewId = dto.ViewId;
        }

Here is the corresponding "project" method:

private static System.Linq.Expressions.Expression<Func<Fab.Data.EntityClasses.View, Fab.Data.Dto.DtoClasses.ViewDto>> CreateProjectionFunc()
        {
            return p__0 => new Fab.Data.Dto.DtoClasses.ViewDto()
            {
                Guid = p__0.Guid,
                ModelGuid = p__0.Model.Guid,
                Name = p__0.Name,
                Origin = new Fab.Data.Dto.DtoClasses.ViewDtoTypes.OriginDto()
                {
                    X = p__0.Origin.X,
                    Y = p__0.Origin.Y,
                    Z = p__0.Origin.Z,
                },
                RightDirection = new Fab.Data.Dto.DtoClasses.ViewDtoTypes.RightDirectionDto()
                {
                    X = p__0.RightDirection.X,
                    Y = p__0.RightDirection.Y,
                    Z = p__0.RightDirection.Z,
                },
                UpDirection = new Fab.Data.Dto.DtoClasses.ViewDtoTypes.UpDirectionDto()
                {
                    X = p__0.UpDirection.X,
                    Y = p__0.UpDirection.Y,
                    Z = p__0.UpDirection.Z,
                },
                ViewDirection = new Fab.Data.Dto.DtoClasses.ViewDtoTypes.ViewDirectionDto()
                {
                    X = p__0.ViewDirection.X,
                    Y = p__0.ViewDirection.Y,
                    Z = p__0.ViewDirection.Z,
                },
                ViewId = p__0.ViewId,
                ViewParamValues = p__0.ViewParamValue.Select(p__1 => new Fab.Data.Dto.DtoClasses.ViewDtoTypes.ViewParamValueDto()
                {
                    DoubleVal = p__1.DoubleVal,
                    ElementIdVal = p__1.ElementIdVal,
                    NoneValue = p__1.NoneValue,
                    ParamName = p__1.Param.Name,
                    ParamStorageTypeName = p__1.Param.ParamStorageType.Name,
                    StringValue = p__1.StringValue,
                }).ToList(),
            };
        }
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 11-Mar-2018 10:13:24   

What's the ORM you're using? EF? Or our own?

Frans Bouma | Lead developer LLBLGen Pro
Puromtec
User
Posts: 76
Joined: 22-Jun-2005
# Posted on: 11-Mar-2018 21:21:05   

I am using EF Core V2.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 12-Mar-2018 10:09:24   

Puromtec wrote:

public static void UpdateFromView(this Fab.Data.EntityClasses.View toUpdate, Fab.Data.Dto.DtoClasses.ViewDto dto)
        {
            if((toUpdate == null) || (dto==null))
            {
                return;
            }
            toUpdate.Guid = dto.Guid;
            toUpdate.Name = dto.Name;
            toUpdate.ViewId = dto.ViewId;
        }

Are you sure this is generated code by LLBLGen Designer and not custom user's code?

David Elizondo | LLBLGen Support Team
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 12-Mar-2018 10:32:03   

Likely a bug. Will look into it.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 12-Mar-2018 11:52:41   

It's currently a limitation, as it only updates fields from the DTO itself, not from embedded derived elements inside the DTO. The derived element derived from the value type is an embedded derived element and is therefore skipped. This isn't correct, fully agreed.

(it currently doesn't see the difference between Customer in Order.Customer and Address in Customer.Address where Address is a value type and Customer is an entity.)

It's not that easy to solve this though, so we'll look into whether it can be done in the v5.3 codebase otherwise we've to postpone this change to v5.4

Frans Bouma | Lead developer LLBLGen Pro
Puromtec
User
Posts: 76
Joined: 22-Jun-2005
# Posted on: 12-Mar-2018 14:16:30   

Thank you guys for looking at this.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 13-Mar-2018 09:45:58   

Almost there. Some tests left


        /// <summary>Updates the specified DMWithValueType.EntityClasses.Customer entity with the values stored in the dto object specified</summary>
        /// <param name="toUpdate">the entity instance to update.</param>
        /// <param name="dto">The dto object containing the source values.</param>
        /// <remarks>The PK field of toUpdate is set only if it's not marked as readonly.</remarks>
        public static void UpdateFromCustomer(this DMWithValueType.EntityClasses.Customer toUpdate, Dtos.DtoClasses.Customer dto)
        {
            if((toUpdate == null) || (dto==null))
            {
                return;
            }
            toUpdate.Address.City = dto.Address.City;
            toUpdate.Address.Country = dto.Address.Country;
            toUpdate.Address.HouseNo = dto.Address.HouseNo;
            toUpdate.Address.Street = dto.Address.Street;
            toUpdate.Address.ZipCode.ZipCodeValue = dto.Address.ZipCode.ZipCodeValue;
            toUpdate.CompanyName = dto.CompanyName;
            toUpdate.Id = dto.Id;

        }

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 13-Mar-2018 12:35:46   

Hotfix is now available (5.2.7 and 5.3.4). Just regenerate the code and it should be included. We didn't include null checks, as you're updating an entity and therefore it's assumed the valuetype object is present.

Frans Bouma | Lead developer LLBLGen Pro