DTO's and WCF - My Templates Provided

Posts   
 
    
Posts: 5
Joined: 05-May-2008
# Posted on: 05-May-2008 01:40:26   

Hi,

When we (our org) was deciding on an SOA strategy and looking at LLBL to create the data tier we had a conundrum. Especially because we wanted to use WCF (via IIS) to deploy them.

We were creating both .Net-based clients (able to use the rich Entities directly) and dumb web service consumming applications, eg. Sharepoint InfoPath Froms Server, which would require DTO's. Unfortunately the dumb consumers couldn't handle the WSDL generated by WCF so we had no choice but to provide DTO's as a minimum.

In the end we decided to provide both and so I scoured the forums and found some DTO templates. So I took them, modified them to make them a little smarter, handle relationships and circular links.

I admit they are not perfect, but they seem to do pretty well. Since I found the originals here on the forums I thought I would post my mods up free for all to use.

Using them should be fairly straight forward but here are the couple of methods to look for 1. DTO Constructor - takes an Entity and copies it (plus related) to a DTO 2. FromEntity - takes an Entity and copies it (plus related) to a DTO 3. ToEntity - takes a DTO and copies it to an Entity, doesn't do any of the related though 4. ToDTOArray - takes an EntityCollection of Entity and converts it to an array of DTO's

The way I tend to use them is to write a service contract for my Entities then duplicate the service contract using DTO's. Then when implementing the DTO service I just implement the methods by converting to/from DTO's and calling the Entity service, eg.

public UserDTO[] GetUsers(bool onlyEnabled, bool withRoles, bool minimal) { return UserDTO.ToDTOArray(UsersService.GetUsers(onlyEnabled, withRoles, minimal)); }

public UserDTO GetUser(Guid id, bool withRoles) { return new UserDTO(UsersService.GetUser(id, withRoles)); }

public UserDTO[] FindUsers(Guid id, string login, string name, bool onlyEnabled, bool withRoles, bool minimal) { return UserDTO.ToDTOArray(UsersService.FindUsers(id, login, name, onlyEnabled, withRoles, minimal)); }

Install Instructions

  1. Into the *\Templates\SharedTemplates\Net2.x\C# folder copy two files entityDTO.template and entityDTOInterface.template
  2. Into the *\Templates folder copy the file DTO.templatebindings
  3. Into the *\Tasks folder copy the file DTO.tasks
  4. Add the DTO tasks into the generation task queue set in you LLBL project
  5. In the project add the DTO folder
  6. Add a reference to System.Runtime.Serialization
  7. Compile!
Posts: 5
Joined: 05-May-2008
# Posted on: 05-May-2008 01:42:14   

entityDTO.template

using System; using System.ComponentModel; using System.Collections; using System.Runtime.Serialization;

using <[RootNamespace]>.HelperClasses; using <[RootNamespace]>.EntityClasses;

using SD.LLBLGen.Pro.ORMSupportClasses;

namespace <[RootNamespace]>.DTOClasses { /// <summary> /// DTO class for the entity '<[CurrentEntityName]>'. /// </summary> [Serializable, DataContract] public <[If UsePartialClasses]>partial <[EndIf]>class <[CurrentEntityName]>DTO : <[ If IsSubType ]><[ SuperTypeName ]>DTO, <[ EndIf]>IDto<<[CurrentEntityName]>Entity> { #region Class Member Declarations <[Foreach EntityField CrLf]> private <[If IsNullable]><[If IsValueType]>Nullable<<[TypeOfField]>><[Else]><[TypeOfField]><[EndIf]><[Else]><[TypeOfField]><[EndIf]> _<[CaseCamel EntityFieldName]>;<[NextForeach]> #endregion

    /// <summary>
    /// CTor
    /// </summary>
    public <[CurrentEntityName]>DTO()
    {       
    }


