我有相当简单的表格结构如下,对我来说发出的声音很奇怪。虽然我选择解决它,但想听取专家的意见。
我有两张桌子
Users
UserName nvarchar(250) Primary Key
FirstName nvarchar(50)
LastName nvarchar(50)
Registrations
Id BigInt PrimaryKey
User nvarchar(250) - Foreign to Users Table
Date - DateTime
Data I have is as follows.
Users
UserName FirstName LastName
a Small A
b Small B
Registrations
Id User Date
1 A 1/1/12
2 B 1/1/12
请注意这里的用户案例是它在SQL中有效,它接受。
现在有趣的部分。我生成了EDMX,.Net 4.0,现在我执行了这段代码。
using (EFTestEntities context = new EFTestEntities())
{
var item = context.Registrations.Where(id => id.Id == 1).FirstOrDefault();
Response.Write(item.User1.LastName);
}
它只是打破空指针异常User1抛出空,当我将注册表中的UserName列的值更改为 a 而不是 A 时,它可以正常工作。
这个Link谈论有些相似
此Link另一个类似问题
请分享您的答案为什么会出现这种情况,我的数据库的排序是不区分大小写的。你有没有遇到类似的事情?
答案 0 :(得分:11)
这里的问题是您的数据库不区分大小写,但CLR(.NET)不是,并且与数据库不同,它不能全局切换到不区分大小写的模式 - 您必须按比较进行。
当您调用item.User1.LastName
EF将触发延迟加载时 - 在数据库中执行附加查询以加载相关用户但是当用户实现时,EF将开始修复并验证其关系模型,这就出现了问题 - 它将字符串与区分大小写进行比较,因此根据此设置,a
不等于A
,因此您加载的User
实体不是您的Registration
实体的关系。因此,EF不会修复User1
属性,它将保持为空。在这种情况下访问LastName
会抛出NullReferenceException
。
只有两种解决方案:
NVarChar
主键和外键是糟糕的数据库设计。如果这些选择都不适合您,则应避免将EF与此类数据库一起使用。
答案 1 :(得分:0)
@Ladislav很好地描述了这个问题,但是有些人可能会使用另一种方法。表中的各个列可以区分大小写,因此它们的行为与.Net相同;
Users
UserName nvarchar(250) collate Latin1_General_CS_AS Primary Key
FirstName nvarchar(50)
LastName nvarchar(50)
Registrations
Id BigInt PrimaryKey
User nvarchar(250) collate Latin1_General_CS_AS - Foreign to Users Table
Date - DateTime
请注意添加到列定义中的collate。现在(假设您已定义外键),数据库将仅针对两个表之间的UserName强制使用大小写一致性。您可能需要事先通过将所有设置都设置为上/下来准备数据,并且如果使用alter table,则可能需要删除并重新创建索引,约束等。
这比尝试在数据库级别更改排序规则的影响要低得多,但仍需要进行一些思考和测试,因为根据其他有效的排序规则,您可能会遇到需要处理的排序规则冲突。
有许多collations可用,因此根据您的情况,其他区分大小写的选项之一可能更适合。