LINQ to SQL - PullRequest
       28

LINQ to SQL

1 голос
/ 01 января 2009

Я заканчиваю программу C # ASP.NET, которая позволяет пользователю создавать свой собственный компьютер, выбирая из выпадающих списков такие аппаратные компоненты, как память, процессор и т. Д. Таблица данных SQL имеет 3 столбца; ComputerID, атрибут и значение. ComputerID - это идентификатор, который соответствует определенному компьютеру в моем основном списке продуктов, а Attribtute - это название аппаратного компонента; память, процессор, жесткий диск и т. д., и значение - это значение, назначенное этому атрибуту, например, 1 ГБ или 2,8 ГГц, 320 ГБ. Это означает, что компьютер будет иметь несколько атрибутов.

То, что я пытаюсь сделать, это сузить результаты, сначала выбрав все компьютеры, которые соответствуют требованиям первого атрибута, а затем получая из этого списка, все компьютеры, которые удовлетворяют следующему требованию ... и так далее, для более чем 10 атрибутов.

Я подумал, что было бы неплохо показать вам пример моего запроса LINQ to SQL, чтобы у вас было лучшее представление о том, что я пытаюсь сделать. Это в основном выбирает ComputerID, где объем памяти компьютера превышает 1 ГБ.

var resultsList = from results in db.ComputerAttributes
                  where computer.Value == "MEMORY" && computer.Value >= "1"
                  select results.ComputerID;

Далее я хочу выбрать из списка результатов, где, например, процессор, быстрее, чем 2,8 ГГц и так далее.

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

Спасибо

Ответы [ 4 ]

1 голос
/ 01 января 2009

Вам нужно использовать Concat как «Союз всех».

IQueryable<ComputerAttribute> results = null;
foreach(ComputerRequirement z in requirements)
{
  //must assign to a locally scoped variable to avoid using
  //  the same reference in all of the where methods.
  ComputerRequirement cr = z;
  if (results == null)
  {
    results = db.ComputerAttributes
      .Where(c => c.Attribute == cr.Attribute && c.Value >= cr.Value);
  }
  else
  {
    results = results
      .Concat(db.ComputerAttributes
         .Where(c => c.Attribute == cr.Attribute && c.Value >= cr.Value)
      );
  }
}

int requirementCount = requirements.Count();

//Get the id's of computers that matched all requirements.
IQueryable<int> ids = results
  .GroupBy(x => x.ComputerId)
  .Where(g => g.Count == requirementsCount)
  .Select(g => g.Key);


//Get all attributes for those id's
List<ComputerAttributes> data = db
  .ComputerAttributes.Where(c => ids.Contains(c.ComputerId))
  .ToList();
0 голосов
/ 02 января 2009

Ух, спасибо всем за советы, это было чрезвычайно полезно. Я попробую ваши методы и расскажу, как идут дела. Последнее решение Дэвида Б. было очень похоже на то, что я делал раньше (считая случаи появления ComputerID), однако мой код был крайне неэффективным. :)

        string[] FinalResults = new string[100];
        int Counter2 = 0;
        foreach (string Result in Results)
        {
            string test = Result;
            var Counter1 = 0;
            foreach (string Result2 in Results)
            {
                if (test == Result2)
                {
                    Counter1++;
                }
                else
                {
                    continue;
                }
            }
            if (Counter1 >= 3 && Result != null)
            {
                FinalResults.SetValue(Result,Convert.ToInt32(Counter2));
            }
            else
            {
                continue;
            }
            Counter2++;
        }
        foreach (string FinalResult in FinalResults)
        {
            if (FinalResult != null)
            {
                Response.Write("Laptop: " + FinalResult + "<br />");
            }
            else
            {
                continue;
            }
        }
    }

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

0 голосов
/ 01 января 2009

Возможно, вы захотите перейти на использование методов расширения. Это может немного облегчить их объединение. Кроме того, вы не сможете выполнять сравнение строк со значениями меньше или больше, поскольку SQL не поддерживает эти типы сравнения строк. Однако если вы сохранили идентификаторы, которые имели тот же порядок, что и описания строк, вы можете сравнить их.

Используя методы расширения, вы можете делать такие вещи, как:

Dictionary<string,int>  attributeMap = new Dictionary<string,int>();
attributeMap.Add("MEMORY",1000);
attributeMap.Add("SPEED",2800);

var results = db.ComputerAttributes;
foreach (var attribute in attributeMap)
{
    results = results.Where( c => c.Attribute == attribute.Key
                             && c.Value >= attribute.Value );
}

var ids = results.Select( c => c.ComputerID );

foreach (int id in ids)
{
    ...
}

В приведенном выше примере 1000 эквивалентно 1 ГБ, а 2800 - 2,8 ГГц.

0 голосов
/ 01 января 2009

Полагаю, вы спрашиваете:

Как мне уточнить содержание поиска, выполненного с помощью LINQ to SQL?

Или что-то похожее, верно?

Насколько я понимаю, у вас есть два варианта:

  1. Фильтрация результатов в памяти (если они кешируются).
  2. Расширьте свой SQL-запрос и снова нажмите на БД.

Я не уверен, что LINQ to SQL позволяет запрашивать существующий набор результатов. Я почти уверен, что это не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...