    /// <summary>
    /// CTor which initializes the DTO with values from its corresponding entity
    /// </summary>
    /// <param name="entityInstance">The entity instance which holds the values for this DTO</param>
    public <[CurrentEntityName]>DTO(<[CurrentEntityName]>Entity entityInstance) : this(entityInstance, new Hashtable(), new Hashtable()) { }
    internal <[CurrentEntityName]>DTO(<[CurrentEntityName]>Entity entityInstance, Hashtable seenObjects, Hashtable parents)<[ If IsSubType ]> : base(entityInstance, seenObjects, parents)<[ EndIf]>
    {
        FromEntity(entityInstance, seenObjects, parents);
    }

    public virtual IDto<<[CurrentEntityName]>Entity> FromEntity(<[CurrentEntityName]>Entity entityInstance, Hashtable seenObjects, Hashtable parents)
    {
            <[ If IsSubType ]>base.FromEntity(entityInstance, seenObjects, parents);
            <[ EndIf]>seenObjects[entityInstance] = this;
            parents = new Hashtable(parents);
            parents.Add(entityInstance, null);

<[Foreach EntityField CrLf]> _<[CaseCamel EntityFieldName]> = entityInstance.<[EntityFieldName]>;<[NextForeach]> <[Foreach RelatedEntity OneToMany CrLf]><[If Not MappedFieldRelationIsHidden]> _<[CaseCamel MappedFieldNameRelation]> = RelatedArray<<[RelatedEntityName]>DTO,<[RelatedEntityName]>Entity>(entityInstance.<[MappedFieldNameRelation]>, seenObjects, parents);<[EndIf]><[NextForeach]> <[Foreach RelatedEntity ManyToMany CrLf]><[If Not MappedFieldRelationIsHidden]> _<[CaseCamel MappedFieldNameRelation]> = RelatedArray<<[RelatedEntityName]>DTO,<[RelatedEntityName]>Entity>(entityInstance.<[MappedFieldNameRelation]>, seenObjects, parents);<[EndIf]><[NextForeach]> <[Foreach RelatedEntity ManyToOne CrLf]><[If Not MappedFieldRelationIsHidden]> _<[CaseCamel MappedFieldNameRelation]> = RelatedObject<<[RelatedEntityName]>DTO,<[RelatedEntityName]>Entity>(entityInstance.<[MappedFieldNameRelation]>, seenObjects, parents);//(new <[RelatedEntityName]>DTO(entityInstance.<[MappedFieldNameRelation]>, seenObjects);<[EndIf]><[NextForeach]> <[Foreach RelatedEntity OneToOne CrLf]><[If Not MappedFieldRelationIsHidden]> _<[CaseCamel MappedFieldNameRelation]> = RelatedObject<<[RelatedEntityName]>DTO,<[RelatedEntityName]>Entity>(entityInstance.<[MappedFieldNameRelation]>, seenObjects, parents);<[EndIf]><[NextForeach]>

        return this;
    }

    <[ If Not IsSubType ]>
    protected virtual T[] RelatedArray<T,U>(EntityCollection<U> entities, Hashtable seenObjects, Hashtable parents) where T : class, IDto<U>, new() where U : EntityBase2
    {
        if (null == entities)
        {
                return null;
        }

        T[] arr = new T[entities.Count];
        int i = 0;

        foreach (U entity in entities)
        {
                if (parents.Contains(entity))
                {
                    return null;
                }
        }

        foreach (U entity in entities)
        {
                if (seenObjects.Contains(entity))
                {
                    arr[i++] = seenObjects[entity] as T;
                }
                else
                {
                    arr[i++] = new T().FromEntity(entity, seenObjects, parents) as T;
                }
        }
        return arr;
    }

    <[ EndIf]>
    <[ If Not IsSubType ]>
    protected virtual T RelatedObject<T,U>(U entityInstance, Hashtable seenObjects, Hashtable parents) where T : class, IDto<U>, new() where U : EntityBase2
    {
            if (null == entityInstance)
            {
                return null;
            }

            if (seenObjects.Contains(entityInstance))
            {
                if (parents.Contains(entityInstance))
                {
                    return null;
                }
                else
                {
                    return seenObjects[entityInstance] as T;
                }
            }

            return new T().FromEntity(entityInstance, seenObjects, parents) as T;
    }

