Für mein allgemeines Gitter tue ich dies derzeit, um die Sortierung zu aktivieren:
Elements.OrderBy(column.SortExpression).AsQueryable();
In dem SortExpression
ist vom Typ Func<T, object>
und Spalte ist eine generische Klasse Column<T>
Ich setze SortExpression in einem Controller wie folgt:
new Column<OrderViewData>{Key = "ShippingDate", SortExpression = e => e.ShippingDate}
Das "OrderBy" führt zu einer Ausführung der SQL-Anweisung, was ich nicht möchte.
Ich versuche also, sie durch diese zu ersetzen:
Elements = from element in Elements
orderby column.SortExpression
select element;
Dadurch wird die Sql-Ausführung nicht ausgelöst.
Nun, natürlich Spalte SortExpression
sollte von einem anderen Typ sein. Nur ich kann nicht wirklich herausfinden, welche Art es sein sollte und wie man es auf die generische Klasse in der Steuerung festgelegt.
Ich sollte immer noch in der Lage sein, die SortExpression
in einer generischen, stark typisierten Art und Weise einer Art.
Irgendwelche Vorschläge, wie ich durch einen Ausdruck irgendwo anders in der Anwendung festgelegt bestellen kann, ohne die Sql beim Anwenden der Reihenfolge auf die IQueryable ausführen?
@ Earwicker:
Das funktioniert:
Expression<Func<Employee, DateTime?>> sortexpression = e => e.BirthDate;
var db = new NorthwindDataContext();
var query = from e in db.Employees
select e;
query = query.OrderBy(sortexpression);
int count = query.Count();
Und erzeugt:
SELECT COUNT(*) AS [value]
FROM [dbo].[Employees] AS [t0]
Wenn ich die DateTime
? in der ersten Zeile mit Objekt:
Expression<Func<Employee, object>> sortexpression = e => e.BirthDate;
Ich erhalte diese Ausnahme:
InvalidOperationException: Bestellung nach Typ 'System.Object' nicht möglich
Nun könnte man sagen: "Dann benutze doch einfach DateTime
?", aber ich möchte, dass der Aufbau der Spalten in meinem generischen Gitter so wenig Code wie möglich erfordert. Ich möchte nicht, dass die Leute den ganzen Code eingeben müssen. Expression<Func<Employee, some_type>>
. Ich möchte, dass die Leute einfach etwas Kleines wie meinen ersten Versuch tippen können SortExpression = e => e.BirthDate
, wo ich die Vorteile der generischen Klasse Column nutze, um 'T' zu definieren.
Glauben Sie, dass es möglich wäre, eine Art Erweiterung zu erstellen, die irgendwie den Typ der e.BirthDate
und wirft dann die Func<T, object>
a Expression<Func<T,some_type>>
? Dann könnte ich im internen Code etwas tun wie: Elements.OrderBy(column.SortExpression.FixCast())
Dass mein interner Code hässlich oder komplex ist, ist mir im Moment ziemlich egal. Ich muss die SQL-Abfragen richtig hinbekommen und mich um die Benutzerfreundlichkeit für Entwickler kümmern, die das Raster verwenden.
Vielen Dank, dass Sie mir geholfen haben!
@ earwicker 2:
var gridBuilder = new RainbowGridBuilder<Employee> ("Examples_Employees")
{
Elements = GetEmployees(),
//The elements (records) we will show in our grid.
//Define the columns for our grid.
Columns = new List<Column<Employee >>
{
new Column<Employee>
{
Key = "EmployeeId",
//Key is used for sorting, selecting columns, ...
Header = "Employee Id",
//The header of the column. Also used as caption in the column selection checkboxlist.
ValueExpression = e => e.EmployeeID.ToString(),
//The Linq expression which will be executed on each element to fill the cell
SortExpression = e => e.EmployeeID,
//The Linq expression by which to sort the elements in the grid.
Display = false
}, //Is this column visible by default?
new Column<Employee>
{
Key = "Name",
ValueExpression = e =>
e.FirstName + " " + e.LastName,
SortExpression = e => e.LastName
} ,
},
// Some other properties here that are irrelevant.
}