T4 用于通过 LLBLGen Pro 实体生成 POCO?

发布于 2024-12-12 14:14:25 字数 292 浏览 2 评论 0原文

据我了解,LLBLGen Pro 无法在其自己的实体上生成 POCO(请参见此处:http://www .llblgen.com/Pages/featuresLLBLGenPro.aspx)。

有没有人编写过 T4,它将生成与 LLBLGen Pro 实体相对应的 POCO 类,并生成适当的转换逻辑以往返于实体和 POCO?还有其他人提出了一种不涉及手动编写大量转换代码的解决方案吗?

As I understand it, LLBLGen Pro cannot generate POCOs over it's own entities (see here: http://www.llblgen.com/Pages/featuresLLBLGenPro.aspx).

Has anyone written a T4 that will generate POCO classes corresponding to LLBLGen Pro entities and generate the appropriate transformation logic to go to and from an entity and POCO? Has anyone else come up with a solution that doesn't involve manually writing tons of transformation code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

枕花眠 2024-12-19 14:14:26

我们从 LLBLGen 生成 DTO,而不是使用 T4。

我们需要从实体创建 DTO。从技术上讲,这些不是 POCO,因为它们具有 ToEntity() 和 FromEntity() 方法,但也许这对您有用。

我们创建了一个 IDTO 接口,然后由 DTO 类(每个实体一个)实现该接口。我们没有修改实体模板,而是添加了将实体转换为 DTO(以及许多其他帮助器转换)的 DTOExtension 方法。

以下是您可以在 LLBLGen v2.6 中使用的模板文件。版本 3 中的模板设计器更易于使用,如果需要,您可以将大部分代码转换为版本 3。

文件: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);
    }
}

文件: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
{
    <[ UserCodeRegion "AdditionalNamespaces" ]>
    // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces
    // __LLBLGENPRO_USER_CODE_REGION_END
    <[ EndUserCodeRegion ]> 
    /// <summary>
    /// DTO class for the entity '<[CurrentEntityName]>'.
    /// </summary>
    [Serializable]
    public <[If UsePartialClasses]>partial <[EndIf]>class <[CurrentEntityName]>DTO : <[ If IsSubType ]><[ SuperTypeName ]>DTO, <[ EndIf]>IDTO<<[CurrentEntityName]>Entity><[ UserCodeRegion "AdditionalInterfaces" ]>
        // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces
        // __LLBLGENPRO_USER_CODE_REGION_END
        <[ EndUserCodeRegion ]> 
    {
        #region Entity Field Public Properties

<[Foreach EntityField CrLf]>        /// <summary>Get or set the <[EntityFieldName]> property that maps to the Entity <[CurrentEntityName]></summary>
        public virtual <[If GenerateAsNullableType]><[TypeOfField]>?<[Else]><[TypeOfField]><[EndIf]> <[EntityFieldName]> { get; set; }
<[NextForeach]>        
        #endregion

        #region Related Field Public Properties

<[ Foreach RelatedEntityField CrLf]>        /// <summary>Get or set the <[MappedFieldNameRelatedField]> property that maps to the Entity <[CurrentEntityName]>'s <[ MappedFieldNameRelation ]>.<[ RelatedEntityFieldName ]></summary>
        public virtual <[If GenerateAsNullableType]><[TypeOfField]>?<[Else]><[TypeOfField]><[EndIf]> <[ MappedFieldNameRelatedField ]> { get; private set; }<[NextForeach]>

        #endregion

        #region Custom Fields
        <[ UserCodeRegion "CustomFieldCode" ]>
        // __LLBLGENPRO_USER_CODE_REGION_START CustomFieldCode
        // __LLBLGENPRO_USER_CODE_REGION_END
        <[ EndUserCodeRegion ]>
        #endregion

        #region Ctors

        /// <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);
        }

        #endregion

        /// <summary>
        /// Creates a <[CurrentEntityName]>DTO object from the given entity.
        /// </summary>
        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]>            this.<[EntityFieldName]> = entityInstance.<[EntityFieldName]>;<[NextForeach]>
