IQueryable で .OrderBy を実行しようとしているという独特の状況があります。(私の定義が正確でない場合はご容赦ください)
私は次のものを持っています:
IQueryable<Source> data = e.Sources.Where(element => element.IsActive == true).OrderBy(el => el.SourceEntityKey);
if (sortDesc.SortDirection == ListSortDirection.Ascending)
{
data = data.OrderBy(order => order.EntityBase.EntityName);
}
else
{
data = data.OrderByDescending(order => order.EntityBase.EntityName);
}
問題は、これがデータベースに実際に格納されている値ではないため、これを実行できないことです。したがって、LINQ to Entities ではサポートされていません。ソースは、実際には人や企業のリストです。ソースとして、個人または会社のサブタイプを持つことができます。会社の場合は、会社名を格納するための独自のテーブルがあります。個人の場合は、独自のテーブルがあり、姓名を格納する 2 つの列があります。そのため、名前がデータベースに同じ方法で保存されていなくても、名前でこれらを注文する方法が必要です。実際の値は次のとおりです。
EntityBase.Person.FirstName
EntityBase.Person.LastName
EntityBase.Company.CompanyName
もう1つの問題は、この後にさらに実行されるため、リストをまだ列挙できないことです。したがって、リストに列挙する前にこれを行う方法が必要です。
助けてくれてありがとう
編集:
できれば簡単にするために単純化しようとしていました...これは、無関係なものを取り除いた私のモデルです。
エンティティベース:
[MetadataType(typeof(EntityBaseMetaData))]
public partial class EntityBase
{
[IgnoreDataMember]
public Person AsPerson
{
get
{
Person p = new Person();
try
{
p = (Person)this;
}
catch
{
p = null;
}
return p;
}
}
[IgnoreDataMember]
public Company AsCompany
{
get
{
Company c = new Company();
try
{
c = (Company)this;
}
catch
{
c = null;
}
return c;
}
}
[IgnoreDataMember]
public string EntityName
{
get
{
string name = "";
if (this.AsPerson != null)
{
name = this.AsPerson.FirstName + " " + this.AsPerson.LastName;
}
else if (this.AsCompany != null)
{
name = this.AsCompany.CompanyName;
}
return name;
}
}
}
public class EntityBaseMetaData
{
//[ScaffoldColumn(false)]
public object EntityBaseKey { get; set; }
}
人:
[MetadataType(typeof(PersonMetaData))]
public partial class Person
{
}
public class PersonMetaData
{
[DisplayName("Person ID")]
public object EntityBaseKey { get; set; }
[DisplayName("First Name")]
public object FirstName { get; set; }
[DisplayName("Last Name")]
public object LastName { get; set; }
}
会社:
[MetadataType(typeof(CompanyMetaData))]
public partial class Company
{
}
public class CompanyMetaData
{
[DisplayName("Company ID")]
public object EntityBaseKey { get; set; }
[DisplayName("Company Name")]
public object CompanyName { get; set; }
}
ソース:
[MetadataType(typeof(SourceMetaData))]
public partial class Source
{ }
public class SourceMetaData
{
[DisplayName("Source ID")]
public object EntityBaseKey { get; set; }
}
コントローラーのアクション:
[GridAction(EnableCustomBinding = true)]
public ActionResult Read(GridCommand command)
{
Entities e = new Entities();
IQueryable<Source> data = e.Sources.Where(element => element.IsActive == true).OrderBy(el => el.EntityBaseKey);
int count = data.Count();
//Apply Grid Commands
if (command != null)
{
//Apply data sort
foreach (SortDescriptor sortDesc in command.SortDescriptors)
{
switch (sortDesc.Member)
{
case "SourceName":
if (sortDesc.SortDirection == ListSortDirection.Ascending)
{
data = data.OrderBy(order => order.EntityBase.EntityName);
}
else {
data = data.OrderByDescending(order => order.EntityBase.EntityName);
}
break;
}
}
//Apply paging
if (command.PageSize > 0)
{
data = data.Skip((command.Page - 1) * command.PageSize).Take(command.PageSize);
}
}
List<SourceView> sources = new List<SourceView>();
foreach (Source s in data.ToList())
{
sources.Add(new SourceView
{
EntityBaseKey = s.EntityBaseKey,
SourceName = s.EntityBase.EntityName,
});
}
return View(new GridModel
{
Data = sources,
Total = count
});
}
これが私がそれを機能させたい方法です。また、表示されていないさらに多くのフィルタリングと並べ替えが行われています。grid コマンドは、Telerik Extensions for ASP.Net の Telerik グリッド用です。クライアント側のバインドを行う必要がなければ、はるかに簡単ですが、データベース情報が多すぎるため、サーバー側のバインドのパフォーマンスが大幅に低下します。
本当に助かります。