Entity Framework 模型优先:以编程方式创建 UNIQUE 约束

Entity Framework model first: create UNIQUE constraint programmatically

我正在尝试向 "UserAccount" entity/class 的 "Username" 属性 添加 UNIQUE 约束。使用代码优先,这没问题,但对于模型优先,我找不到任何关于如何实现它的信息。 设计器不支持此功能。我不能使用注释,因为实体 classes 是自动生成的。我无法使用 Fluent API,因为 OnModelCreating() 方法未在模型优先中调用,因此我没有 DbModelBuilder 实例。 我唯一能想到的是在应用程序启动时执行某种手动 SQL 语句来创建 UNIQUE 约束,这违背了 EF 的目的。 这是我当前的 DbContext class:

 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; }
}

我什至懒得去 post UserAccount class 因为它是自动生成的,不应该被修改(我知道DbContext 也是自动生成的,但可以对其进行修改)。 对此的任何帮助表示赞赏!

首先,我建议您也切换到 Entity Framework Code First。它使您可以更好地控制 EF 可以实现的所有功能。

我以前没用过,但我知道Model Conventions。它们适用于模型配置。也许这将是一种为应配置为唯一约束的已定义模型 type/property 设置约定的方法。

根据以下内容,应该可以在创建数据库时先修改模型的设置。

Model Conventions are based on the underlying model metadata. There are conventions for both CSDL and SSDL. Create a class that implements IConceptualModelConvention from CSDL conventions and implement IStoreModelConvention for SSDL convention.

来源:http://www.entityframeworktutorial.net/entityframework6/custom-conventions-codefirst.aspx

There are two types of model conventions, Conceptual (C-Space) and Store (S-Space). This distinction indicates where in the pipeline a convention is executed. A C-Space convention is applied to the model that the application builds, whereas an S-Space convention is applied to the version of the model.

来源: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);
        }
    }
}