2014-09-06 3 views
1

데이터베이스에 개체가 10 개 있습니다 (예 : 10 개). 이제 사용자가 그 중 일부 (1 또는 2 최대 10 개)를 선택한 다음 사용자의 선택에 따라 사용자가 선택한 특성을 가진 개체 목록을 만듭니다. 내가 생각하는 시나리오는 다음과 같습니다..net에서 사용자로부터 열을 가져 와서 데이터베이스에서 여러 열을 선택하는 방법

해당 속성의 열 (column)을 표시하는 확인란이있는 페이지는 사용자가 필요로하는 각각을 선택합니다.

그러나 여기 내 문제가 어떻게 선택한 확인란을 쿼리로 실행할 수 있습니까? 예를 들어 사용자가 col 1, col 2, col 6, col 10을 선택한 경우 사용자 선택을 담당하는 쿼리를 작성하려면 어떻게해야합니까?

var file2 = file.Select(f => new { "attributes selected by user" }).OrderBy(what user wants) 
+0

죄송합니다. 성취하려는 것을 정말로 이해하지 못합니다. – Pleun

+0

linq 쿼리를 데이터베이스 호출로 변환하는 데 사용하고있는 것은 무엇입니까? Entity Framework 또는 구식 linq-to-sql? – Rhumborl

+0

@ Plleun 나는 그것을 분명히 설명한다고 생각한다. 10 cols를 가진 데이터베이스의 테이블을 상상해 보라. 사용자가 해당 테이블의 모든 행을 인쇄하려고하지만 모든 열을 인쇄하지 않고 그 중 일부를 인쇄하려고합니다. 인쇄하려는 열을 사용자가 선택하도록합니다. 을 선택하는 코드를 작성하는 방법을 모르겠습니다. 사용자가 선택한 확인란 (사용자가 선택한 확인란) – user3915488

답변

0

들이 Nuget에 System.Linq.Dynamic 라이브러리

을 갈 수있는 방법입니다
[TestMethod] 
public void StringyAndDangerous() 
{ 
    var fakePersonDbSet = new List<Person> { new Person() { FirstName = "Some", LastName = "Guy" } }.AsQueryable(); 
    var attributes = new string[] { "FirstName", "LastName" }; 
    var selectedFields = String.Join(",", attributes); 
    var exprssion = string.Format("new ({0})", selectedFields); 
    var result = fakePersonDbSet.Select(exprssion, attributes).Cast<dynamic>().First(); 
} 

하지만 유형 안전이 느슨하고 컴파일되지 않습니다. ime 점검. '당신은 더 나은 당신이 코드는 경향이 덜 오류가있을 것입니다 필요하지 않은 데이터베이스에서 필드를 당겨과 반사를 사용하여 모두 공격하지만 성능 할게요

[TestMethod] 
public void SlowerButSafer() 
{ 
    var fakePersonDbSet = new List<Person> { new Person() { FirstName = "Some", LastName = "Guy" } }.AsQueryable(); 
    var attributes = new string[] { "FirstName", "LastName" }; 
    var personPropertylist = CovertToKeyValuePair(fakePersonDbSet.First()) 
     .Where(c=> attributes.Contains(c.Key)) 
     .ToArray();    
} 

private IEnumerable<KeyValuePair<string, object>> CovertToKeyValuePair<T>(T @object) 
{ 
    var result = new List<KeyValuePair<string, object>>(); 
    var properties = typeof (T).GetProperties(); 
    foreach (var property in properties) 
    { 
     result.Add(new KeyValuePair<string, object>(property.Name, property.GetValue(@object, null))); 
    } 
    return result; 
} 

다른 접근 방식을 복용 할 수 있으며 당신이 원 존재하지 않는 열을 선택하려고 시도하면 오류가 발생합니다.

0

사용 DynamicLinq : 예 나는 이것의 의미있는 문구를 싶어요. (link)

확장 방법 :

public static T GetValue<T>(this DynamicClass dynamicObject, string propName) 
{ 
    if (dynamicObject == null) 
    { 
     throw new ArgumentNullException("dynamicObject"); 
    } 

    var type = dynamicObject.GetType(); 
    var props = type.GetProperties(BindingFlags.Public 
           | BindingFlags.Instance 
           | BindingFlags.FlattenHierarchy); 
    var prop = props.FirstOrDefault(property => property.Name == propName); 
    if (prop == null) 
    { 
     throw new InvalidOperationException("Specified property doesn't exist."); 
    } 

    return (T)prop.GetValue(dynamicObject, null); 
} 

public static string ToDynamicSelector(this IList<string> propNames) 
{ 
    if (!propNames.Any()) 
     throw new ArgumentException("You need supply at least one property"); 
    return string.Format("new({0})", string.Join(",", propNames)); 
} 

용도 :

using System.Linq.Dynamic; 

// .. 

var columns = new[] { "col1", "col2", etc }; 

var result = context.Files.OrderBy(file => file.Id) 
          .Select(columns.ToDynamicSelector()) 
          .Cast<DynamicClass>.ToList(); 

결과 열이 선택된 특성을 포함 wchich DynamiClass 인스턴스 소식 모음 것이다.

DynamicClass에서 하나의 속성을 가져올 수 :

var columnValue = result.First().GetValue<string>("col1"); 

IEnumerable에서 값을 얻고 싶다면 :

var list = new List<File> { File1, File2, etc.. }; 

var result = list.AsQueryable().Select(/* the same as above */); 
관련 문제