<[Foreach RelatedEntityField CrLf]>            if (entityInstance.AlreadyFetched<[MappedFieldNameRelation]>)
                this.<[MappedFieldNameRelatedField]> = entityInstance.<[MappedFieldNameRelatedField]>;<[NextForeach]>
<[Foreach RelatedEntity OneToMany CrLf]><[If Not MappedFieldRelationIsHidden]>            if (entityInstance.AlreadyFetched<[MappedFieldNameRelation]>)
                <[MappedFieldNameRelation]> = RelatedArray<<[RelatedEntityName]>DTO, <[RelatedEntityName]>Entity>(entityInstance.<[MappedFieldNameRelation]>, seenObjects, parents);<[EndIf]><[NextForeach]>
<[Foreach RelatedEntity ManyToMany CrLf]><[If Not MappedFieldRelationIsHidden]>            if (entityInstance.AlreadyFetched<[MappedFieldNameRelation]>)
                <[MappedFieldNameRelation]> = RelatedArray<<[RelatedEntityName]>DTO, <[RelatedEntityName]>Entity>(entityInstance.<[MappedFieldNameRelation]>, seenObjects, parents);<[EndIf]><[NextForeach]>
<[Foreach RelatedEntity ManyToOne CrLf]><[If Not MappedFieldRelationIsHidden]>            if (entityInstance.AlreadyFetched<[MappedFieldNameRelation]>)
                <[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]>            if (entityInstance.AlreadyFetched<[MappedFieldNameRelation]>)
                <[MappedFieldNameRelation]> = RelatedObject<<[RelatedEntityName]>DTO, <[RelatedEntityName]>Entity>(entityInstance.<[MappedFieldNameRelation]>, seenObjects, parents);<[EndIf]><[NextForeach]>

            return this;
        }

        <[ If Not IsSubType ]>
        /// <summary>
        /// Get a collection of DTO objects created from entities related to <[CurrentEntityName]>Entity.
        /// It keeps track of entities previously seen to prevent an infinite loop.
        /// <summary>
        protected virtual T[] RelatedArray<T,U>(EntityCollectionBase<U> entities, Hashtable seenObjects, Hashtable parents) where T : class, IDTO<U>, new() where U : EntityBase
        {
            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;
        }

        /// <summary>
        /// Creates a DTO object from the given related <[CurrentEntityName]>Entity entity.
        /// This is used to populate a single DTO from a single relation of the <[CurrentEntityName]>Entity.
        /// <summary>
        protected virtual T RelatedObject<T,U>(U entityInstance, Hashtable seenObjects, Hashtable parents) where T : class, IDTO<U>, new() where U : EntityBase
        {
            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]>
        /// <summary>
        /// Get a collection of individual DTO objects from the EntityCollectionBase<<[CurrentEntityName]>Entity> collection.
        /// <summary>
        public static <[CurrentEntityName]>DTO[] ToDTOArray(EntityCollectionBase<<[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. 
        /// Readonly fields on the entity are NOT copied to the entity from this DTO.
        /// </summary>
        public virtual <[CurrentEntityName]>Entity ToEntity(<[CurrentEntityName]>Entity toFill)
        {
<[Foreach EntityField CrLf]><[If IsReadOnly ]><[ Else ]>            toFill.<[EntityFieldName]> = this.<[EntityFieldName]>;<[ EndIf ]><[NextForeach]>

<[ If IsSubType ]>            base.ToEntity(toFill);<[ EndIf]>        
            return toFill;
        }

        #region Relation Fields

<[Foreach RelatedEntity OneToMany CrLf]><[If Not MappedFieldRelationIsHidden]>
        /// <summary> Gets the EntityCollectionBase with the related entities of type '<[RelatedEntityName]>Entity' which are related to this entity via a relation of type '1:n'.
        /// If the EntityCollectionBase hasn't been fetched yet, the collection returned will be empty.</summary>
        public virtual <[RelatedEntityName]>DTO[] <[MappedFieldNameRelation]> { get; set; }<[EndIf]><[NextForeach]>
<[Foreach RelatedEntity ManyToMany CrLf]><[If Not MappedFieldRelationIsHidden]>
        /// <summary> Gets the EntityCollectionBase with the related entities of type '<[RelatedEntityName]>Entity' which are related to this entity via a relation of type 'm:n'.
        /// If the EntityCollectionBase hasn't been fetched yet, the collection returned will be empty.</summary>
        public virtual <[RelatedEntityName]>DTO[] <[MappedFieldNameRelation]> { get; set; }<[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)]
        public virtual <[RelatedEntityName]>DTO <[MappedFieldNameRelation]> { get; set; }<[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)]
        public virtual <[RelatedEntityName]>DTO <[MappedFieldNameRelation]> { get; set; }<[EndIf]><[NextForeach]>

        #endregion

        #region Custom DTO code
        <[ UserCodeRegion "CustomDTOCode" ]>
        // __LLBLGENPRO_USER_CODE_REGION_START CustomDTOCode
        // __LLBLGENPRO_USER_CODE_REGION_END
        <[ EndUserCodeRegion ]>
        #endregion
    }
}

