4

EF + RIA를 사용하고 있으며 불행하게도 관련 엔터티별로 정렬 문제를 해결합니다.ESQL을 LINQ to Entities로 변환. 관련 엔터티별로 정렬

<Attribute>: 
    int Id; 
    decimal DecimalColumn; 
    string StringColumn; 
    int EntityId; 
    int AttributeTypeId; 

<SomeEntity>: 
    int Id; 
    string Name; 

(정렬)이 물건을 다시 쓸 수있는 방법을 사용하여, 거기 :

var queryESQL = string.Format(
@" select VALUE ent from SomeEntities as ent 
    join Attributes as ea ON ea.EntityId = ent.Id 
    where ea.AttributeTypeId = @typeId 
    order by ea.{0} {1}", columnName, descending ? "desc" : "asc"); 

var query = ObjectContext.CreateQuery<SomeEntity>(queryESQL, new ObjectParameter("typeId", attributeTypeId));               

테이블 구조 다음 한 : 같은 목적을 위해 는 (발견에만이 솔루션) 내가 구현 ESQL 쿼리가 엔티티에 LINQ 접근?

답변

2

내 시도입니다. 작동하지 않을 수도 있습니다. 동적 컬럼 이름을 얻는 방법에 대해 더 생각해 봐야겠다. 편집 : 주문 열에 문자열을 사용할 수 있습니다.

int typeId = 1115; 
bool orderAscending = false; 
string columnName = "StringColumn"; 
var query = from ent in SomeEntities 
join ea in Attributes on ea.EntityId = ent.Id 
where ea.AttributeTypeId = typeId; 

if(orderAscending) 
{ 
    query = query.OrderBy(ea => columnName).Select(ea => ea.Value); 
} 
else 
{ 
    query = query.OrderByDescending(ea => columnName).Select(ea => ea.Value); 
} 

var results = query.ToList(); // LINQ가 지연된 실행을하기 때문에 toList 또는 enumerate를 호출하여 쿼리를 실행합니다.

편집 : 선택 중단 후 주문하는 것은 주문하는 것으로 생각됩니다. 나는 select 문을 order 후에 옮겼다. 나는 또한 "query ="를 추가했지만 필요한지 확실하지 않습니다. 나는 이것을 지금 시험 할 방법이 없다.

편집 3 : 오늘 나는 LINQPad을 발사하고 내가 가지고 있었던 것에 약간 조정을했다. 필자는 EF 사용에 대한 코드 첫 번째 접근 방식으로 데이터를 모델링했으며, 사용자가 가지고있는 것과 거의 비슷해야합니다. 이 방법은 단순히 속성 목록을 얻으려는 경우에 효과적입니다 (그렇지 않은 경우). 이 문제를 해결하기 위해 MyAttribute 클래스에 Entity 속성을 추가했습니다. 이 코드는 LINQPAD에서 작동합니다.

void Main() 
{ 
    // add test entities as needed. I'm assuming you have an Attibutes collection on your Entity based on your tables. 
    List<MyEntity> SomeEntities = new List<MyEntity>(); 
    MyEntity e1 = new MyEntity(); 
    MyAttribute a1 = new MyAttribute(){ StringColumn="One", DecimalColumn=25.6M, Id=1, EntityId=1, AttributeTypeId = 1, Entity=e1 }; 
    e1.Attributes.Add(a1); 
    e1.Id = 1; 
    e1.Name= "E1"; 
    SomeEntities.Add(e1); 

    MyEntity e2 = new MyEntity(); 
    MyAttribute a2 = new MyAttribute(){ StringColumn="Two", DecimalColumn=198.7M, Id=2, EntityId=2, AttributeTypeId = 1, Entity=e2 }; 
    e2.Attributes.Add(a2); 
    e2.Id = 2; 
    e2.Name = "E2"; 
    SomeEntities.Add(e2); 

    MyEntity e3 = new MyEntity(); 
    MyAttribute a3 = new MyAttribute(){ StringColumn="Three", DecimalColumn=65.9M, Id=3, EntityId=3, AttributeTypeId = 1, Entity=e3 }; 
    e3.Attributes.Add(a3); 
    e3.Id = 3; 
    e3.Name = "E3"; 
    SomeEntities.Add(e3); 

    List<MyAttribute> attributes = new List<MyAttribute>(); 
    attributes.Add(a1); 
    attributes.Add(a2); 
    attributes.Add(a3); 

    int typeId = 1; 
    bool orderAscending = true; 
    string columnName = "StringColumn"; 
    var query = (from ent in SomeEntities 
    where ent.Attributes.Any(a => a.AttributeTypeId == typeId) 
    select ent.Attributes).SelectMany(a => a).AsQueryable(); 
    query.Dump("Pre Ordering"); 
    if(orderAscending) 
    { 
     // query = is needed 
     query = query.OrderBy(att => MyEntity.GetPropertyValue(att, columnName)); 
    } 
    else 
    { 
     query = query.OrderByDescending(att => MyEntity.GetPropertyValue(att, columnName)); 
    } 

    // returns a list of MyAttributes. If you need to get a list of attributes, add a MyEntity property to the MyAttribute class and populate it 
    var results = query.Select(att => att.Entity).ToList().Dump(); 
} 

// Define other methods and classes here 
} 
    class MyAttribute 
    { 
    public int Id { get; set; } 
    public decimal DecimalColumn { get; set; } 
    public string StringColumn { get; set; } 
    public int EntityId { get; set; } 
    public int AttributeTypeId { get; set; } 
    // having this property will require an Include in EF to return it then query, which is less effecient than the original ObjectQuery< for the question 
    public MyEntity Entity { get; set; } 

    } 
    class MyEntity 
    { 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public ICollection<MyAttribute> Attributes { get; set; } 
    public MyEntity() 
    { 
    this.Attributes = new List<MyAttribute>(); 
    } 

    // this could have been on any class, I stuck it here for ease of use in LINQPad 
    // caution reflection may be slow 
    public static object GetPropertyValue(object obj, string property) 
{ 
// from Kjetil Watnedal on http://stackoverflow.com/questions/41244/dynamic-linq-orderby 
    System.Reflection.PropertyInfo propertyInfo=obj.GetType().GetProperty(property); 
    return propertyInfo.GetValue(obj, null); 
} 
+0

나는 shure가 아니지만 'OrderBy' 컨텍스트 내에'Column1' 속성이 없습니다. 'ea'는'SomeEntity'를 나타냅니다. –

+0

나는 내 대답을 마치면서 바로 떠나야했다. Column1은 그 당시 장소 홀더였습니다. 동적으로 쿼리를 정렬하는 방법을 보여주기 위해 내 대답을 업데이트했습니다. – Aligned

+0

여기서 중요한 문제는'Attributes'로 정렬하는 것입니다. 이름으로 정렬하는 것은 목표가 아닙니다. –