Я также пытался работать с подобной SQL-IN-вещью - запросом на модель данных сущности. Мой подход - строковый построитель для создания большого OR-выражения. Это ужасно уродливо, но я боюсь, что это единственный способ пойти прямо сейчас.
Теперь хорошо, это выглядит так:
Queue<Guid> productIds = new Queue<Guid>(Products.Select(p => p.Key));
if(productIds.Count > 0)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}.ProductId = Guid\'{1}\'", entities.Products.Name, productIds.Dequeue());
while(productIds.Count > 0)
{
sb.AppendFormat(" OR {0}.ProductId = Guid\'{1}\'",
entities.Products.Name, productIds.Dequeue());
}
}
Работа с GUID в этом контексте: Как вы можете видеть выше, всегда есть слово «GUID» перед GUID ifself в фрагментах строки запроса. Если вы не добавите это, ObjectQuery<T>.Where
выдает следующее исключение:
Типы аргументов «Edm.Guid» и «Edm.String» несовместимы для этой операции., Near equals expression , строка 6, столбец 14.
blockquote>Обнаружено это в форумах MSDN, может быть полезно иметь в виду.
Matthias
... с нетерпением жду следующей версии .NET и Entity Framework, когда все станет лучше. :)
grouperArray.sort(function (a, b) {
var aSize = a.gsize;
var bSize = b.gsize;
var aLow = a.glow;
var bLow = b.glow;
console.log(aLow + " | " + bLow);
if(aSize == bSize)
{
return (aLow < bLow) ? -1 : (aLow > bLow) ? 1 : 0;
}
else
{
return (aSize < bSize) ? -1 : 1;
}
});
grouperArray.sort(function (a, b) {
return a.gsize - b.gsize || a.glow - b.glow;
});
более короткая версия
Вот реализация, которая использует рекурсию для сортировки по любому числу полей сортировки от 1 до бесконечного. Вы передаете ему массив результатов, который представляет собой массив объектов результатов для сортировки, и массив sorts, который представляет собой массив объектов сортировки, определяющих сортировку. У каждого объекта сортировки должен быть ключ «выбрать» для имени ключа, которое он сортирует, и ключ «порядок», который является строкой, обозначающей «восходящий» или «нисходящий».
sortMultiCompare = (a, b, sorts) => {
let select = sorts[0].select
let order = sorts[0].order
if (a[select] < b[select]) {
return order == 'ascending' ? -1 : 1
}
if (a[select] > b[select]) {
return order == 'ascending' ? 1 : -1
}
if(sorts.length > 1) {
let remainingSorts = sorts.slice(1)
return this.sortMultiCompare(a, b, remainingSorts)
}
return 0
}
sortResults = (results, sorts) => {
return results.sort((a, b) => {
return this.sortMultiCompare(a, b, sorts)
})
}
// example inputs
const results = [
{
"LastName": "Doe",
"FirstName": "John",
"MiddleName": "Bill"
},
{
"LastName": "Doe",
"FirstName": "Jane",
"MiddleName": "Bill"
},
{
"LastName": "Johnson",
"FirstName": "Kevin",
"MiddleName": "Bill"
}
]
const sorts = [
{
"select": "LastName",
"order": "ascending"
},
{
"select": "FirstName",
"order": "ascending"
},
{
"select": "MiddleName",
"order": "ascending"
}
]
// call the function like this:
let sortedResults = sortResults(results, sorts)
Это то, что я использую
function sort(a, b) {
var _a = "".concat(a.size, a.glow);
var _b = "".concat(b.size, b.glow);
return _a < _b;
}
, разделив два элемента как строку, и они будут отсортированы по строковому значению. Если вы хотите, вы можете обернуть _a и _b с помощью parseInt, чтобы сравнить их как числа, если вы знаете, что они будут численными.
grouperArray.sort(
function(a,b){return a.gsize == b.gsize ? a.glow - b.glow : a.gsize - b.gsize}
);
Я ожидаю, что ваш троичный оператор ((aSize < bSize) ? -1 : (aSize > bSize) ? 1 : 0;)
вас смутит. Вы должны проверить ссылку, чтобы лучше понять ее.
До тех пор, вот ваш код выдувается в полноэкранном режиме if / else.
grouperArray.sort(function (a, b) {
if (a.gsize < b.gsize)
{
return -1;
}
else if (a.gsize > b.gsize)
{
return 1;
}
else
{
if (a.glow < b.glow)
{
return -1;
}
else if (a.glow > b.glow)
{
return 1;
}
return 0;
}
});
Я понимаю, что это было спрошено некоторое время назад, но я думал, что добавлю свое решение.
Эта функция динамически генерирует методы сортировки. просто укажите каждое сортируемое дочернее свойство, добавленное +/-, чтобы указать восходящий или нисходящий порядок. Супер можно использовать повторно, и ему не нужно ничего знать о структуре данных, которую вы собрали вместе.
function getSortMethod(){
var _args = Array.prototype.slice.call(arguments);
return function(a, b){
for(var x in _args){
var ax = a[_args[x].substring(1)];
var bx = b[_args[x].substring(1)];
var cx;
ax = typeof ax == "string" ? ax.toLowerCase() : ax / 1;
bx = typeof bx == "string" ? bx.toLowerCase() : bx / 1;
if(_args[x].substring(0,1) == "-"){cx = ax; ax = bx; bx = cx;}
if(ax != bx){return ax < bx ? -1 : 1;}
}
}
}
пример использования:
items.sort (getSortMethod ('- price', '+ priority', ' + name '));
это сначала сортировало бы items
с наименьшим price
, причем привязки переходили к элементу с наивысшим priority
. дальнейшие связи нарушаются элементом name
, где элементы представляют собой массив, подобный:
var items = [
{ name: "z - test item", price: "99.99", priority: 0, reviews: 309, rating: 2 },
{ name: "z - test item", price: "1.99", priority: 0, reviews: 11, rating: 0.5 },
{ name: "y - test item", price: "99.99", priority: 1, reviews: 99, rating: 1 },
{ name: "y - test item", price: "0", priority: 1, reviews: 394, rating: 3.5 },
{ name: "x - test item", price: "0", priority: 2, reviews: 249, rating: 0.5 } ...
];
live demo: http://gregtaff.com/misc/ multi_field_sort /
EDIT: Исправлена проблема с Chrome.
grouperArray.sort(function (a, b) {
var aSize = a.gsize;
var bSize = b.gsize;
var aLow = a.glow;
var bLow = b.glow;
console.log(aLow + " | " + bLow);
return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : ( (aLow < bLow ) ? -1 : (aLow > bLow ) ? 1 : 0 );
});
Вот реализация для тех, кто может захотеть что-то более общее, которое будет работать с любым количеством полей.
Array.prototype.sortBy = function (propertyName, sortDirection) {
var sortArguments = arguments;
this.sort(function (objA, objB) {
var result = 0;
for (var argIndex = 0; argIndex < sortArguments.length && result === 0; argIndex += 2) {
var propertyName = sortArguments[argIndex];
result = (objA[propertyName] < objB[propertyName]) ? -1 : (objA[propertyName] > objB[propertyName]) ? 1 : 0;
//Reverse if sort order is false (DESC)
result *= !sortArguments[argIndex + 1] ? 1 : -1;
}
return result;
});
}
В принципе, вы можете указать любое количество свойств / направление сортировки:
var arr = [{
LastName: "Doe",
FirstName: "John",
Age: 28
}, {
LastName: "Doe",
FirstName: "Jane",
Age: 28
}, {
LastName: "Foo",
FirstName: "John",
Age: 30
}];
arr.sortBy("LastName", true, "FirstName", true, "Age", false);
//Will return Jane Doe / John Doe / John Foo
arr.sortBy("Age", false, "LastName", true, "FirstName", false);
//Will return John Foo / John Doe / Jane Doe
grouperArray.sort(function (a, b) {
var aSize = a.gsize;
var bSize = b.gsize;
var aLow = a.glow;
var bLow = b.glow;
console.log(aLow + " | " + bLow);
return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : (aLow < bLow) ? -1 : (aLow > bLow) ? 1 : 0); });
grouperArray.sort((a, b) => a.gsize - b.gsize || a.glow - b.glow);
Даже более короткая версия с использованием синтаксиса стрелок!
grouperArray.sort(function (a, b) {
var aSize = a.gsize;
var bSize = b.gsize;
if (aSize !== aSize)
return aSize - bSize;
return a.glow - b.glow;
});
не проверен, но я думаю, что он должен работать.