    <[ EndIf]>
        public static <[CurrentEntityName]>DTO[] ToDTOArray(EntityCollection<<[CurrentEntityName]>Entity> entities)
        {
            Hashtable seenObjects = new Hashtable();
            <[CurrentEntityName]>DTO[] arr = new <[CurrentEntityName]>DTO[entities.Count];
            for (int i = 0; i < entities.Count; i++)
            {
                arr[i] = new <[CurrentEntityName]>DTO().FromEntity(entities[i], seenObjects, new Hashtable()) as <[CurrentEntityName]>DTO;
            }
            return arr;
        }

    /// <summary>
    /// Creates a new entity instance and copies over the values of this DTO
    /// </summary>
    public <[ If IsSubType ]>override <[SuperTypeName]><[ Else]>virtual <[CurrentEntityName]><[ EndIf]>Entity ToEntity()
    {
        return ToEntity(new <[CurrentEntityName]>Entity());
    }


    /// <summary>
    /// Copies over the values of this DTO into the entity passed in.
    /// </summary>
    public virtual <[CurrentEntityName]>Entity ToEntity(<[CurrentEntityName]>Entity toFill)
    {

<[Foreach EntityField CrLf]> toFill.<[EntityFieldName]> = _<[CaseCamel EntityFieldName]>;<[NextForeach]> <[ If IsSubType ]> base.ToEntity(toFill);<[ EndIf]> return toFill; }

    #region Fields

<[Foreach EntityField CrLf]> /// <summary> The <[EntityFieldName]> property of the Entity <[CurrentEntityName]></summary> [DataMember] public <[If EntityFieldOverrides]>override<[Else]>virtual<[EndIf]> <[If IsNullable]><[If IsValueType]>Nullable<<[TypeOfField]>><[Else]><[TypeOfField]><[EndIf]><[Else]><[TypeOfField]><[EndIf]> <[EntityFieldName]> { get { return _<[CaseCamel EntityFieldName]>;} set { _<[CaseCamel EntityFieldName]> = value; } }<[NextForeach]>

    #endregion

    #region Relation Fields

<[Foreach RelatedEntity OneToMany CrLf]><[If Not MappedFieldRelationIsHidden]> private <[RelatedEntityName]>DTO[] _<[CaseCamel MappedFieldNameRelation]>;<[EndIf]><[NextForeach]> <[Foreach RelatedEntity ManyToMany CrLf]><[If Not MappedFieldRelationIsHidden]> private <[RelatedEntityName]>DTO[] _<[CaseCamel MappedFieldNameRelation]>;<[EndIf]><[NextForeach]> <[Foreach RelatedEntity ManyToOne CrLf]><[If Not MappedFieldRelationIsHidden]> private <[RelatedEntityName]>DTO _<[CaseCamel MappedFieldNameRelation]>;<[EndIf]><[NextForeach]> <[Foreach RelatedEntity OneToOne CrLf]><[If Not MappedFieldRelationIsHidden]> private <[RelatedEntityName]>DTO _<[CaseCamel MappedFieldNameRelation]>;<[EndIf]><[NextForeach]>

<[Foreach RelatedEntity OneToMany CrLf]><[If Not MappedFieldRelationIsHidden]> /// <summary> Gets the EntityCollection with the related entities of type '<[RelatedEntityName]>Entity' which are related to this entity via a relation of type '1:n'. /// If the EntityCollection hasn't been fetched yet, the collection returned will be empty.</summary> [DataMember] public virtual <[RelatedEntityName]>DTO[] <[MappedFieldNameRelation]> { get { return _<[CaseCamel MappedFieldNameRelation]>; } set { _<[CaseCamel MappedFieldNameRelation]> = value; } }<[EndIf]><[NextForeach]> <[Foreach RelatedEntity ManyToMany CrLf]><[If Not MappedFieldRelationIsHidden]> /// <summary> Gets the EntityCollection with the related entities of type '<[RelatedEntityName]>Entity' which are related to this entity via a relation of type 'm:n'. /// If the EntityCollection hasn't been fetched yet, the collection returned will be empty.</summary> [DataMember] public virtual <[RelatedEntityName]>DTO[] <[MappedFieldNameRelation]> { get { return _<[CaseCamel MappedFieldNameRelation]>; } set { _<[CaseCamel MappedFieldNameRelation]> = value; } }<[EndIf]><[NextForeach]> <[Foreach RelatedEntity ManyToOne CrLf]><[If Not MappedFieldRelationIsHidden]> /// <summary> Gets / sets related entity of type '<[RelatedEntityName]>Entity' which has to be set using a fetch action earlier. If no related entity /// is set for this property, null is returned. This property is not visible in databound grids.</summary> [Browsable(false), DataMember] public virtual <[RelatedEntityName]>DTO <[MappedFieldNameRelation]> { get { return _<[CaseCamel MappedFieldNameRelation]>; } set { _<[CaseCamel MappedFieldNameRelation]> = value; } }<[EndIf]><[NextForeach]> <[Foreach RelatedEntity OneToOne CrLf]><[If Not MappedFieldRelationIsHidden]> /// <summary> Gets / sets related entity of type '<[RelatedEntityName]>Entity' which has to be set using a fetch action earlier. If no related entity /// is set for this property, null is returned. This property is not visible in databound grids.</summary> [Browsable(false), DataMember] public virtual <[RelatedEntityName]>DTO <[MappedFieldNameRelation]> { get { return _<[CaseCamel MappedFieldNameRelation]>; } set { _<[CaseCamel MappedFieldNameRelation]> = value; } }<[EndIf]><[NextForeach]>

