gpt4 book ai didi

.net - T4 用于在 LLBLGen Pro 实体上生成 POCO?

转载 作者:行者123 更新时间:2023-12-04 15:03:09 25 4
gpt4 key购买 nike

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

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

最佳答案

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

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

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

以下是您可以在 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>

关于.net - T4 用于在 LLBLGen Pro 实体上生成 POCO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7913266/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com