我有问题绑定一个telerik RadGrid和一个简单的vanilla ASP.NET GridView到以下LINQ到实体查询的结果.在这两种情况下,网格都包含正确的行数,但是所有其他行中仅复制第一行的数据.我直接从这个代码中分配返回值,即网格上的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; }
ADDED:这是替代的纯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;
更多:
>通过LINQ工作发送到sql Server的查询.
>迭代LINQ查询结果返回结果之前,返回相同的重复.
>迭代LINQ结果调用方法,绑定之前,导致相同的重复.
更新:
基于Marc Gravel以下非常合乎逻辑和适当的建议,我发现EF设计师对我的实体类实体关键字做了一个非常未受过教育的猜测,它是其列表中仅有的第一个领域所有其他记录共有七个条目.
这确实是重复的原因.如果只有我可以更改或删除实体密钥,但是这个具有Etch-a-Sketch的所有业务逻辑的EF设计师都非常钦佩重复它的延迟选择,同时嘲笑我锁定外面乞求改变密钥.
解决方法
它看起来像我有一个borked主键. LINQ-to-sql和EF的“身份管理”方面意味着,只要它看到相同的对象类型的主键值,它就不得不给同一个实例.
例如,给出数据:
id | name | ... -------+------------+------ 1 | Fred | ... 2 | Barney | ... 1 | Wilma | ... 1 | Betty | ...
那么如果它认为id是从LINQ迭代对象时的主键,它被迫给你“Fred”,“Barney”,“Fred”,“Fred”.从本质上讲,当它再次看到id 1时,它甚至没有看到其他列 – 它只是从标识缓存中读取ID为1的实例,并为您提供与之前相同的Fred实例.如果不认为id是主键,它会将每一行视为一个单独的对象(如果在其中一个字段中具有与另一个记录相同的值,那么这不是完全不寻常的).
我建议检查您标记为主键(在您的DBML / EDM模型中)的任何字段在每行中是否唯一.在上述情况下,id列显然不表示唯一标识符,因此不适合作为主键.在LINQ-to-sql / EF设计器中,只需取消标记.
更新:特别是在设计器中查看各种属性的“实体密钥”属性 – 特别是在查询视图时.检查“实体密钥”是否只适用于合适的列(即使行唯一的列).如果设置不正确,请将其设置为false.这也是黄色键图标可见 – 这应该只出现在真正是记录的唯一标识符的东西上.