2012-05-11 3 views
1

C#을 사용하여 파일 다운로드 서비스를 작성하는 중 - 프로세스의 일부로 하나 이상의 데이터베이스에서 다운로드의 유효성을 검사하고 다운로드 세부 정보를 제공합니다.엔터티 및 변수 LINQ/쿼리 선택

유효성 검사 프로세스에서 호출 할 수있는 데이터베이스가 4 개 있습니다. 실제로 다운로드 할 서비스에 따라 다릅니다. 데이터베이스는 MSSQL 또는 MySQL 중 하나이며 복잡한 조인의 저장 프로 시저 또는 여러 조인이 포함 된 LINQ 쿼리를 사용할 수 있습니다. 모든 결과에는 동일한 열 정보가 포함됩니다.

Entity Framework 내에서 데이터베이스를 정의했으며 단일 인스턴스의 코드에 만족합니다. 다른 데이터베이스를 쿼리하면 동일한 작업을 수행하는 코드를 다시 작성하고 싶지 않습니다.

조건을 기반으로 사용할 엔터티와 쿼리를 지정하고 강력한 형식을 유지할 수있는 솔루션을 찾으려고 몇 시간 동안 검색했습니다. 이 같은 저장 프로 시저 쿼리

내가 사용하고 코드 : 나는 다음과 같은 코드를 사용 할 수있는 LINQ 쿼리에 대한

using (myEntity1 ctx = new myEntity1()) 
{ 
    var results = ctx.MyStoredProcedure(param1, param2); 

    foreach (var result in results) 
    { 
     // do stuff here 
    } 
} 

:

using (myEntity2 ctx = new myEntity2()) 
{ 
    var results = (from t in ctx.table select new { t.Col1, t.Col2,}); 

    foreach (var result in results) 
    { 
     // do stuff here 
    } 
} 

간단히 말해서, 나는 할 수 있도록하려면 여러 조건에 따라 엔티티와 쿼리를 지정합니다. 결과를 강력하게 입력하기를 바랍니다. 그것은 충분히 간단 해 보이지만 나는 그 답을 찾을 수 없습니다.

감사

크리스

+0

[이 (http://stackoverflow.com/questions/9762 : 아마도이 확장 방법을 사용하여, 원했던 808/change-fluent-api-mapping-dynamic)은 당신이 원하는 것과 조금 비슷해 보입니다. –

답변

0

내가 지금은 아마 그 POCO에 각 데이터 집합을로드 할 저장소를 사용하는 것이이 일을한다면 논스톱 학습의 또 다른 올해는 다음 실제로 하나의 내가으로이 포항 강판을 투사 한 후

public static class QueryableExtensions 
{ 

    public static ProjectionExpression<TSource> Project<TSource>(this IQueryable<TSource> source) 
    { 
     return new ProjectionExpression<TSource>(source); 
    } 

    public static string GetSQL<TSource>(this IQueryable<TSource> source) 
    { 
     return source.ToString(); 
    } 
} 

public class ProjectionExpression<TSource> 
{ 
    private static readonly Dictionary<string, Expression> ExpressionCache = new Dictionary<string, Expression>(); 

    private readonly IQueryable<TSource> _source; 

    public ProjectionExpression(IQueryable<TSource> source) 
    { 
     _source = source; 
    } 

    public IQueryable<TDest> To<TDest>() 
    { 
     var queryExpression = GetCachedExpression<TDest>() ?? BuildExpression<TDest>(); 

     return _source.Select(queryExpression); 
    } 

    private static Expression<Func<TSource, TDest>> GetCachedExpression<TDest>() 
    { 
     var key = GetCacheKey<TDest>(); 

     return ExpressionCache.ContainsKey(key) ? ExpressionCache[key] as Expression<Func<TSource, TDest>> : null; 
    } 

    private static Expression<Func<TSource, TDest>> BuildExpression<TDest>() 
    { 
     var sourceProperties = typeof(TSource).GetProperties(); 
     var destinationProperties = typeof(TDest).GetProperties().Where(dest => dest.CanWrite); 
     var parameterExpression = Expression.Parameter(typeof(TSource), "src"); 


     var bindings = destinationProperties 
          .Select(destinationProperty => BuildBinding(parameterExpression, destinationProperty, sourceProperties)) 
          .Where(binding => binding != null); 

     var expression = Expression.Lambda<Func<TSource, TDest>>(Expression.MemberInit(Expression.New(typeof(TDest)), bindings), parameterExpression); 

     var key = GetCacheKey<TDest>(); 

     ExpressionCache.Add(key, expression); 

     return expression; 
    } 

    private static MemberAssignment BuildBinding(Expression parameterExpression, MemberInfo destinationProperty, IEnumerable<PropertyInfo> sourceProperties) 
    { 
     var sourceProperty = sourceProperties.FirstOrDefault(src => src.Name == destinationProperty.Name); 

     if (sourceProperty != null) 
     { 
      return Expression.Bind(destinationProperty, Expression.Property(parameterExpression, sourceProperty)); 
     } 

     var propertyNames = SplitCamelCase(destinationProperty.Name); 

     if (propertyNames.Length == 2) 
     { 
      sourceProperty = sourceProperties.FirstOrDefault(src => src.Name == propertyNames[0]); 

      if (sourceProperty != null) 
      { 
       var sourceChildProperty = sourceProperty.PropertyType.GetProperties().FirstOrDefault(src => src.Name == propertyNames[1]); 

       if (sourceChildProperty != null) 
       { 
        return Expression.Bind(destinationProperty, Expression.Property(Expression.Property(parameterExpression, sourceProperty), sourceChildProperty)); 
       } 
      } 
     } 

     return null; 
    } 

    private static string GetCacheKey<TDest>() 
    { 
     return string.Concat(typeof(TSource).FullName, typeof(TDest).FullName); 
    } 

    private static string[] SplitCamelCase(string input) 
    { 
     return Regex.Replace(input, "([A-Z])", " $1", RegexOptions.Compiled).Trim().Split(' '); 
    } 
} 

http://www.devtrends.co.uk/blog/stop-using-automapper-in-your-data-access-code