文件:dtoExtensions.template

using System;
using System.Collections.Generic;
using System.Linq;
using <[RootNamespace]>;
using <[RootNamespace]>.EntityClasses;
using <[RootNamespace]>.CollectionClasses;
using <[RootNamespace]>.DTOClasses;
using <[RootNamespace]>.HelperClasses;

namespace <[RootNamespace]>.DTOClasses
{
    /// <summary>
    /// Generates extension methods for converting Entities to DTOs
    /// This class is generated. Do not modify.
    /// </summary>
    public static <[If UsePartialClasses]>partial <[EndIf]>class Extensions
    {
<[If HasEntity]><[Foreach Entity]>
        /// <summary>Create a <[CurrentEntityName]> DTO from a <[CurrentEntityName]> entity</summary>
        /// <returns>The DTO created</returns>
        public static <[CurrentEntityName]>DTO ToDTO(this <[CurrentEntityName]>Entity entity)
        {
            <[CurrentEntityName]>DTO dto = null;
            if (entity != null)
                dto = new <[CurrentEntityName]>DTO(entity);
            return dto;
        }

        /// <summary>Create a list of <[CurrentEntityName]>DTO from a <[CurrentEntityName]>Collection</summary>
        /// <returns>The DTO list created</returns>
        public static List<<[CurrentEntityName]>DTO> ToDTOs(this <[CurrentEntityName]>Collection collection)
        {
            List<<[CurrentEntityName]>DTO> dtoList = new List<<[CurrentEntityName]>DTO>(collection.Count);
            foreach(<[CurrentEntityName]>Entity entity in collection)
                dtoList.Add(new <[CurrentEntityName]>DTO(entity));
            return dtoList;
        }

        /// <summary>Create a list of <[CurrentEntityName]>DTO from a List of <[CurrentEntityName]> entities</summary>
        /// <returns>The DTO list created</returns>
        public static List<<[CurrentEntityName]>DTO> ToDTOs(this List<<[CurrentEntityName]>Entity> entities)
        {
            return entities.ConvertAll<<[CurrentEntityName]>DTO>(e => new <[CurrentEntityName]>DTO(e));
        }

        /// <summary>From the queryable object, get a list of <[CurrentEntityName]>DTO</summary>
        /// <returns>The DTO list created</returns>
        public static List<<[CurrentEntityName]>DTO> ToDTOs(this IQueryable<<[CurrentEntityName]>Entity> queryableEntities)
        {
            return queryableEntities.ToList().ConvertAll<<[CurrentEntityName]>DTO>(e => new <[CurrentEntityName]>DTO(e));
        }

        /// <summary>From the queryable object, get a list of <[CurrentEntityName]>DTO</summary>
        /// <returns>The DTO list created</returns>
        public static <[CurrentEntityName]>DTO FirstDTO(this IQueryable<<[CurrentEntityName]>Entity> queryableEntities)
        {
            <[CurrentEntityName]>DTO dto = null;
            <[CurrentEntityName]>Entity firstEntity = queryableEntities.First();
            if (firstEntity != null)
                dto = new <[CurrentEntityName]>DTO(firstEntity);
            return dto;
        }
<[NextForeach]><[EndIf]>
        #region Custom code
        <[ UserCodeRegion "CustomDTOCode" ]>
        // __LLBLGENPRO_USER_CODE_REGION_START CustomDTOCode
        // __LLBLGENPRO_USER_CODE_REGION_END
        <[ EndUserCodeRegion ]>
        #endregion
    }
}

