1

我正在使用 MVC4、EF5 和 SQL Server 2012 Express LocalDB。Customer域模型具有PhoneEmail字段。任何一个都可以为空,但至少必须填充一个

我在客户端和服务器端都使用 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 约束,所以如果我允许它们为空并添加检查约束,我会遇到问题,因为可以有多个空值,根据定义,它们不是唯一的吗?

4

2 回答 2

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;

这里讨论唯一性问题。

于 2013-01-05T17:55:18.480 回答
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}

该解决方案还可以在未来扩展到其他联系人,并且可以根据联系人类型添加其他规则。并且不需要数据库约束,业务规则保留在一个地方。

希望有帮助。

于 2013-01-05T13:05:22.897 回答