entity framework中的唯一键4

现有的数据库模式具有唯一的非主键和一些依赖它们的外键。

在Entity Framework v4中是否可以定义唯一的不是主键的键? 怎么样?

entity framework6.1现在支持数据注解和Fluent API的独特function。

数据注释 ( 参考 )

public class MyEntityClass { [Index(IsUnique = true)] [MaxLength(255)] // for code-first implementations public string MyUniqueProperty{ get; set; } } 

stream利的API ( 参考 )

 public class MyContext : DbContext { protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder .Entity<MyEntityClass>() .Property(t => t.MyUniqueProperty) .HasMaxLength(255) // for code-first implementations .HasColumnAnnotation( "Index", new IndexAnnotation(new[] { new IndexAttribute("Index") { IsUnique = true } }))); } } } 

您必须应用索引并将unique属性设置为true。 默认情况下,根据文档索引是不唯一的。

还需要在项目中安装Entity Framework 6.1 NuGet包,以便使用新的API进行索引。

关于代码优先实现的注意事项: VARCHAR(MAX)不能是唯一约束的一部分。 您必须以数据注释或Fluent API的forms指定最大长度。

另请参阅此MSDN博客文章: http : //blogs.msdn.com/b/efdesign/archive/2011/03/09/unique-constraints-in-the-entity-framework.aspx 。 简而言之,这在V4中是不被支持的,尽pipeEF团队似乎有计划在未来的版本中支持它。

不久前我遇到了同样的问题。

我被给了一个有几个表的数据库(见下文)。

  public class ClinicDbContext : DbContext { public DbSet<User> Users { get; set; } public DbSet<Doctor> Doctors { get; set; } public DbSet<Patient> Patients { get; set; } public DbSet<Secretary> Secretarys { get; set; } public DbSet<Disease> Diseases { get; set; } public DbSet<Consultation> Consultations { get; set; } public DbSet<Administrator> Administrators { get; set; } } 

用户表是这样描述的:

 public class User { [Key] public Guid UserId { get; set; } public string UserName { get; set; } public string Password { get; set; } public string Name { get; set; } public string Surname { get; set; } public string IdentityCardNumber { get; set; } public string PersonalNumericalCode { get; set; } public DateTime DateOfBirth { get; set; } public string Address { get; set; } } 

接下来,我被要求确保所有' UserName '属性都是唯一的。 由于没有注释,我必须找出解决办法。 这里是:

首先,我改变了我的数据库上下文类看起来像这样:

 public class ClinicDbContext : DbContext { public DbSet<User> Users { get; set; } public DbSet<Doctor> Doctors { get; set; } public DbSet<Patient> Patients { get; set; } public DbSet<Secretary> Secretarys { get; set; } public DbSet<Disease> Diseases { get; set; } public DbSet<Consultation> Consultations { get; set; } public DbSet<Administrator> Administrators { get; set; } public class Initializer : IDatabaseInitializer<ClinicDbContext> { public void InitializeDatabase(ClinicDbContext context) { if (!context.Database.Exists() || !context.Database.CompatibleWithModel(false)) { if (context.Database.Exists()) { context.Database.Delete(); } context.Database.Create(); context.Database.ExecuteSqlCommand("CREATE INDEX IX_Users_UserName ON dbo.Users ( UserName )"); } } } } 

上面的重要部分是sql命令 ,通过在我们希望的列上强制唯一索引来改变表格。

这个方法可以从主类调用,例如:

 class Program { static void Main(string[] args) { Database.SetInitializer<ClinicDbContext>(new ClinicDbContext.Initializer()); using (var ctx = new ClinicDbContext()) { Console.WriteLine("{0} products exist in the database.", ctx.Users.Count()); } Console.WriteLine("Press any key to exit."); Console.ReadKey(); } } 

试图运行Program类时发生的最后一个问题如下: 表中的列是无效的types,用作索引中的键列

为了解决这个问题,我为UserName属性添加了一个[MaxLength(250)]注解。

下面是用户类最终的样子:

 public class User { [Key] public Guid UserId { get; set; } [MaxLength(250)] public string UserName { get; set; } public string Password { get; set; } public string Name { get; set; } public string Surname { get; set; } public string IdentityCardNumber { get; set; } public string PersonalNumericalCode { get; set; } public DateTime DateOfBirth { get; set; } public string Address { get; set; } } 

希望它也能解决你的问题!

我试着定义下面的表格:

  • 订单[Id(主要,身份),ClientName,FriendlyOrderNum(唯一)]
  • OrderItems [Id(主要,标识),FriendlyOrderNum(唯一),ItemName]

还有一个从OrderItems.FriendlyOrderNum(Mant)到Orders.FriendlyOrderNum(one)的外键映射。

如果唯一的非主键是可能的,下面的SSDL应该工作:

 <Schema Namespace="EfUkFk_DbModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl"> <EntityContainer Name="EfUkFk_DbModelStoreContainer"> <EntitySet Name="OrderItems" EntityType="EfUkFk_DbModel.Store.OrderItems" store:Type="Tables" Schema="dbo" /> <EntitySet Name="Orders" EntityType="EfUkFk_DbModel.Store.Orders" store:Type="Tables" Schema="dbo" /> </EntityContainer> <EntityType Name="OrderItems"> <Key> <PropertyRef Name="RowId" /> </Key> <Property Name="RowId" Type="bigint" Nullable="false" StoreGeneratedPattern="Identity" /> <Property Name="OrderNum" Type="char" Nullable="false" MaxLength="5" /> <Property Name="ItemName" Type="varchar" MaxLength="100" /> </EntityType> <!--Errors Found During Generation: warning 6035: The relationship 'FK_OrderItems_Orders' has columns that are not part of the key of the table on the primary side of the relationship. The relationship was excluded. --> <EntityType Name="Orders"> <Key> <PropertyRef Name="RowId" /> </Key> <Property Name="RowId" Type="bigint" Nullable="false" StoreGeneratedPattern="Identity" /> <Property Name="ClientName" Type="varchar" MaxLength="100" /> <Property Name="OrderNum" Type="char" Nullable="false" MaxLength="5" /> </EntityType> <!-- AsafR --> <Association Name="FK_OrderItems_Orders"> <End Role="Orders" Type="EfUkFk_DbModel.Store.Orders" Multiplicity="1"> </End> <End Role="OrderItems" Type="EfUkFk_DbModel.Store.OrderItems" Multiplicity="*" /> <ReferentialConstraint> <Principal Role="Orders"> <PropertyRef Name="OrderNum" /> </Principal> <Dependent Role="OrderItems"> <PropertyRef Name="OrderNum" /> </Dependent> </ReferentialConstraint> </Association> </Schema></edmx:StorageModels> 

它不。 在<EntityType>中添加更多<key>元素也是不可能的。

我的结论是,在EF 4中不支持非主键唯一键。

您也可以使用DataAnnotationsvalidation。

我已经创build了这个 ( UniqueAttribute )类,它inheritance了ValidationAttribute ,并且当应用于属性时,该列的值将在validation期间被检索和validation。

你可以从这里获取原始代码。