    #endregion

}

}

Posts: 5
Joined: 05-May-2008
# Posted on: 05-May-2008 01:42:53   

entityDTOInterface.template

using System; using System.ComponentModel; using System.Collections; using System.Runtime.Serialization;

using <[RootNamespace]>.HelperClasses; using <[RootNamespace]>.EntityClasses;

using SD.LLBLGen.Pro.ORMSupportClasses;

namespace <[RootNamespace]>.DTOClasses { /// <summary> /// DTO interface. /// </summary> public interface IDto<T> { T ToEntity(T toFill); IDto<T> FromEntity(T entityInstance, Hashtable seenObjects, Hashtable parents); } }

Posts: 5
Joined: 05-May-2008
# Posted on: 05-May-2008 01:43:25   

DTO.templatebindings

<?xml version="1.0" encoding="utf-8" ?> - <templateBindings name="DTO Template" description="DTO Template" precedenceLevel="10" databaseDriverID="2D18D138-1DD2-467E-86CC-4838250611AE" xmlns="http://sd/llblgen/pro/templateBindingsDefinition.xsd"> - <supportedPlatforms> <platform name=".NET 2.0" /> </supportedPlatforms> - <language name="C#"> <templateBinding templateID="SD_DTOTemplate" filename="SharedTemplates\Net2.x\C#\entityDTO.template" templateLanguage="TDL" /> <templateBinding templateID="SD_DTOInterfaceTemplate" filename="SharedTemplates\Net2.x\C#\entityDTOInterface.template" templateLanguage="TDL" /> </language> </templateBindings>

Posts: 5
Joined: 05-May-2008
# Posted on: 05-May-2008 01:43:51   

DTO.tasks

<?xml version="1.0" ?> - <taskGroup xmlns="http://sd/llblgen/pro/taskGroupElementDefinitions.xsd" name="DTO Templates" isOptional="false" description="General group of tasks which are used DTO templates."> - <supportedPlatforms> <platform name=".NET 2.0" /> </supportedPlatforms> - <supportedTemplateGroups> <templateGroup name="Adapter" /> </supportedTemplateGroups> - <taskGroup name="Create Directories"> - <task name="DTODirectoryCreator" assemblyFilename="SD.LLBLGen.Pro.TaskPerformers.dll" taskPerformerClass="SD.LLBLGen.Pro.TaskPerformers.DirectoryCreator"> - <parameters> <parameter name="folderToCreate" defaultValue="DTO" isOptional="false" description="The folder to create" /> <parameter name="failWhenExistent" defaultValue="false" isOptional="true" description="Flag to signal what to do when the folder already exists. Overrules clearWhenExistent" valueType="boolean" /> <parameter name="clearWhenExistent" defaultValue="false" isOptional="true" description="Flag to signal if an existing folder has to be cleared first. Overruled by failWhenExistent" valueType="boolean" /> </parameters> </task> </taskGroup> - <taskGroup name="Create DTO Classes" description="Create DTO Classes"> - <task name="DTOInterfaceCreator" assemblyFilename="SD.LLBLGen.Pro.TaskPerformers.dll" taskPerformerClass="SD.LLBLGen.Pro.TaskPerformers.CodeEmitter"> - <parameters> <parameter isOptional="false" name="destinationFolder" defaultValue="DTO" /> <parameter isOptional="false" name="failWhenExistent" defaultValue="false" /> <parameter isOptional="false" name="filenameFormat" defaultValue="IDto.cs" /> <parameter isOptional="false" name="templateID" defaultValue="SD_DTOInterfaceTemplate" /> <parameter isOptional="false" name="emitType" defaultValue="generic" /> </parameters> </task> - <task name="DTOClassCreator" assemblyFilename="SD.LLBLGen.Pro.TaskPerformers.dll" taskPerformerClass="SD.LLBLGen.Pro.TaskPerformers.CodeEmitter"> - <parameters> <parameter isOptional="false" name="destinationFolder" defaultValue="DTO" /> <parameter isOptional="false" name="failWhenExistent" defaultValue="false" /> <parameter isOptional="false" name="filenameFormat" defaultValue="[elementName]DTO.[extension]" /> <parameter isOptional="false" name="templateID" defaultValue="SD_DTOTemplate" /> <parameter isOptional="false" name="emitType" defaultValue="allEntities" /> </parameters> </task> </taskGroup> </taskGroup>

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 05-May-2008 09:35:42   

Thanks for sharing! simple_smile

You also could have added it as an attachment to your first post btw wink

Frans Bouma | Lead developer LLBLGen Pro
Posts: 4
Joined: 06-May-2008
# Posted on: 06-May-2008 17:36:40   

Thanks ! I was just thinking about working on these myself, this will save me a ton of time.

In order to get these to work, I had to remove the "databaseDriverID="2D18D138-1DD2-467E-86CC-4838250611AE" from the DTO.templatebindings file in order for LLBLgen to find the templates.

Just a question about how you added these to the project. I usually generate the LLBL projects into a separate folder and reference them in the main project. Do you generate these this way or do you add this folder directly into the main project?

I got a little mixed up at the "add these to the project" part, but other than that they seemed to have worked great.

LukeO
User
Posts: 58
Joined: 23-Jul-2007
# Posted on: 28-May-2008 01:47:12   

I started looking at these templates too. Nice! Had one question. If I'm to separate the LLBLGen generated DLL from the DTO how do I resolve the issue of the template using the EntityCollection class? It's use implies that I would need to distribute the LLBLGen DLL which is something I'm trying to avoid.

Thanks, -Luke

pablo.manzanera wrote:

Thanks ! I was just thinking about working on these myself, this will save me a ton of time.

In order to get these to work, I had to remove the "databaseDriverID="2D18D138-1DD2-467E-86CC-4838250611AE" from the DTO.templatebindings file in order for LLBLgen to find the templates.

Just a question about how you added these to the project. I usually generate the LLBL projects into a separate folder and reference them in the main project. Do you generate these this way or do you add this folder directly into the main project?

I got a little mixed up at the "add these to the project" part, but other than that they seemed to have worked great.

Posts: 4
Joined: 06-May-2008
# Posted on: 28-May-2008 16:36:08   

I haven't gotten to the point of testing the working implementation yet, but if I understand you correctly when you add a reference to a web service that returns DTO or list of DTOs, you will get an associated schema as if you returned a typed dataset.

Also, the results I got after using this:

DAL folder + + - DatabaseGeneric folder + + - DatabaseSpecific folder + + - DTO folder + + - DAL.csproj + + - DALDBSpecific.csproj

--> The .cs files in the DTO folder are in the DTOClasses namespace, and I think they should be in the DTO namespace to match the folder they are in

--> I think it would be good to add a .csproj file generator to the overall template so that it could be referenced just like the DAL and DALDBSpecific projects, and maintained separately from any manually written code

Other than that it looks like the code works as advertised and is very well done.

LukeO wrote:

I started looking at these templates too. Nice! Had one question. If I'm to separate the LLBLGen generated DLL from the DTO how do I resolve the issue of the template using the EntityCollection class? It's use implies that I would need to distribute the LLBLGen DLL which is something I'm trying to avoid.

Thanks, -Luke

Seth avatar
Seth
User
Posts: 204
Joined: 25-Mar-2006
# Posted on: 17-Jun-2008 21:17:14   

So I'm a complete noob when it comes to templates etc. I got these to work just fine but I wanted to add a project generator that creates a single C# project (or assembly) for the DTO's. How can this be done. Also, does anyone have an example of how this is ideally used in a wcf app? Thanks for the help!

Posts: 4
Joined: 06-May-2008
# Posted on: 18-Jun-2008 17:02:54   

Seth wrote:

So I'm a complete noob when it comes to templates etc. I got these to work just fine but I wanted to add a project generator that creates a single C# project (or assembly) for the DTO's. How can this be done. Also, does anyone have an example of how this is ideally used in a wcf app? Thanks for the help!

I seperated these out into a project file just by copying some of the template instructions from the ones that come with llblgen, but the references in these classes are setup to be a folder within the main project. Like it is, it won't compile that way.

Can't help you with WCF part, I thought these were supposed to be something different. I thought they were for returning lightweight objects through web services with an associated schema (instead of returning DataSets), but for me they don't return a schema when called through a web service.

Perhaps it's a .NET 3.5 thing, but I couldn't get the desired results when using these to target .NET 2.0 with VS.NET 2008.

LukeO
User
Posts: 58
Joined: 23-Jul-2007
# Posted on: 18-Jun-2008 17:41:26   

Seth wrote:

So I'm a complete noob when it comes to templates etc. I got these to work just fine but I wanted to add a project generator that creates a single C# project (or assembly) for the DTO's. How can this be done. Also, does anyone have an example of how this is ideally used in a wcf app? Thanks for the help!

I created a separate project file and had the template dump these into the directory. I then added those newly "existing" files to the project to make my DTO dll.

You'll also need to create another project that uses the DTOs. This is your basic WCF app that instead of returning a DATASET or simple types returns your DTO using the DTO's factory methods. Remember that you'll also need to create a service interface (contract) first.

-Luke

Posts: 4
Joined: 06-May-2008
# Posted on: 19-Jun-2008 14:59:30   

LukeO wrote:

Seth wrote:

So I'm a complete noob when it comes to templates etc. I got these to work just fine but I wanted to add a project generator that creates a single C# project (or assembly) for the DTO's. How can this be done. Also, does anyone have an example of how this is ideally used in a wcf app? Thanks for the help!

I created a separate project file and had the template dump these into the directory. I then added those newly "existing" files to the project to make my DTO dll.

You'll also need to create another project that uses the DTOs. This is your basic WCF app that instead of returning a DATASET or simple types returns your DTO using the DTO's factory methods. Remember that you'll also need to create a service interface (contract) first.

-Luke

What version of the .NET framework are you using?

toddaheath
User
Posts: 3
Joined: 20-Jun-2008
# Posted on: 24-Jun-2008 19:44:48   

I was wondering what approarch you are using on the service side for deleting orphanded objects from the collections on entity updates / deletes? What approach are you using for switching from the DTO objects to the Entity objects on the service side?

LukeO
User
Posts: 58
Joined: 23-Jul-2007
# Posted on: 24-Jun-2008 19:54:56   

3.5

pablo.manzanera wrote:

LukeO wrote:

Seth wrote:

So I'm a complete noob when it comes to templates etc. I got these to work just fine but I wanted to add a project generator that creates a single C# project (or assembly) for the DTO's. How can this be done. Also, does anyone have an example of how this is ideally used in a wcf app? Thanks for the help!

I created a separate project file and had the template dump these into the directory. I then added those newly "existing" files to the project to make my DTO dll.

You'll also need to create another project that uses the DTOs. This is your basic WCF app that instead of returning a DATASET or simple types returns your DTO using the DTO's factory methods. Remember that you'll also need to create a service interface (contract) first.

-Luke

What version of the .NET framework are you using?

LukeO
User
Posts: 58
Joined: 23-Jul-2007
# Posted on: 24-Jun-2008 20:05:38   

I'm not trying to make anything too complicated as far as object graphs are concerned. For deletes I tend to (if possible) defer those to the database server using cascading deletes and stored procedures or triggers.

For the DTO -> to Entity objects I'm using the code provided above. Specifically the ToEntity method.

toddaheath wrote:

I was wondering what approarch you are using on the service side for deleting orphanded objects from the collections on entity updates / deletes? What approach are you using for switching from the DTO objects to the Entity objects on the service side?

DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 02-Sep-2008 23:03:31   

Hi,

Great template ! Question though : How could you make the DTO more "smart" with change-tracking built-in ? So when you hand-over the DTO back to the LLBLGen entity after editing, it then has the possibility to iterate over all properties which have e.g. IsChanged set to True.

Or am I missing something in this DTO architecture / setup ?

grtz, Danny

arschr
User
Posts: 893
Joined: 14-Dec-2003
# Posted on: 28-Oct-2008 16:01:20   

I am starting to work with these templates.

One issue I've found that hasn't been mentioned yet. Read only fields arenot being honored in the ToEntity method. So for example on my entities with TimeStamp fields I get compile errors where the ToEntity method tries to set the timestamp.

For now I am commenting out the assignment. If I find another solution I'll let y'all know.

kakaiya
User
Posts: 161
Joined: 20-Mar-2004
# Posted on: 05-May-2009 09:52:25   

Hi All,

One issue I've found that hasn't been mentioned yet. Read only fields arenot being honored in the ToEntity method. So for example on my entities with TimeStamp fields I get compile errors where the ToEntity method tries to set the timestamp.

Any one has a solution to this?

Thanks.

Kaksss

methodman
User
Posts: 194
Joined: 24-Aug-2009
# Posted on: 15-Feb-2010 12:35:13   

I was following this install instuctions

Install Instructions

