Consider the following POCO entity for Entity Framework Code First:
public class Foo
{
public int Id { get; set; }
[Required, StringLength(100)]
public string Name { get; set; }
}
Which will generate the following table:
CREATE TABLE [dbo].[Foo] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (100) NOT NULL,
CONSTRAINT [PK_dbo.Foo] PRIMARY KEY CLUSTERED ([Id] ASC)
);
Now, I understand that the default behavior of EF is to convert empty strings to null. So even if I explicitly feed it an empty string I will get a validation exception, which is perfect. The following code will throw a DbEntityValidationException
:
var f = new Foo { Name = "" };
context.Foos.Add(f);
context.SaveChanges();
But, the problem is if I have an external application which accesses the database directly, I can perform the following query and it succeeds:
insert into dbo.Foo(Name)
values ('')
The best solution is arguably to not allow anyone to connect directly to the database and force them through a business layer. In reality however this may not always be possible. Especially if, say, I myself am importing external data via an SSIS package.
My best understanding says that applications should be set up to reject as much bad data at the lowest level possible. In this case this would mean the at database level. So if were creating the database the old fashioned way, I would add a constraint to check (Name <> '')
and stop dirty data from ever being inserted in the first place.
Is there a way to get EF Code First to generate this constraint for me, or some other way to get it to enforce a non-empty-string (minimum length 1) at the database level - preferably using an attribute? Or is my only recourse to add the constraint manually in a migration?