【问题标题】:Single Row Table in Entity Framework 6Entity Framework 6 中的单行表
【发布时间】:2015-07-08 20:09:07
【问题描述】:
我找不到这个问题的解决方案,但标题清楚地表明了我想要什么。
是否可以创建单行表(我只需要在表中存储一个布尔值)?以及如何使用 Fluent API 配置此约束?
【问题讨论】:
标签:
c#
sql
entity-framework
entity-framework-6
【解决方案1】:
您可以将其中一列设为主要列,也可以只允许一个值。不幸的是,fluent api 目前不支持默认值
public class StatusIdentifer
{
[DefaultValue("1")]
[Key]
public int id {get; set}; //set can be removed here?
public bool status {get:set;} //your boolean value
}
诀窍是不要为 id 公开任何 set 方法。
在数据库级别,您仍然可以打破范式。答案here 讲述了如何创建检查约束
public void InitializeDatabase(MyRepository context) {
if (!context.Database.Exists() || !context.Database.ModelMatchesDatabase()) {
context.Database.DeleteIfExists();
context.Database.Create();
context.ObjectContext.ExecuteStoreCommand("CREATE UNIQUE CONSTRAINT...");
context.ObjectContext.ExecuteStoreCommand("CREATE INDEX...");
context.ObjectContext.ExecuteStoreCommand("ETC...");
}
}
【解决方案2】:
经过一些研究,我想出了这个解决方案。
我为数据库创建了一个 Initializer(因为在 OnModelCreating 方法中无法调用 ExecuteSqlCommand)。
class UserDbInitializer : CreateDatabaseIfNotExists<UserDbContext>
{
protected override void Seed(UserDbContext context)
{
context.Database.ExecuteSqlCommand(
"CREATE TABLE __Lock(" +
"Id char(1) NOT NULL DEFAULT 'X'," +
"Lock bit NOT NULL," +
"CONSTRAINT PK_LOCK PRIMARY KEY (Id)," +
"CONSTRAINT CK_LOCK_Locked CHECK (Id='X'))"
);
context.Database.ExecuteSqlCommand(
"INSERT INTO __Lock VALUES('X', 0)"
);
base.Seed(context);
}
}
并且在 UserDbContext 中有以下属性:
public bool Locked
{
get
{
return Database.SqlQuery<bool>("SELECT Lock FROM __Lock").SingleAsync().Result;
}
set
{
if (value)
Database.ExecuteSqlCommand("UPDATE __Lock SET Lock = 1");
else
Database.ExecuteSqlCommand("UPDATE __Lock SET Lock = 0");
}
}
希望这对其他人有帮助:)
【解决方案3】:
在 EF Core 中,您可以设置主键的检查约束。它强制列 Id 的值必须等于 1。
modelBuilder.Entity<YourTable>(e =>
{
e.HasCheckConstraint("CK_Table_Column", "[Id] = 1");
e.HasData(...) //optionally add some initial date for Id = 1
});