저는 EF를 통해 데이터베이스 액세스를 간소화하기 위해 LINQ 확장을 구축 중이며 해당 프로세스의 일부는 데이터 엔터티를 비즈니스 엔터티에 매핑하는 것입니다.정적 클래스에서 요청 별 변수를 사용하는 더 좋은 방법이 있습니까?
나는 포함 할 탐색 속성과 깊이를 결정하기 위해 Dictionary<string, int>
을 사용합니다.
예 :이 내 저장소에 나에게 접근 물건을 할 수 있습니다 및 서비스
public static class LinqExtensions
{
private static readonly Dictionary<string, int> Dictionary = new Dictionary<string, int>();
/// <summary>
/// Adds the navigational property identified by value to be included in the query and entity mapping, recursing a maximum of depth times.
/// </summary>
/// <param name="value">Navigational Property to add</param>
/// <param name="depth">Desired recursion depth</param>
public static TSource With<TSource>(this TSource source, string value, int depth = 0)
{
Dictionary.Add(value, depth);
return source;
}
/// <summary>
/// Clears the navigational property dictionary
/// </summary>
public static void Reset()
{
Dictionary.Clear();
}
/// <summary>
/// Builds and executes a query, dynamically including desired navigational properties in a asynchronous fashion.
/// The result is then mapped to the provided TResult business entity and returned as a list.
/// </summary>
/// <returns>Null or a list of mapped domain Entities</returns>
public static async Task<IEnumerable<TResult>> BuildQueryAsync<TSource, TResult>(this IQueryable<TSource> dbEntity) where TResult : class, new()
{
var query = dbEntity;
var localDictionary = new Dictionary<string, int>(Dictionary);
Reset();
foreach (var i in localDictionary)
{
query = query.Include(i.Key);
}
List<TSource> result = await (from entity in query select entity).ToListAsync();
return Equals(result, default(TSource)) ? null : result.Select(u => u.BuildEntity(new TResult(), localDictionary));
}
/// <summary>
/// Maps values from sourceEntity to targetEntity, recursing into properties defined in localDictionary.
/// </summary>
public static TTarget BuildEntity<TSource, TTarget>(this TSource sourceEntity, TTarget targetEntity, Dictionary<string, int> localDictionary)
{
return (TTarget)targetEntity.InjectFrom(new SinglePropertyDepthInjection(localDictionary), sourceEntity);
}
}
다음과 같이
public override async Task<IEnumerable<User>> GetAllAsync()
{
return await _context.Users.With("Messages", 1).With("Notifications", 2).BuildQueryAsync<Data.Entities.User, User>();
}
지금 내가 인해 정적 속성이이 가능하지 않을 것을 잘 알고 있어요 모든 요청에서 공유됩니다.
나는 easilly 메소드 매개 변수로 사전을 추가 할 수 있습니다 알고, 같은 그것을 해결 :
public override async Task<IEnumerable<User>> GetAllAsync()
{
var dict = new Dictionary<string, int>();
dict.Add("Messages", 1);
dict.Add("Notifications", 2);
return await _context.Users.BuildQueryAsync<Data.Entities.User, User>(dict);
}
그러나 아마 더 우아한 해결책이 있다면 나는의 일부로 유지 이상적으로, 궁금 해서요 LINQ 쿼리.
내가 알고있는 것은 HttpContext.Current
이지만 관련 메소드가 비동기 적이기 때문에 컨텍스트 스레드로 돌아가는 것이 얼마나 좋은 아이디어인지 잘 모르겠습니다.
아이디어가 있으십니까?