文件: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 3.5" />
    </supportedPlatforms>
    <supportedTemplateGroups>
    <templateGroup name="SelfServicing" />
    </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="DTOClasses" 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="DTOClasses" />
                <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="DTOClasses" />
                <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>
        <task name="DTOExtentionsCreator" assemblyFilename="SD.LLBLGen.Pro.TaskPerformers.dll" taskPerformerClass="SD.LLBLGen.Pro.TaskPerformers.CodeEmitter">
            <parameters>
                <parameter isOptional="false" name="destinationFolder" defaultValue="DTOClasses" />
                <parameter isOptional="false" name="failWhenExistent" defaultValue="false" />
                <parameter isOptional="false" name="filenameFormat" defaultValue="DTOExtensions.cs" />
                <parameter isOptional="false" name="templateID" defaultValue="SD_DTOExtentionsTemplate" />
                <parameter isOptional="false" name="emitType" defaultValue="generic" />
            </parameters>
        </task>
    </taskGroup>
</taskGroup>

最后,将以下内容添加到 *.preset 文件中的适当位置。这将在您的生成预设中定义上面的代码生成任务。

<taskGroupPreset name="DTO Templates">
  <taskGroupPreset name="Create Directories">
    <taskPreset name="DTODirectoryCreator" />
  </taskGroupPreset>
  <taskGroupPreset name="Create DTO Classes">
    <taskPreset name="DTOInterfaceCreator" />
    <taskPreset name="DTOEntityInterfaceCreator" />
    <taskPreset name="DTOBaseClassCreator" />
    <taskPreset name="DTOClassCreator" />
  <taskPreset name="DTOExtentionsCreator" />
  </taskGroupPreset>
</taskGroupPreset>

We generated DTOs from LLBLGen rather than using T4.

We had a need to create DTOs from an Entity. These aren't technically POCOs because they have a ToEntity() and FromEntity() method, but perhaps this will work for you.

We created an IDTO<T> interface that was then implemented by the DTO classes (one for each entity). Rather than modifying the entity templates, we added DTOExtension methods that would convert an Entity to a DTO (as well as numerous other helper conversions).

Here are the template files you can use within LLBLGen v2.6. The template designer in version 3 is much easier to use, and you can convert much of this code for version 3 if you need to.

File: 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);
    }
}

