Я наткнулся на интересную ошибку с linq to sql. Посмотрите на приведенный ниже код, который свободно переводится из запроса LINQtoSQL от поисковой системы, которую я пишу.
Цель запроса - найти любые группы, в которых есть идентификаторы "Джо", "Джефф", "Джим" в последовательном порядке.
Обратите особое внимание на переменные с именами localKeyword и localInt. Если бы вы удалили объявления этих кажущихся бесполезными локальных переменных и заменили их теми, которые они проксируют, вы бы обнаружили, что запрос больше не работает.
Я все еще начинающий с linq to sql, но похоже, что он передает все местные жители в качестве ссылок. Это приводит к тому, что запрос имеет значение только локальных переменных при оценке запроса. В LINQ to SQL мой запрос в итоге выглядел как
SELECT * FROM INDEX ONE, INDEX TWO, INDEX THREE
WHERE ONE.ID = 'Jim' and TWO.ID = 'Jim' and
TWO.SEQUENCE = ONE.SEQUENCE + 2 and
THREE.ID = 'Jim' and
THREE.SEQUENCE = ONE.SEQUENCE + 2 and
ONE.GROUP == TWO.GROUP and ONE.GROUP == THREE.GROUP
Запрос, конечно, перефразирован. Что именно происходит, это ошибка? Я прошу, возможно, лучше понять, почему это происходит. Вы должны найти код компиляции в Visual Studio 2008.
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
namespace BreakLINQ
{
class Program
{
public struct DataForTest
{
private int _sequence;
private string _ID;
private string _group;
public int Sequence
{
get
{
return _sequence;
}
set
{
_sequence = value;
}
}
public string ID
{
get
{
return _ID;
}
set
{
_ID = value;
}
}
public string Group
{
get
{
return _group;
}
set
{
_group = value;
}
}
}
static void Main(string[] args)
{
List<DataForTest> elements = new List<DataForTest>
{
new DataForTest() { Sequence = 0, ID = "John", Group="Bored" },
new DataForTest() { Sequence = 1, ID = "Joe", Group="Bored" },
new DataForTest() { Sequence = 2, ID = "Jeff", Group="Bored" },
new DataForTest() { Sequence = 3, ID = "Jim", Group="Bored" },
new DataForTest() { Sequence = 1, ID = "Jim", Group="Happy" },
new DataForTest() { Sequence = 2, ID = "Jack", Group="Happy" },
new DataForTest() { Sequence = 3, ID = "Joe", Group="Happy" },
new DataForTest() { Sequence = 1, ID = "John", Group="Sad" },
new DataForTest() { Sequence = 2, ID = "Jeff", Group="Sad" },
new DataForTest() { Sequence = 3, ID = "Jack", Group="Sad" }
};
string[] order = new string[] { "Joe", "Jeff", "Jim" };
int sequenceID = 0;
var query = from item in elements
select item;
foreach (string keyword in order)
{
if (sequenceID == 0)
{
string localKeyword = keyword;
query = from item in query
where item.ID == localKeyword
select item;
}
else
{
string localKeyword = keyword;
int localSequence = sequenceID;
query = from item in query
where (from secondItem in elements
where secondItem.Sequence == item.Sequence + localSequence &&
secondItem.ID == localKeyword
select secondItem.Group).Contains(item.Group)
select item;
}
sequenceID++;
}
}
}
}
Значение запроса после завершения кода должно иметь значение {"Джо", "Скучно", 1}.