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);
}
}
}
我正在尝试向 "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);
}
}
}