  1. Into the *\Templates\SharedTemplates\Net2.x\C# folder copy two files entityDTO.template and entityDTOInterface.template
  2. Into the *\Templates folder copy the file DTO.templatebindings
  3. Into the *\Tasks folder copy the file DTO.tasks
  4. Add the DTO tasks into the generation task queue set in you LLBL project
  5. In the project add the DTO folder
  6. Add a reference to System.Runtime.Serialization
  7. Compile!

I got stuck at point 4. I cannot see the DTO task in the designer's "Task queue to execute task"

MTrinder
User
Posts: 1461
Joined: 08-Oct-2008
# Posted on: 18-Feb-2010 21:27:00   

Have you restarted the designer after copying the folders...?

Matt

hcaldeira
User
Posts: 16
Joined: 24-Mar-2009
# Posted on: 11-Mar-2010 16:20:48   

Change the files DTO.tasks and DTO.templatebindings to be compatible with .NET 3.5

... <supportedPlatforms> <platform name=".NET 2.0" /> <platform name=".NET 3.5" /> </supportedPlatforms> ...

Walter Almeida avatar
Posts: 150
Joined: 27-Aug-2007
# Posted on: 27-May-2010 09:10:36   

I was interrested by this DTO template. However I have a concern regarding the use of the seenObjects hashtable.

I understand the need for it: avoid infinite loops when cycling references exists. However the hashtable identifies the object as unique by its hashcode

The hascode is unique for a given object type. However the seenObjects hastable store entities of different types. therefore unicity of the hascode accross entity types is not garantied anymore....

Anyone has a better solution to this issue? IOW a reference to a good algorithm to perform object structure traversal?

Thanks in advance