LINQ to hash — не удается выполнить кастинг правильно!

#c# #asp.net-mvc #linq-to-entities

#c# #asp.net-mvc #linq-to-entities

Вопрос:

У меня есть таблица в SQL Server с 3 столбцами, доменом, ключом и значением. Я хотел бы в конечном итоге получить хэш, который я мог бы использовать в dot-net. Я использую EF 4.0.

сначала я пытался:

 List<Dictionary<string, string>> myHash = db.Registries
  .Where(x => x.Domain == "Pricing")
  .Select(x => new { Key = x.Key, Value = x.Value });
  

который жалуется:

Ошибка 3 Не удается неявно преобразовать тип ‘System.Linq.IQueryable’to’System.Коллекции.Generic.List>’. Существует явное преобразование (вы пропускаете кастинг?) C:UsersekkisDocumentsVisual Studio 2010 Projects SkillScore WebsiteControllers HomeController.cs 53 21 Website

итак, очевидно, что тип выбора нуждается в настройке. Я возился с ним полчаса (я такой бесполезный!), Не имея возможности заставить его работать (боже, как я скучаю по IRC). кому-нибудь помочь?

Комментарии:

1. да, я действительно пробовал: .Select(x => (Dictionary<строка, string>) new {…})

2. Я тоже пытался . Select().Cast<Dictionary<string, строка>>() — который, как мы знаем, жалуется, что он может приводить только к собственным типам EF

3. это также не удается: .Select(x => новый словарь<строка, string>() { x.Ключ, x.значение }) — Метод перегрузки для ‘Add’ не принимает 1 аргумент

4. здесь жалуется, что нет определения для ‘Key’: .Select(x => новый словарь<строка, string>() { Ключ = x.Key, значение = x.Value })

5. @ekkis: Вы захотите ToDictionary() создать словарь из linq — смотрите мой ответ.

Ответ №1:

Похоже, это то, что вам нужно:

 List<Dictionary<string, string>> myHash = db.Registries
                                            .GroupBy(x => x.Domain)
                                            .Select(g => g.ToDictionary(x => x.Key, 
                                                                        x => x.Value))
                                            .ToList() ;
  

Это создает отдельный словарь для каждого домена и помещает их все в список. Однако это не совсем полезно, поскольку вы теряете информацию о доменном имени — возможно, Dictionary<string, Dictionary<string,string>> было бы больше того, что вы хотите (имея доменное имя в качестве ключа внешнего словаря).

Словарь для одного домена вы можете получить, используя ToDictionary() напрямую:

 var pricingDictionary = db.Registries
                          .Where(x => x.Domain == "Pricing")
                          .ToDictionary( x => x.Key, 
                                         x => x.Value);
  

Обратите внимание, что pricingDictionary имеет тип Dictionary<string, string> , поэтому, если вам нужен полный тип, вы можете сделать:

 Dictionary<string, string> myHash = db.Registries
                                      .Where(x => x.Domain == "Pricing")
                                      .ToDictionary( x => x.Key, 
                                                     x => x.Value);
  

Комментарии:

1. вот и все! боже. так много борьбы только потому, что я не знаю. миллион благодарностей, это идеально.

Ответ №2:

Меня заинтересовало: «Как создать словарь словарей в запросе LINQ».

Вот моя скромная попытка, которая непроверена, потому что у меня нет LINQ-DB, потому что у меня нет IIS, потому что я не могу использовать IIS по «подлинным» причинам, о которых некоторые могут догадаться.

Пожалуйста, не стесняйтесь редактировать этот код, чтобы исправить это (если он сломан).

 using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args) {
            var registries = FetchAllRegistries();
            foreach ( KeyValuePair<string, Dictionary<string,string>> domain in registries ) {
                Console.WriteLine("Domain: " domain.Key);
                foreach ( KeyValuePair<string,string> entry in domain.Value ) {
                    Console.WriteLine("  " entry.Key " " entry.Value);
                }                
            }
        }

        private static Dictionary<string, Dictionary<string, string>> FetchAllRegistries() {
            return db.Registries
                .GroupBy(x => x.Domain)
                .Select(g => g.ToDictionary(
                    d => d.Domain,
                    d => d.ToDictionary(
                        kv => kv.Key,
                        kv => kv.Value
                    )
                ))
            ;
        }

        private static Dictionary<string, Dictionary<string, string>> FetchRegistry(string domainName) {
            return db.Registries
                .Where(x => x.Domain == domainName)
                .ToDictionary(
                    x => x.Key
                  , x => x.Value
                );
        }

    }

}
  

И простите меня: эти запросы просто подтверждают мое мнение о том, что LINQ оооочень уродлив, что его задняя часть должна быть сбрита, и его следует научить ходить задом наперед. Верно: версия «длинной руки» НАМНОГО более подробная, НО она также намного понятнее. Я полагаю, моя точка зрения заключается в том, что «LINQ великолепен. Позор из-за кривой обучения STEEEEEEP».

И, да, пожалуйста… давайте вернемся к cgi-скриптам на Perl. Благослови меня, отец, ибо я не могу унаследовать… Я влюблен в простолюдинку. Вздох.

Приветствия. Кит.

Комментарии:

1. смеется… Наверное, я похож на тех хиппи 21 века, которые так и не покинули 70-е и ездят на новеньких Volvos со знаком мира на бампере. Меня, брыкающегося и кричащего, тащат в новый мир