File: 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
{
    <[ UserCodeRegion "AdditionalNamespaces" ]>
    // __LLBLGENPRO_USER_CODE_REGION_START AdditionalNamespaces
    // __LLBLGENPRO_USER_CODE_REGION_END
    <[ EndUserCodeRegion ]> 
    /// <summary>
    /// DTO class for the entity '<[CurrentEntityName]>'.
    /// </summary>
    [Serializable]
    public <[If UsePartialClasses]>partial <[EndIf]>class <[CurrentEntityName]>DTO : <[ If IsSubType ]><[ SuperTypeName ]>DTO, <[ EndIf]>IDTO<<[CurrentEntityName]>Entity><[ UserCodeRegion "AdditionalInterfaces" ]>
        // __LLBLGENPRO_USER_CODE_REGION_START AdditionalInterfaces
        // __LLBLGENPRO_USER_CODE_REGION_END
        <[ EndUserCodeRegion ]> 
    {
        #region Entity Field Public Properties

<[Foreach EntityField CrLf]>        /// <summary>Get or set the <[EntityFieldName]> property that maps to the Entity <[CurrentEntityName]></summary>
        public virtual <[If GenerateAsNullableType]><[TypeOfField]>?<[Else]><[TypeOfField]><[EndIf]> <[EntityFieldName]> { get; set; }
<[NextForeach]>        
        #endregion

        #region Related Field Public Properties

<[ Foreach RelatedEntityField CrLf]>        /// <summary>Get or set the <[MappedFieldNameRelatedField]> property that maps to the Entity <[CurrentEntityName]>'s <[ MappedFieldNameRelation ]>.<[ RelatedEntityFieldName ]></summary>
        public virtual <[If GenerateAsNullableType]><[TypeOfField]>?<[Else]><[TypeOfField]><[EndIf]> <[ MappedFieldNameRelatedField ]> { get; private set; }<[NextForeach]>

        #endregion

        #region Custom Fields
        <[ UserCodeRegion "CustomFieldCode" ]>
        // __LLBLGENPRO_USER_CODE_REGION_START CustomFieldCode
        // __LLBLGENPRO_USER_CODE_REGION_END
        <[ EndUserCodeRegion ]>
        #endregion

        #region Ctors

        /// <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);
        }

        #endregion

        /// <summary>
        /// Creates a <[CurrentEntityName]>DTO object from the given entity.
        /// </summary>
        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]>            this.<[EntityFieldName]> = entityInstance.<[EntityFieldName]>;<[NextForeach]>
<[Foreach RelatedEntityField CrLf]>            if (entityInstance.AlreadyFetched<[MappedFieldNameRelation]>)
                this.<[MappedFieldNameRelatedField]> = entityInstance.<[MappedFieldNameRelatedField]>;<[NextForeach]>
<[Foreach RelatedEntity OneToMany CrLf]><[If Not MappedFieldRelationIsHidden]>            if (entityInstance.AlreadyFetched<[MappedFieldNameRelation]>)
                <[MappedFieldNameRelation]> = RelatedArray<<[RelatedEntityName]>DTO, <[RelatedEntityName]>Entity>(entityInstance.<[MappedFieldNameRelation]>, seenObjects, parents);<[EndIf]><[NextForeach]>
<[Foreach RelatedEntity ManyToMany CrLf]><[If Not MappedFieldRelationIsHidden]>            if (entityInstance.AlreadyFetched<[MappedFieldNameRelation]>)
                <[MappedFieldNameRelation]> = RelatedArray<<[RelatedEntityName]>DTO, <[RelatedEntityName]>Entity>(entityInstance.<[MappedFieldNameRelation]>, seenObjects, parents);<[EndIf]><[NextForeach]>
