我正在使用MVC4,EF5和SQL Server 2012 Express LocalDB。 Customer
域模型包含Phone
和Email
个字段。两者都可以为null,但是,必须至少填充一个。
我在客户端和服务器端使用FluentValidation确保这一点。
但是,当我需要坚持模型时,我遇到了EF5的限制。如果我同时使用了两个,那么持久化代码会失败,但如果我将它们都设为可选:
...
this.Property(q => q.Phone).IsOptional();
this.Property(q => q.Email).IsOptional();
然后这不符合我的要求。
Q1 :我如何对此进行建模 - 有一种简单的方法,还是我必须使用检查约束?这个检查约束是否正常:
ALTER TABLE dbo.[Customer]
ADD CONSTRAINT constraintAtLeastOneContactDetailRequired
CHECK ( ([Phone] IS NOT NULL) OR ([Email] IS NOT NULL) )
--CHECK ( NOT(COALESCE([Phone], [Email]) IS NULL) ) <--or this?
;
Q2 :我对这两个字段都有一个UNIQUE约束,所以如果我允许它们为null并添加检查约束,那么我是否会遇到问题,因为根据定义,可能存在多个空值独特?
答案 0 :(得分:1)
看起来EF不处理约束,所以我需要求助于SQL。这就是我正在做的,但可能有更好的方法:
-- enforce the either-or rule:
ALTER TABLE Customer ADD CONSTRAINT chk1 CHECK ((Phone IS NOT NULL) OR (Email IS NOT NULL));
-- columns cannot be declared as unique (because of multiple nulls), so use workaround:
CREATE UNIQUE NONCLUSTERED INDEX idx1 ON Customer(Phone) WHERE Phone IS NOT NULL;
CREATE UNIQUE NONCLUSTERED INDEX idx2 ON Contact(Email) WHERE Email IS NOT NULL;
唯一性问题是discussed here。
答案 1 :(得分:0)
我认为上面的MarkG有解决方案。创建一个单独的表/实体CustomerContectDetails:
Field Type
CustomerID int (Foreign key link to cusotomer tables)
ContactType int (enumerator - initially either phone or email)
ContactDetails nvarchar(255) to hold either the email or phone number
然后一个简单的计数
if (CustomerContectDetails.Count(x => x.CustomerID == localCustomerID) > 0)
{ // positive actions}
else
{ // negative actions}
此解决方案还可以在将来扩展到其他联系人,并且可以根据联系人类型添加其他规则。并且不需要数据库约束,业务规则也在一个地方。
希望有所帮助。