Какой тип я должен использовать с этим совокупным запросом? - PullRequest
1 голос
/ 19 февраля 2010

Я только что освоился с LINQ to SQL, и мне нужен совет по реализации простого сценария:

У меня есть метод ListTagCounts, который выполняет агрегированный запрос с LINQ To SQL. Я не был уверен, какой тип возвращаемого значения использовать, поэтому использовал метод ToList() и создал класс только для возвращаемого типа, чтобы заставить его компилироваться.

Схема:

Link         LinkTag      Tag
----------   ----------   ----------
LinkID       LinkID       TagID
URL          TagID        Name
IsDeleted

Код:

static void Main(string[] args)
{
    var counts = ListTagCounts();
    foreach(var c in counts)
        Console.WriteLine("Tag: {0}, Count: {1}", c.Tag, c.Count);
    Console.ReadKey();
}

public static List<MyReturnClass> ListTagCounts()
{
    List<MyReturnClass> counts;
    using (var db = new MyDbDataContext())
    {
        counts = (from t in db.Tags
                  join lt in db.LinkTags on t.TagID equals lt.TagID
                  join l in db.Links on lt.LinkID equals l.LinkID
                  where l.IsDeleted == false
                  select new MyReturnClass() { Tag = t.Name, Count = t.LinkTags.Count() }
        ).Distinct().OrderBy(t => t.Tag).ToList();
    }
    return counts;
}

public class MyReturnClass
{
    public string Tag { get; set; }
    public int Count { get; set; }
}

Если я сделаю

select new { Tag = t.Name, Count = t.LinkTags.Count() }

вместо

select new MyReturnClass() { Tag = t.Name, Count = t.LinkTags.Count() }

в моем запросе LINQ, каким должен быть тип возвращаемого значения?

Ответы [ 3 ]

1 голос
/ 19 февраля 2010

Первый параметр вернет анонимный тип, который не может быть типом возврата вашего метода, второй способ - это конкретный класс, содержащий вашу информацию, поэтому тип известен и, следовательно, допустим для возврата.

Я бы также предложил вернуть IEnumerable<MyReturnClass>, если вам не нужно, чтобы он был списком (читай: вы ожидаете добавить в него больше элементов)

1 голос
/ 19 февраля 2010

При использовании следующего синтаксиса:

select new { Tag = ..., Count = ... };

Вы создаете анонимный тип . Компилятор генерирует имя этого типа для вас во время компиляции, поэтому вы не сможете узнать, что это такое.

Когда вы вызываете ToList для запроса, который выбирает экземпляры этого анонимного типа, возможно, что вы можете вернуть список, потому что List реализует некоторые неуниверсальные классы (которые, очевидно, не полагаются на параметр типа T, которым вы не являетесь. не знаю) вы можете привести к.

Как правило, вы не должны позволять анонимным типам избегать метода, в котором они используются. Если вам нужно передать информацию за пределы метода, в котором находится запрос, то то, что вы делаете, правильно при создании специализированный класс, а затем возвращает последовательность этого.

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

0 голосов
/ 19 февраля 2010

Как правило, вы хотите присвоить это типу 'var', но это хорошо только для локальных переменных. «объект» может быть ??? Но это длинный

...