<[Foreach RelatedEntity ManyToOne CrLf]><[If Not MappedFieldRelationIsHidden]>            if (entityInstance.AlreadyFetched<[MappedFieldNameRelation]>)
                <[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]>            if (entityInstance.AlreadyFetched<[MappedFieldNameRelation]>)
                <[MappedFieldNameRelation]> = RelatedObject<<[RelatedEntityName]>DTO, <[RelatedEntityName]>Entity>(entityInstance.<[MappedFieldNameRelation]>, seenObjects, parents);<[EndIf]><[NextForeach]>

            return this;
        }

        <[ If Not IsSubType ]>
        /// <summary>
        /// Get a collection of DTO objects created from entities related to <[CurrentEntityName]>Entity.
        /// It keeps track of entities previously seen to prevent an infinite loop.
        /// <summary>
        protected virtual T[] RelatedArray<T,U>(EntityCollectionBase<U> entities, Hashtable seenObjects, Hashtable parents) where T : class, IDTO<U>, new() where U : EntityBase
        {
            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;
        }

        /// <summary>
        /// Creates a DTO object from the given related <[CurrentEntityName]>Entity entity.
        /// This is used to populate a single DTO from a single relation of the <[CurrentEntityName]>Entity.
        /// <summary>
        protected virtual T RelatedObject<T,U>(U entityInstance, Hashtable seenObjects, Hashtable parents) where T : class, IDTO<U>, new() where U : EntityBase
        {
            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]>
        /// <summary>
        /// Get a collection of individual DTO objects from the EntityCollectionBase<<[CurrentEntityName]>Entity> collection.
        /// <summary>
        public static <[CurrentEntityName]>DTO[] ToDTOArray(EntityCollectionBase<<[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. 
        /// Readonly fields on the entity are NOT copied to the entity from this DTO.
        /// </summary>
        public virtual <[CurrentEntityName]>Entity ToEntity(<[CurrentEntityName]>Entity toFill)
        {
<[Foreach EntityField CrLf]><[If IsReadOnly ]><[ Else ]>            toFill.<[EntityFieldName]> = this.<[EntityFieldName]>;<[ EndIf ]><[NextForeach]>

<[ If IsSubType ]>            base.ToEntity(toFill);<[ EndIf]>        
            return toFill;
        }

        #region Relation Fields

<[Foreach RelatedEntity OneToMany CrLf]><[If Not MappedFieldRelationIsHidden]>
        /// <summary> Gets the EntityCollectionBase with the related entities of type '<[RelatedEntityName]>Entity' which are related to this entity via a relation of type '1:n'.
        /// If the EntityCollectionBase hasn't been fetched yet, the collection returned will be empty.</summary>
        public virtual <[RelatedEntityName]>DTO[] <[MappedFieldNameRelation]> { get; set; }<[EndIf]><[NextForeach]>
<[Foreach RelatedEntity ManyToMany CrLf]><[If Not MappedFieldRelationIsHidden]>
        /// <summary> Gets the EntityCollectionBase with the related entities of type '<[RelatedEntityName]>Entity' which are related to this entity via a relation of type 'm:n'.
        /// If the EntityCollectionBase hasn't been fetched yet, the collection returned will be empty.</summary>
        public virtual <[RelatedEntityName]>DTO[] <[MappedFieldNameRelation]> { get; set; }<[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)]
        public virtual <[RelatedEntityName]>DTO <[MappedFieldNameRelation]> { get; set; }<[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)]
        public virtual <[RelatedEntityName]>DTO <[MappedFieldNameRelation]> { get; set; }<[EndIf]><[NextForeach]>

        #endregion

        #region Custom DTO code
        <[ UserCodeRegion "CustomDTOCode" ]>
        // __LLBLGENPRO_USER_CODE_REGION_START CustomDTOCode
        // __LLBLGENPRO_USER_CODE_REGION_END
        <[ EndUserCodeRegion ]>
        #endregion
    }
}

File: dtoExtensions.template

using System;
using System.Collections.Generic;
using System.Linq;
using <[RootNamespace]>;
using <[RootNamespace]>.EntityClasses;
using <[RootNamespace]>.CollectionClasses;
using <[RootNamespace]>.DTOClasses;
using <[RootNamespace]>.HelperClasses;

