Stored procedures 实体框架代码优先-配置SqlQuery的映射
我使用EntityFramework5(采用代码优先的方法)从遗留存储过程中用参数填充我的一个类,这很好(详细信息如下)。 我的问题是,我想将列的名称映射到具有不同名称的属性(我不喜欢来自Erp的名称)。 我尝试使用配置类(就像我映射到视图或表时所做的那样)为具有不同名称的属性指定列名,下面是我的结果:Stored procedures 实体框架代码优先-配置SqlQuery的映射,stored-procedures,configuration,ef-code-first,mapping,entity-framework-5,Stored Procedures,Configuration,Ef Code First,Mapping,Entity Framework 5,我使用EntityFramework5(采用代码优先的方法)从遗留存储过程中用参数填充我的一个类,这很好(详细信息如下)。 我的问题是,我想将列的名称映射到具有不同名称的属性(我不喜欢来自Erp的名称)。 我尝试使用配置类(就像我映射到视图或表时所做的那样)为具有不同名称的属性指定列名,下面是我的结果: 如果我不使用配置类(我不将其添加到DbContext的OnModelCreating方法中),那么EF可以工作,但只加载与列名称完全匹配的属性(在本例中,这是我所期望的);其他财产无效 如果我
- 如果我不使用配置类(我不将其添加到DbContext的OnModelCreating方法中),那么EF可以工作,但只加载与列名称完全匹配的属性(在本例中,这是我所期望的);其他财产无效李>
- 如果我使用配置类(将其添加到DbContext的OnModelCreating方法中的modelBuilder中),则EF会引发一个异常,指出“数据读取器与指定的“…项”不兼容。“Description”类型的成员在数据读取器中没有同名的对应列”,这听起来很奇怪,因为在配置中我指定属性描述映射到列itemsdescription
public class Item
{
public String Id { get; set; }
public String Description { get; set; }
}
配置类:
public class ItemConfiguration : EntityTypeConfiguration<Item>
{
public ItemConfiguration()
{
HasKey(x => new { x.Id });
Property(x => x.Id).HasColumnName("Code");
Property(x => x.Description).HasColumnName("ItemDescription");
}
}
谢谢大家! 我在这里发现:
“SqlQuery方法的设计不考虑任何映射…”
他们还说:“我们同意,让SqlQuery尊重列属性的选项是有用的,因此我们将继续讨论这个问题,并将其放在我们的待办事项列表中,以备将来考虑。”因此,如果您有同样的问题,请投票:-)同时,您可以使用此方法。 很少有测试(因为它适用于我的类),但如果需要,也不难修复。。。 它需要一个上下文(检索映射的自定义类型),同时需要一个不同的连接来运行datareader 用法:
List students=Mapper.Map(context,(newschoolcontext()).Database.Connection,“从学生中选择*)
公共静态类映射器
{
///
///将查询结果映射到实体中。
///
///
///上下文。
///运行查询的连接。必须与上下文上的连接不同。
///SQL查询。
///实体列表
///
///上下文
///或
///查询连接
///或
///sqlQuery
///
公共静态列表映射(DbContext上下文、DbConnection queryConnection、string sqlQuery),其中T:new()
{
if(上下文==null)
抛出新的ArgumentNullException(“上下文”);
if(queryConnection==null)
抛出新ArgumentNullException(“queryConnection”);
if(sqlQuery==null)
抛出新ArgumentNullException(“sqlQuery”);
var connectionState=queryConnection.State;
if(connectionState!=connectionState.Open)
queryConnection.Open();
DbCommand=queryConnection.CreateCommand();
command.CommandText=sqlQuery;
DbDataReader=command.ExecuteReader();
列表实体=新列表();
while(reader.Read())
{
添加(InternalMap(上下文,读取器));
}
if(connectionState!=connectionState.Open)
queryConnection.Close();
返回实体;
}
私有静态T InternalMap(DbContext上下文,DbDataReader reader),其中T:new()
{
T entityObject=new T();
InternalMapEntity(上下文、读取器、entityObject);
返回实体对象;
}
私有静态void InternalMapEntity(DbContext上下文、DbDataReader读取器、对象entityObject)
{
ObjectContext=((IOObjectContextAdapter)context).ObjectContext;
var metadataWorkspace=((EntityConnection)objectContext.Connection).GetMetadataWorkspace();
IEnumerable entitySetMappingCollection=metadataWorkspace.GetItems(DataSpace.CSSpace).Single().EntitySetMappings;
IEnumerable associationSetMappingCollection=metadataWorkspace.GetItems(DataSpace.CSSpace).Single().AssociationSetMappings;
var entitySetMappings=entitySetMappingCollection.First(o=>o.EntityTypeMappings.Select(e=>e.EntityType.Name)。包含(entityObject.GetType().Name));
var entityTypeMapping=entitySetMappings.EntityTypeMappings[0];
string tableName=entityTypeMapping.EntitySetMapping.EntitySet.Name;
Console.WriteLine(表名);
MappingFragment MappingFragment=entityTypeMapping.Fragments[0];
foreach(属性映射映射mappingFragment.PropertyMappings中的属性映射)
{
对象值=Convert.ChangeType(读卡器[((ScalarPropertyMapping)propertyMapping).Column.Name],propertyMapping.Property.PrimitiveType.ClrEquivalentType);
entityObject.GetType().GetProperty(propertyMapping.Property.Name).SetValue(entityObject,value,null);
WriteLine({0}{1}{2}),propertyMapping.Property.Name,((ScalarPropertyMapping)propertyMapping.Column,value);
}
foreach(entityTypeMapping.EntityType.NavigationProperties中的var navigationProperty)
{
PropertyInfo PropertyInfo=entityObject.GetType().GetProperty(navigationProperty.Name);
AssociationSetMapping AssociationSetMapping=associationSetMappingCollection.First(a=>a.AssociationSet.ElementType.FullName==navigationProperty.RelationshipType.FullName);
//associationSetMapping.AssociationTypeMapping.MappingFragment.PropertyMappings包含两个元素,一个用于直接关系,另一个用于反向关系
EndPropertyMapping propertyMappings=associationSetMapping.As
var par = new SqlParameter();
par.ParameterName = "@my_par";
par.Direction = ParameterDirection.Input;
par.SqlDbType = SqlDbType.VarChar;
par.Size = 20;
par.Value = ...;
var data = _context.Database.SqlQuery<Item>("exec spItem @my_par", par);
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new ItemConfiguration());
}
public static class Mapper
{
/// <summary>
/// Maps the result of a query into entities.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="context">The context.</param>
/// <param name="queryConnection">The connection to run the query. Must be different from the one on the context.</param>
/// <param name="sqlQuery">The SQL query.</param>
/// <returns>An entity list</returns>
/// <exception cref="System.ArgumentNullException">
/// context
/// or
/// queryConnection
/// or
/// sqlQuery
/// </exception>
public static List<T> Map<T>(DbContext context, DbConnection queryConnection, string sqlQuery) where T:new()
{
if (context == null)
throw new ArgumentNullException("context");
if (queryConnection == null)
throw new ArgumentNullException("queryConnection");
if (sqlQuery == null)
throw new ArgumentNullException("sqlQuery");
var connectionState = queryConnection.State;
if (connectionState != ConnectionState.Open)
queryConnection.Open();
DbCommand command = queryConnection.CreateCommand();
command.CommandText = sqlQuery;
DbDataReader reader = command.ExecuteReader();
List<T> entities = new List<T>();
while (reader.Read())
{
entities.Add(InternalMap<T>(context, reader));
}
if (connectionState != ConnectionState.Open)
queryConnection.Close();
return entities;
}
private static T InternalMap<T>(DbContext context, DbDataReader reader) where T: new()
{
T entityObject = new T();
InternalMapEntity(context, reader, entityObject);
return entityObject;
}
private static void InternalMapEntity(DbContext context, DbDataReader reader, object entityObject)
{
ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
var metadataWorkspace = ((EntityConnection)objectContext.Connection).GetMetadataWorkspace();
IEnumerable<EntitySetMapping> entitySetMappingCollection = metadataWorkspace.GetItems<EntityContainerMapping>(DataSpace.CSSpace).Single().EntitySetMappings;
IEnumerable<AssociationSetMapping> associationSetMappingCollection = metadataWorkspace.GetItems<EntityContainerMapping>(DataSpace.CSSpace).Single().AssociationSetMappings;
var entitySetMappings = entitySetMappingCollection.First(o => o.EntityTypeMappings.Select(e => e.EntityType.Name).Contains(entityObject.GetType().Name));
var entityTypeMapping = entitySetMappings.EntityTypeMappings[0];
string tableName = entityTypeMapping.EntitySetMapping.EntitySet.Name;
Console.WriteLine(tableName);
MappingFragment mappingFragment = entityTypeMapping.Fragments[0];
foreach (PropertyMapping propertyMapping in mappingFragment.PropertyMappings)
{
object value = Convert.ChangeType(reader[((ScalarPropertyMapping) propertyMapping).Column.Name], propertyMapping.Property.PrimitiveType.ClrEquivalentType);
entityObject.GetType().GetProperty(propertyMapping.Property.Name).SetValue(entityObject, value, null);
Console.WriteLine("{0} {1} {2}", propertyMapping.Property.Name, ((ScalarPropertyMapping)propertyMapping).Column, value);
}
foreach (var navigationProperty in entityTypeMapping.EntityType.NavigationProperties)
{
PropertyInfo propertyInfo = entityObject.GetType().GetProperty(navigationProperty.Name);
AssociationSetMapping associationSetMapping = associationSetMappingCollection.First(a => a.AssociationSet.ElementType.FullName == navigationProperty.RelationshipType.FullName);
// associationSetMapping.AssociationTypeMapping.MappingFragment.PropertyMappings contains two elements one for direct and one for inverse relationship
EndPropertyMapping propertyMappings = associationSetMapping.AssociationTypeMapping.MappingFragment.PropertyMappings.Cast<EndPropertyMapping>().First(p => p.AssociationEnd.Name.EndsWith("_Target"));
object[] key = propertyMappings.PropertyMappings.Select(c => reader[c.Column.Name]).ToArray();
object value = context.Set(propertyInfo.PropertyType).Find(key);
propertyInfo.SetValue(entityObject, value, null);
}
}
}
public static class DbSetExtensions
{
public static DbSqlQuery<TEntity> SqlColumnQuery<TEntity>(this DbSet<TEntity> dbSet, string sqlQuery)
where TEntity : class
{
var context = GetContext(dbSet);
return dbSet.SqlQuery(MapQueryToColumns(sqlQuery, context, typeof(TEntity)));
}
public static DbContext GetContext<TEntity>(this DbSet<TEntity> dbSet)
where TEntity : class
{
object internalSet = dbSet
.GetType()
.GetField("_internalSet", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(dbSet);
object internalContext = internalSet
.GetType()
.BaseType
.GetField("_internalContext", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(internalSet);
return (DbContext)internalContext
.GetType()
.GetProperty("Owner", BindingFlags.Instance | BindingFlags.Public)
.GetValue(internalContext, null);
}
private static string MapQueryToColumns(string sqlQuery , DbContext context, Type entityType)
{
ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
var metadataWorkspace = ((EntityConnection)objectContext.Connection).GetMetadataWorkspace();
IEnumerable<EntitySetMapping> entitySetMappingCollection = metadataWorkspace.GetItems<EntityContainerMapping>(DataSpace.CSSpace).Single().EntitySetMappings;
//IEnumerable<AssociationSetMapping> associationSetMappingCollection = metadataWorkspace.GetItems<EntityContainerMapping>(DataSpace.CSSpace).Single().AssociationSetMappings;
var entitySetMappings = entitySetMappingCollection.First(o => o.EntityTypeMappings.Select(e => e.EntityType.Name).Contains(entityType.Name));
var entityTypeMapping = entitySetMappings.EntityTypeMappings[0];
string tableName = entityTypeMapping.EntitySetMapping.EntitySet.Name;
MappingFragment mappingFragment = entityTypeMapping.Fragments[0];
List<string> propertyMappings = new List<string>();
foreach (PropertyMapping propertyMapping in mappingFragment.PropertyMappings)
{
propertyMappings.Add(string.Format("{0} {1}", ((ScalarPropertyMapping)propertyMapping).Column.Name, propertyMapping.Property.Name));
}
var joinFields = string.Join(",",propertyMappings.ToArray());
return string.Format("SELECT {0} FROM ({1})", joinFields, sqlQuery);
}
}
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Data;
using System.Data.Common;
using System.Data.Entity.Core.EntityClient;
using System.Data.Entity.Core.Mapping;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
public abstract partial class BaseService
where TEntity : EntityDefault
{
private const int MAX_ITEMS_PER_PREDICATE = 500;
///
/// Lista imutável contendo todos os predicates, por tipo da entidade, a serem buscados no banco de dados.
///
private ImmutableDictionary> Predicates { get; set; }
private ImmutableDictionary PredicatesCount { get; set; }
private ImmutableDictionary> LoadedPredicates { get; set; }
///
/// Lista imutável contendo as entidades, que são propriedades de navegação, já buscadas no banco de dados.
///
private ImmutableList NavigationEntities { get; set; }
///
/// Lista imutável contendo todas as propriedades de navegação
///
private ImmutableList NavigationProperties { get; set; }
///
/// Maps the result of a query into entities.
///
///
/// The SQL query.
/// List of parameters to be passed to the procedure
///
/// It might return null when query is null or empty.
/// An entity list
///
/// context
/// or
/// queryConnection
/// or
/// sqlQuery
///
public List SqlQuery(string query, Dictionary parameters, params KeyValuePair[] options) where T : EntityDefault
{
DbConnection queryConnection = null;
try
{
InitOrResetSqlQueryVariables();
if (query.HasntValue())
{
throw new ArgumentNullException(nameof(query));
}
queryConnection = Db.Database.Connection;
var connectionState = queryConnection.State;
if (connectionState != ConnectionState.Open)
{
queryConnection.Open();
}
var command = queryConnection.CreateCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = query;
if (parameters != null)
{
command.AddParameters(parameters);
}
var reader = command.ExecuteReader();
var entities = new List();
while (reader.Read())
{
entities.Add(MapEntity(reader));
}
LoadNavigationProperties(entities, options);
return entities;
}
finally
{
InitOrResetSqlQueryVariables();
if (Db.BaseDb.AutoCloseConnection && queryConnection != null)
{
if (queryConnection.State != ConnectionState.Closed)
{
queryConnection.Close();
}
queryConnection.Dispose();
}
}
}
public List SqlQuery(string query, List parameters, params KeyValuePair[] options) where T : EntityDefault
{
DbConnection queryConnection = null;
try
{
InitOrResetSqlQueryVariables();
if (query.HasntValue())
{
throw new ArgumentNullException(nameof(query));
}
queryConnection = Db.Database.Connection;
var connectionState = queryConnection.State;
if (connectionState != ConnectionState.Open)
{
queryConnection.Open();
}
var command = queryConnection.CreateCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = query;
if (parameters != null)
{
command.Parameters.AddRange(parameters.ToArray());
}
var reader = command.ExecuteReader();
var entities = new List();
while (reader.Read())
{
entities.Add(MapEntity(reader));
}
LoadNavigationProperties(entities, options);
return entities;
}
finally
{
InitOrResetSqlQueryVariables();
if (Db.BaseDb.AutoCloseConnection && queryConnection != null)
{
if (queryConnection.State != ConnectionState.Closed)
{
queryConnection.Close();
}
queryConnection.Dispose();
}
}
}
private T MapEntity(IDataRecord reader)
{
var entityObject = Activator.CreateInstance();
MapEntity(reader, entityObject);
return entityObject;
}
private void MapEntity(IDataRecord reader, object entityObject)
{
var objectContext = ((IObjectContextAdapter)Db).ObjectContext;
var metadataWorkspace = ((EntityConnection)objectContext.Connection).GetMetadataWorkspace();
var entitySetMappingCollection =
metadataWorkspace.GetItems(DataSpace.CSSpace).Single().EntitySetMappings;
var associationSetMappingCollection =
metadataWorkspace.GetItems(DataSpace.CSSpace)
.Single()
.AssociationSetMappings.ToList();
var entitySetMappings =
entitySetMappingCollection.First(
o => o.EntityTypeMappings.Select(e => e.EntityType.Name).Contains(entityObject.GetType().Name));
var entityTypeMapping = entitySetMappings.EntityTypeMappings[0];
var tableName = entityTypeMapping.EntitySetMapping.EntitySet.Name;
Debug.WriteLine(tableName);
var mappingFragment = entityTypeMapping.Fragments[0];
// Maps the properties of the entity itself
foreach (var propertyMapping in mappingFragment.PropertyMappings)
{
var valueBeforCasting = reader[((ScalarPropertyMapping)propertyMapping).Column.Name];
var value = valueBeforCasting is DBNull
? null
: propertyMapping.Property.IsEnumType
? Convert.ChangeType(valueBeforCasting,
typeof(int))
: Convert.ChangeType(valueBeforCasting,
propertyMapping.Property.PrimitiveType.ClrEquivalentType);
entityObject.GetType()
.GetProperty(propertyMapping.Property.Name)
.SetValue(entityObject, value, null);
Debug.WriteLine("{0} {1} {2}", propertyMapping.Property.Name,
((ScalarPropertyMapping)propertyMapping).Column, value);
}
if (NavigationProperties.Count == 0)
{
NavigationProperties = NavigationProperties.AddRange(entityTypeMapping.EntityType.NavigationProperties);
}
// Maps the associated navigational properties
foreach (var navigationProperty in NavigationProperties)
{
var propertyInfo = entityObject.GetType().GetProperty(navigationProperty.Name);
// TODO: Por Marco em 26/11/2015
/*
* Verificar em QueryOptions (que neste momento não é passada para esta rotina) se foi solicitado Eager Loading desta navigationProperty.
* Caso negativo executar um "continue;"
*
* Isso ajudará a evitar consultas desnecessárias ao banco de dados.
*/
var propertyType = propertyInfo.PropertyType;
var associationSetMapping =
associationSetMappingCollection.First(
a => a.AssociationSet.ElementType.FullName == navigationProperty.RelationshipType.FullName);
// associationSetMapping.AssociationTypeMapping.MappingFragment.PropertyMappings contains two elements one for direct and one for inverse relationship
var propertyMappings =
associationSetMapping.AssociationTypeMapping.MappingFragment.PropertyMappings
.Cast().First(p => p.AssociationEnd.Name.EndsWith("_Target"));
var key = propertyMappings.PropertyMappings.Select(c => reader[c.Column.Name]).ToArray();
if (!key.Any() || key[0] is DBNull)
continue;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Monta o PredicateBuilder que será utilizado para trazer todas as entidades associadas solicitadas
var outerPredicate = typeof(PredicateBuilder).InvokeStaticGenericMethod(propertyType, "False");
if (!Predicates.ContainsKey(propertyType))
{
var predicatesList = new List { outerPredicate };
Predicates = Predicates.Add(propertyType, predicatesList);
LoadedPredicates = LoadedPredicates.Add(propertyType, new List());
PredicatesCount = PredicatesCount.Add(propertyType, 0);
}
var loadedPredicates = LoadedPredicates[propertyType];
if (loadedPredicates.All(p => p != Convert.ToInt32(key[0])))
{
loadedPredicates.Add(Convert.ToInt32(key[0]));
BuildPredicate(propertyType, outerPredicate, Convert.ToInt32(key[0]));
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Seta o Id como helper para a rotina LoadAssociatedEntities
var value = Activator.CreateInstance(propertyType);
var idProperty = propertyType.GetProperty("Id");
idProperty.SetValue(value, key[0]);
propertyInfo.SetValue(entityObject, value, null);
}
}
private void BuildPredicate(Type propertyType, object outerPredicate, int pkValue)
{
var parameter = Expression.Parameter(propertyType, "p");
var property = Expression.Property(parameter, "Id");
var valueToCompare = Expression.Constant(pkValue);
var equalsExpression = Expression.Equal(property, valueToCompare);
var funcType = typeof(Func).MakeGenericType(propertyType, typeof(bool));
var lambdaExpression = Expression.Lambda(funcType, equalsExpression, parameter);
var predicateList = Predicates[propertyType];
var predicatesCount = PredicatesCount[propertyType];
if (predicatesCount % MAX_ITEMS_PER_PREDICATE == 0)
{
predicateList.Add(outerPredicate);
}
var predicate = predicateList.Last();
predicate = typeof(PredicateBuilder).InvokeStaticGenericMethod(propertyType, "Or", predicate, lambdaExpression);
predicateList[predicateList.Count - 1] = predicate;
predicatesCount++;
PredicatesCount = PredicatesCount.Replace(propertyType, predicatesCount);
}
///
/// Carrega as entidades associadas solicitadas via EagerLoading
///
/// Tipo específico de EntityDefault
/// Lista de entidades que irão ter as entidades associadas carregadas
/// Array de Eager Loadings a serem carregados
private void LoadNavigationProperties(IReadOnlyList entities,
params KeyValuePair[] eagerLoadings) where T : EntityDefault
{
foreach (var predicateItem in Predicates)
{
var newEagerLoadings = new List>();
var newOptions =
eagerLoadings
.Where(p => p.Key == QueryOptions.DefineInclude || p.Key == QueryOptions.DefineIncludes)
.ToList();
var predicateWhere = predicateItem;
// Loop em todas as propriedades de navegação de T que sejam do mesmo tipo do predicate.Key
// Esse loop terá alimentado newEagerLoadings com os valores adequados.
foreach (
var navigationProperty in
NavigationProperties.Where(
p => entities[0].GetType().GetProperty(p.Name).PropertyType == predicateWhere.Key))
{
newOptions =
newOptions.Where(p => p.Value.ToString().StartsWith(navigationProperty.Name)).ToList();
if (!newOptions.Any())
continue;
// ReSharper disable once LoopCanBeConvertedToQuery
foreach (var option in newOptions)
{
if (!option.Value.ToString().Contains("."))
{
continue;
}
var newOption = Pairing.Of(option.Key,
option.Value.ToString()
.RemovePrefix(navigationProperty.Name + ".")
.RemovePrefix(navigationProperty.Name));
if (newOption.HasntValue() || newOption.Value.ToString().IsNullOrEmpty())
{
continue;
}
newEagerLoadings.Add(newOption);
}
}
var predicateList = predicateItem.Value;
var funcType = predicateItem.Value.First().InvokeMethod("Compile", true).GetType();
var newInstanceOfThis = GetInstanceOfService(funcType.GenericTypeArguments[0], Db);
foreach (var predicate in predicateList)
{
// A fim de tentar evitar bugs de StackOverflow
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
var expandedPredicate = typeof(Extensions).InvokeStaticGenericMethod(funcType, "Expand", predicate);
var selectResponse = (IEnumerable)newInstanceOfThis.InvokeGenericMethod(predicateItem.Key,
"Many", expandedPredicate, newEagerLoadings.ToArray());
var listOfItems = selectResponse.ToList();
// Obtém o retorno
// Executa a query e preenche PredicateEntities
NavigationEntities = NavigationEntities.AddRange(listOfItems);
}
}
// Loop nas entidades para atribuir as entidades associadas
foreach (var entity in entities)
{
// Loop nas propriedades de navegação, para listar as entidades associadas
foreach (var navigationProperty in NavigationProperties)
{
// navigationProperty é a entidade associada que será atribuída a entity
var propertyInfo = entity.GetType().GetProperty(navigationProperty.Name);
var propertyType = propertyInfo.PropertyType;
var propertyValue = propertyInfo.GetValue(entity);
if (propertyValue == null)
{
continue;
}
var idPropertyInfo = propertyType.GetProperty("Id");
var keyValue = idPropertyInfo.GetValue(propertyValue);
if (keyValue == null)
{
continue;
}
var key = Convert.ToInt32(keyValue);
// Pega a lista de entidades associadas que sejam do mesmo tipo da propriedade de navegação
var associatedEntitiesOfSameType = NavigationEntities.Where(p => p.GetType() == propertyType)
.ToList();
if (!associatedEntitiesOfSameType.Any())
{
// O usuário não solicitou EagerLoading dessa navigationProperty
continue;
}
// Busca a entidade associada pelo Id, alimentado em "InternalMapEntity"
var associatedEntityInstance =
associatedEntitiesOfSameType.FirstOrDefault(
p => Convert.ToInt32(idPropertyInfo.GetValue(p)) == key);
if (associatedEntityInstance == null)
continue; // Não localizada. Removida do banco de dados?
// Atribui a entidade associada a "entity"
propertyInfo.SetValue(entity, associatedEntityInstance);
}
}
}
}