Повторяющиеся строки при связывании данных с LINQ для объектов - PullRequest
12 голосов
/ 16 июня 2009

У меня проблемы с привязкой и Telerik RadGrid, и простого ванильного ASP.NET GridView к результатам следующего запроса LINQ to entity. В обоих случаях сетки содержат правильное количество строк, но данные только из первой группы строк дублируются во всех других строках. Я непосредственно присваиваю возвращаемое значение из этого кода свойству DataSource в сетках.

public IEnumerable<DirectoryPersonEntry> FindPersons(string searchTerm)
{
    DirectoryEntities dents = new DirectoryEntities();
    return from dp in dents.DirectoryPersonEntrySet
           where dp.LastName.StartsWith(searchTerm) || dp.Extension.StartsWith(searchTerm)
           orderby dp.LastName, dp.Extension
           select dp;
}

ДОБАВЛЕНО: Это альтернативный простой код ADO.NET, который работает:

    DataTable ret = new DataTable();
    using (SqlConnection sqn = new SqlConnection(ConfigurationManager.ConnectionStrings["WaveAdo"].ConnectionString))
    {
        SqlDataAdapter adap = new SqlDataAdapter("select * from DirectoryPersonList where LastName like '" + searchTerm + "%' order by LastName ", sqn);
        sqn.Open();
        adap.Fill(ret);
    }
    return ret;

БОЛЬШЕ :

  1. Запрос, отправленный на SQL Server через LINQ, работает.
  2. Итерация результатов запроса LINQ перед их возвратом приводит к одинаковым дублированиям.
  3. Итерация LINQ приводит к тому, что вызывающий метод перед привязкой приводит к таким же дублированиям.

UPDATE : Основываясь на очень логичном и подходящем совете от Марка Гравела ниже, я обнаружил, что дизайнер EF сделал очень необразованное предположение о ключе сущности для моего класса сущности, первого поля в его списке полей, Department , из которых есть только приблизительно семь записей, разделенных между всеми другими записями.

Это действительно причина дублирования. Если бы я только мог изменить или удалить ключ сущности, но этот EF-дизайнер со всей бизнес-логикой Etch-a-Sketch превосходно стремится повторить свой запаздывающий выбор ключа, смеясь над мной, запертым снаружи и просящим сменить ключ.

Ответы [ 4 ]

30 голосов
/ 21 июня 2009

Мне кажется, у вас есть первичный ключ с пробой. Аспект LINQ-to-SQL и EF «управление идентификацией» означает, что он обязан возвращать один и тот же экземпляр всякий раз, когда он видит одинаковые значения первичного ключа для одного и того же типа объекта.

Например, с учетом данных:

id     | name       | ...
-------+------------+------
1      | Fred       | ...
2      | Barney     | ...
1      | Wilma      | ...
1      | Betty      | ...

Затем , если он думает, что id является первичным ключом при переборе объектов из LINQ, заставляет выдавать вам "Fred", "Barney", "Fred "," Фред ". По сути, когда он снова видит id 1, он даже не смотрит на другие столбцы - он просто выбирает экземпляр с id 1 из кэша идентификаторов - и дает вам тот же экземпляр Fred, который он дал вам ранее. Если он не думает, что id является первичным ключом, он будет обрабатывать каждую строку как отдельный объект (и что, если он имеет то же значение в одном из полей, что и другая запись - это не не совсем необычно).

Я бы посоветовал проверить, что все поля, отмеченные вами как первичный ключ (в вашей модели DBML / EDM), действительно уникальны для каждой строки. В приведенном выше случае столбец id явно не представляет уникальный идентификатор, поэтому не подходит в качестве первичного ключа. Просто снимите отметку как таковую в конструкторе LINQ-to-SQL / EF.


update: в частности, посмотрите на свойство «Entity Key» для различных свойств в конструкторе - особенно если вы запрашиваете представление. Убедитесь, что для «Entity Key» установлено значение true только для подходящих столбцов (то есть тех, которые делают строку уникальной). Если он установлен неправильно, установите для него значение false. Это также видно в виде значка желтой клавиши - это должно появляться только на вещах, которые действительно являются уникальными идентификаторами записи.

1 голос
/ 19 июня 2009

А если заключить запрос ссылки в круглые скобки и использовать расширение .Distinct ()?

public IEnumerable<DirectoryPersonEntry> FindPersons(string searchTerm)
{
    DirectoryEntities dents = new DirectoryEntities();
    return (from dp in dents.DirectoryPersonEntrySet
           where dp.LastName.StartsWith(searchTerm) || dp.Extension.StartsWith(searchTerm)
           orderby dp.LastName, dp.Extension
           select dp).Distinct();
}
0 голосов
/ 16 февраля 2011

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

вместо выбора дп, используйте

select new <ObjectName>
{
a = v.a
b = v.b
}.

Это не вернет дубликаты.

0 голосов
/ 22 июня 2009

Разница между вашими рабочими и неработающими запросами заключается в предложении orderby. Я обнаружил документированную ошибку в реализации orderby в Linq to Entities ... могут быть и другие.

Попробуйте удалить orderby из прерванного запроса и посмотрите, есть ли у вас дубликаты.

Другим отличием является OR в предложении where. Попробуйте использовать только первую часть [где dp.LastName.StartsWith (searchTerm)] и посмотрите, есть ли у вас дубликаты.

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