namespace <[RootNamespace]>.DTOClasses
{
    /// <summary>
    /// Generates extension methods for converting Entities to DTOs
    /// This class is generated. Do not modify.
    /// </summary>
    public static <[If UsePartialClasses]>partial <[EndIf]>class Extensions
    {
<[If HasEntity]><[Foreach Entity]>
        /// <summary>Create a <[CurrentEntityName]> DTO from a <[CurrentEntityName]> entity</summary>
        /// <returns>The DTO created</returns>
        public static <[CurrentEntityName]>DTO ToDTO(this <[CurrentEntityName]>Entity entity)
        {
            <[CurrentEntityName]>DTO dto = null;
            if (entity != null)
                dto = new <[CurrentEntityName]>DTO(entity);
            return dto;
        }

        /// <summary>Create a list of <[CurrentEntityName]>DTO from a <[CurrentEntityName]>Collection</summary>
        /// <returns>The DTO list created</returns>
        public static List<<[CurrentEntityName]>DTO> ToDTOs(this <[CurrentEntityName]>Collection collection)
        {
            List<<[CurrentEntityName]>DTO> dtoList = new List<<[CurrentEntityName]>DTO>(collection.Count);
            foreach(<[CurrentEntityName]>Entity entity in collection)
                dtoList.Add(new <[CurrentEntityName]>DTO(entity));
            return dtoList;
        }

        /// <summary>Create a list of <[CurrentEntityName]>DTO from a List of <[CurrentEntityName]> entities</summary>
        /// <returns>The DTO list created</returns>
        public static List<<[CurrentEntityName]>DTO> ToDTOs(this List<<[CurrentEntityName]>Entity> entities)
        {
            return entities.ConvertAll<<[CurrentEntityName]>DTO>(e => new <[CurrentEntityName]>DTO(e));
        }

        /// <summary>From the queryable object, get a list of <[CurrentEntityName]>DTO</summary>
        /// <returns>The DTO list created</returns>
        public static List<<[CurrentEntityName]>DTO> ToDTOs(this IQueryable<<[CurrentEntityName]>Entity> queryableEntities)
        {
            return queryableEntities.ToList().ConvertAll<<[CurrentEntityName]>DTO>(e => new <[CurrentEntityName]>DTO(e));
        }

        /// <summary>From the queryable object, get a list of <[CurrentEntityName]>DTO</summary>
        /// <returns>The DTO list created</returns>
        public static <[CurrentEntityName]>DTO FirstDTO(this IQueryable<<[CurrentEntityName]>Entity> queryableEntities)
        {
            <[CurrentEntityName]>DTO dto = null;
            <[CurrentEntityName]>Entity firstEntity = queryableEntities.First();
            if (firstEntity != null)
                dto = new <[CurrentEntityName]>DTO(firstEntity);
            return dto;
        }
<[NextForeach]><[EndIf]>
        #region Custom code
        <[ UserCodeRegion "CustomDTOCode" ]>
        // __LLBLGENPRO_USER_CODE_REGION_START CustomDTOCode
        // __LLBLGENPRO_USER_CODE_REGION_END
        <[ EndUserCodeRegion ]>
        #endregion
    }
}

FILE: 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 3.5" />
    </supportedPlatforms>
    <supportedTemplateGroups>
    <templateGroup name="SelfServicing" />
    </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="DTOClasses" 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="DTOClasses" />
                <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="DTOClasses" />
                <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>
        <task name="DTOExtentionsCreator" assemblyFilename="SD.LLBLGen.Pro.TaskPerformers.dll" taskPerformerClass="SD.LLBLGen.Pro.TaskPerformers.CodeEmitter">
            <parameters>
                <parameter isOptional="false" name="destinationFolder" defaultValue="DTOClasses" />
                <parameter isOptional="false" name="failWhenExistent" defaultValue="false" />
                <parameter isOptional="false" name="filenameFormat" defaultValue="DTOExtensions.cs" />
                <parameter isOptional="false" name="templateID" defaultValue="SD_DTOExtentionsTemplate" />
                <parameter isOptional="false" name="emitType" defaultValue="generic" />
            </parameters>
        </task>
    </taskGroup>
</taskGroup>

Finally, add the following to the appropriate place in your *.preset file. This will define the code generation task above within your generation preset.

<taskGroupPreset name="DTO Templates">
  <taskGroupPreset name="Create Directories">
    <taskPreset name="DTODirectoryCreator" />
  </taskGroupPreset>
  <taskGroupPreset name="Create DTO Classes">
    <taskPreset name="DTOInterfaceCreator" />
    <taskPreset name="DTOEntityInterfaceCreator" />
    <taskPreset name="DTOBaseClassCreator" />
    <taskPreset name="DTOClassCreator" />
  <taskPreset name="DTOExtentionsCreator" />
  </taskGroupPreset>
</taskGroupPreset>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文