2013-07-14 3 views
10

Я использую Entity Framework 5 и у меня есть следующие объекты:Имя свойства в типе должно быть уникальным

public class User { 
    public Int32 Id { get; set; } 
    public String Username { get; set; }  
    public virtual ICollection<CLaim> CLaims { get; set; } 
} 

public class Claim { 
    public Int32 Id { get; set; } 
    public String Type { get; set; } 
    public String Value { get; set; } 
    public virtual User User { get; set; } 
} 

Несколько замечаний по поводу этих лиц:

  1. в пользовательском объекте Идентификатор ПК;
  2. В объекте претензии Id является FK и равен User.Id;
  3. В претензии сущности рк является составным из (Id, Type, Value)

Так у меня есть следующий SQL для этих объектов:

create table dbo.Users 
(
    Id int identity not null 
    constraint PK_Users_Id primary key clustered (Id), 
    Username nvarchar (120) not null 
    constraint UQ_Users_Username unique (Username) 
); 

create table dbo.Claims 
(
    Id int not null, 
    [Type] nvarchar (200) not null, 
    Value nvarchar (200) not null, 
    constraint PK_Claims_Id_Type_Value primary key (Id, [Type], Value), 
); 

alter table dbo.Claims 
add constraint FK_CLaims_Id foreign key (Id) 
    references dbo.Users(Id) on delete cascade on update cascade; 

Наконец, конфигурация сущностей, как следующим образом:

internal class UserConfiguration : EntityTypeConfiguration<User> { 
    internal UserConfiguration() : base() { 
    ToTable("Users"); 
    HasKey(x => x.Id); 
    Property(x => x.Id).IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
    Property(x => x.Username).IsRequired().HasMaxLength(120); 
    } 
} 

internal class ClaimConfiguration : EntityTypeConfiguration<Claim> { 
    internal ClaimMapper() : base() { 
    ToTable("Claims"); 
    HasKey(x => new { x.Id, x.Type, x.Value }); 
    Property(x => x.Id).IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 
    Property(x => x.Type).IsRequired().HasMaxLength(200); 
    Property(x => x.Value).IsRequired().HasMaxLength(200); 

    HasRequired<User>(x => x.User).WithMany(y => y.Claims).Map(z => { z.MapKey("Id"); }); 
    } 
} 

ПРОБЛЕМА:

При попытке создать пользователя, я получаю следующее сообщение об ошибке:

Each property name in a type must be unique. Property name 'Id' was already defined.

Кто-нибудь знает, что я могу делать неправильно?

ответ

30

MapKey Используется только в том случае, если столбец внешнего ключа не отображается как свойство в вашей модели. Но в вашем случае это - как собственность Claim.Id. В этом случае вы должны использовать HasForeignKey вместо MapKey:

HasRequired<User>(x => x.User) 
    .WithMany(y => y.Claims) 
    .HasForeignKey(x => x.Id); 
+24

Что вы будете делать, если это однонаправленное? Нет метода HasForeignKey с возвратом HasOptional/WithOptionalPrincipal – Sam

+0

@Sam В этом случае я использую'MapKey 'со строковым именем поля FK. Если я получу ошибку об этом свойстве с уже существующим именем, я добавлю'Ignore 'для этого свойства. – Diana

+0

@Diana делает исправление отношений, и все работает, когда вы делаете это «взломать»? – jbojcic

0

В дополнение к ответу Slauma в

HasForeignKey не доступен для 1: 1, если вы все еще нужно, вы можете просто использовать WithMany без параметров

HasRequired<User>(x => x.User).WithMany().HasForeignKey(x => x.Id); 
HasRequired(x => x.City).WithMany().HasForeignKey(x => x.CityId); 
Смежные вопросы