2012-09-20 3 views
2

У меня есть Person объект:GroupBy с тройным оператором

public class Person 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
    public string Address { get; set; } 
    public double Height { get; set; } 
    public bool IsTest { get; set; } 
} 

Тогда у меня есть список, заполненный различные Person объектов.

Я хочу знать, есть ли способ использовать тернарный оператор с GroupBy в LINQ в зависимости от некоторого свойства объекта. Например:

var groupedPersons = persons.GroupBy(person => person.IsTest ? 
         new { 
           person.Name, 
           person.Age, 
           person.Address 
          } 
        : new { 
           person.Name, 
           person.Age, 
           person.Address, 
           person.Height}).ToList(); 

Но, к сожалению, не работает, дает мне исключение,

Тип условного выражение не может быть определена, потому что нет нет неявного преобразования между «AnonymousType # 1» и «AnonymousType # 2 '

Возможно ли это вообще и как?

Благодаря

EDIT: Пытались, но не работает.

var groupedPersons = persons.GroupBy(person => person.OnTest ? 
        new Person { 
            Address = person.Address, 
            Name = person.Name, 
            Age = person.Age } 
        : new Person { 
            Address= person.Address, 
            Name = person.Name, 
            Age = person.Age , 
            Height = person.Height}).ToList(); 

EDIT: Понял работать, посмотрите на мой ответ

+1

Вы пытались выбрать новые «Лица» вместо использования анонимных классов? – Thousand

+0

ooh спасибо ...это было легко :) – evilone

+1

Я удивлен, что выбираю работы Человека, если только ваш класс человека не использует Equals() и GetHashCode(). Если это EF, то я уверен, что он не позволит вам выбирать новые экземпляры класса сущности. – ChaseMedallion

ответ

-1

Хорошо, попробовав некоторые примеры, показанные здесь, я понял, что это не сработает, и я получил его, чтобы работать другим способом. Вот пример того, как я сделал это:

var groupedPersons = 
     persons.GroupBy(
       person => 
         person.Name + "|" + 
         person.Age.ToString() + "|" + 
         person.Address + "|" + 
         (person.IsTest ? null : person.Height.ToString()) 
     .ToList(); 

Так что, если есть лицо с имуществом IsTest = false затем использует person.Height к группе также.

+0

Выполнение этого метода - плохая идея, строка - это не какой-то общий тип, который вы должны использовать для представления чего-либо. – svick

+0

Фактически в моем реальном объекте (это в проекте не «Человек здесь») все свойства, которые сгруппированы, являются строками. И еще одно булевское свойство. Затем, в зависимости от логического значения, мне нужно сгруппировать по одному другому свойству или нет. – evilone

+0

Итак, я спросил, это достижимо и как - и я нашел для него одно решение. Я могу изменить свойства моего примера класса Person на строки тоже, если это проблема и случай downvoting. – evilone

0

Вы не можете использовать троичной как часть группы, сама по себе, так как компилятор не может определить тип возвращаемого вызов GroupBy (поскольку на самом деле это два разных типа).

Вы можете встроить логику внутри собственности на Person объекта вместо:

public class Person { 
    public string Name { get; set; } 
    public int Age { get; set; } 
    public string Address { get; set; } 
    public double Height { get; set; } 
    public bool IsTest { get; set; } 
    public double GroupProperty { get { return IsTest ? 0.0 : Height } } 
} 

var groupedPersons = persons.GroupBy(person => 
    new { 
     person.Name, 
     person.Age, 
     person.Address, 
     person.GroupByProperty 
    }).ToList(); 

Это устранит Height свойство в качестве значения группирования для всех Person экземпляров с IsTest набор для true (поскольку все они будут доля одна и та же высота).

+0

За исключением того, что ваш код фактически не использует 'Person', он создает объект анонимного типа , – svick

2

Возможно использование анонимных объектов. Вы просто должны убедиться, что они имеют те же имена полей и типы полей:

var groupedPersons = persons.GroupBy(person => person.IsTest ? 
         new { 
           person.Name, 
           person.Age, 
           person.Address, 
           Height = 0 
          } 
        : new { 
           person.Name, 
           person.Age, 
           person.Address, 
           person.Height}).ToList(); 

Edit: Теперь, когда я думаю об этом вы можете сэкономить несколько строк кода, с трехзначным оператором при назначении Height. Если вы беспокоитесь о том, что люди с высотой 0 сгруппированы с испытуемыми, вы можете также группировать их по IsTest.

var groupedPersons = persons.GroupBy(person => 
         new { 
           person.Name, 
           person.Age, 
           person.Address, 
           Height = person.IsTest ? 0 : person.Height, 
           person.IsTest 
          }).ToList(); 
Смежные вопросы