实体框架模型优先:以编程方式创建 UNIQUE 约束
Posted
技术标签:
【中文标题】实体框架模型优先:以编程方式创建 UNIQUE 约束【英文标题】:Entity Framework model first: create UNIQUE constraint programmatically 【发布时间】:2018-04-06 13:11:10 【问题描述】:我正在尝试向我的“UserAccount”实体/类的“用户名”属性添加一个 UNIQUE 约束。使用代码优先,这没有问题,但对于模型优先,我找不到任何关于如何实现这一点的信息。 设计器不支持此功能。我不能使用注释,因为实体类是自动生成的。我不能使用 Fluent API,因为 OnModelCreating() 方法没有在模型优先中调用,因此我没有 DbModelBuilder 实例。 我唯一能想到的就是在应用程序启动时执行某种手动 SQL 语句来创建 UNIQUE 约束,这违背了 EF 的目的。 这是我当前的 DbContext 类:
public partial class UserAccountsModelContainer : DbContext
public UserAccountsModelContainer()
: base("name=UserAccountsModelContainer")
protected override void OnModelCreating(DbModelBuilder modelBuilder)
throw new UnintentionalCodeFirstException();
public virtual DbSet<UserAccount> UserAccounts get; set;
我什至不会费心发布 UserAccount 类,因为它是自动生成的,不应该修改(我知道 DbContext 也是自动生成的,但可以修改它) . 对此的任何帮助表示赞赏!
【问题讨论】:
让我们面对现实吧……模型优先正在死去,取而代之的是代码优先。如果您真的很幸运,有人会提出或多或少可行的解决方案,但请仔细考虑您是否可以为您的项目摆脱模型优先。 已经开始了 ;) 我简直不敢相信这样一个简单的任务从未集成到模型优先中。 【参考方案1】:首先,我也建议您切换到 Entity Framework Code First。它使您可以更好地控制使用 EF 可能实现的每件事。
我以前从未使用过它,但我知道Model Conventions
。它们适用于模型配置。也许这将是一种为应配置为唯一约束的已定义模型类型/属性设置约定的方法。
基于以下内容,应该可以在创建数据库时首先修改模型的设置。
模型约定基于底层模型元数据。那里 是 CSDL 和 SSDL 的约定。创建一个实现的类 IConceptualModelConvention 来自 CSDL 约定和实现 SSDL 约定的 IStoreModelConvention。
来源:http://www.entityframeworktutorial.net/entityframework6/custom-conventions-codefirst.aspx
有两种类型的模型约定,概念(C-Space)和 商店(S 空间)。这种区别表明管道中的哪个位置 约定被执行。将 C-Space 约定应用于模型 应用程序构建,而应用 S-Space 约定 到模型的版本。
来源:https://entityframework.codeplex.com/wikipage?title=Custom%20Conventions
更多示例实现,包括。解释见msdn。我想它们对您的情况很有帮助。
来自 MSDN 的一个示例:
public class DiscriminatorRenamingConvention : IStoreModelConvention<EdmProperty>
public void Apply(EdmProperty property, DbModel model)
if (property.Name == "Discriminator")
property.Name = "EntityType";
它将 Discriminator 列重命名为 EntityType。这是一个非常简单的示例,但您可以对其进行修改以解决您的问题:
public class ModelBasedConvention : IConceptualModelConvention<EdmProperty>
public void Apply(EdmProperty property, DbModel model)
if (property.Name == "Username"
&& property.DeclaringType.GetType() == typeof(UserAccount))
property.AddAnnotation("UniqueKey", property);
【讨论】:
感谢您的详细回答。鉴于完成这样一个简单任务的复杂性,我决定改用代码优先(基于 grek40 的回答和我自己的测试)。以上是关于实体框架模型优先:以编程方式创建 UNIQUE 约束的主要内容,如果未能解决你的问题,请参考以下文章