2011-08-03 13 views
5

mam tych klas:Jak odwzorować obiekt podrzędny na obiekt nadrzędny bez wprowadzania elementu macierzystego w elemencie podrzędnym?

public class Product 
{ 
    [Key] 
    public virtual int ProductId { get; set; } 
    public virtual string ProductName { get; set; } 
    public virtual string Category { get; set; } 

    public virtual IList<ProductPricing> ProductPriceList { get; set; } 


    [Timestamp] 
    public virtual byte[] Version { get; set; } 
} 

public class ProductPricing 
{   

    // no ProductId here 
    public virtual Product Product { get; set; } 

    [Key] 
    public virtual int ProductPricingId { get; set; } 

    public virtual DateTime EffectiveDate { get; set; } 
    public virtual decimal Price { get; set; } 


} 

To jest moja ModelBuilder:

modelBuilder.Entity<Product>(). 
    HasMany(x => x.ProductPriceList) 
    .WithRequired() 
    .HasForeignKey(x => x.Product); 

Jest to błąd:

The foreign key component 'Product' is not a declared property on type 'ProductPricing'. Verify that it has not been explicitly excluded from the model and that it is a valid primitive property.

UPDATE

Wcześniej próbowałem po, odpowiadający err ors poniższy kod

modelBuilder.Entity<Product>() 
    .HasMany(x => x.ProductPriceList) 
    .WithRequired(); 

{"Invalid column name 'Product_ProductId1'.\r\nInvalid column name 'Product_ProductId'.\r\nInvalid column name 'Product_ProductId1'."}

modelBuilder.Entity<Product>() 
    .HasMany(x => x.ProductPriceList) 
    .WithRequired() 
    .Map(x => x.MapKey("ProductId")); 

{"Invalid column name 'Product_ProductId'."}

modelBuilder.Entity<Product>() 
    .HasMany(x => x.ProductPriceList) 
    .WithRequired(x => x.Product); 

{"Invalid column name 'Product_ProductId'.\r\nInvalid column name 'Product_ProductId'."}

modelBuilder.Entity<Product>() 
    .HasMany(x => x.ProductPriceList) 
    .WithRequired(x => x.Product) 
    .Map(x => x.MapKey("ProductId")); 

{"Multiplicity constraint violated. The role 'Product_ProductPriceList_Source' of the relationship 'TestEfCrud.Mappers.Product_ProductPriceList' has multiplicity 1 or 0..1."}

Jeśli to może pomóc, oto DDL:

create table Product 
(
ProductId int not null identity(1,1) primary key, 
ProductName varchar(100) not null, 
Category varchar(100) not null, 
Version rowversion not null 
); 

create table ProductPricing 
(
ProductId int not null references Product(ProductId), 
ProductPricingId int identity(1,1) not null primary key, 
EffectiveDate datetime not null, 
Price decimal(18,6) not null 
); 

UPDATE 2

Próbowałem tę odpowiedź, która wygląda trochępodobny do mojego przypadku, mapowanie pochodzi od podmiotu dziecięcej How to map parent column in EF 4.1 code first

Jednak użycie tego:

modelBuilder.Entity<ProductPricing>() 
    .HasOptional(x => x.Product) 
    .WithMany() 
    .Map(x => x.MapKey("ForeignKeyColumn")); 

i to:

modelBuilder.Entity<ProductPricing>() 
    .HasRequired(x => x.Product) 
    .WithMany() 
    .HasForeignKey(x => x.Product); 

Zarówno doprowadziły do ​​tego błędu:

{"Invalid column name 'Product_ProductId1'.\r\nInvalid column name 'Product_ProductId1'.\r\nInvalid column name 'Product_ProductId1'."}

Odpowiedz

4

Nie rozumiem dlaczego używacie biegle mapowanie? Twój model powinien być mapowany zgodnie z domyślnymi konwencjami. Jeśli chcesz mapować go z płynną stosowania mapowania:

modelBuilder.Entity<Product>() 
      .HasMany(x => x.ProductPriceList) // Product has many ProductPricings 
      .WithRequired(y => y.Product)  // ProductPricing has required Product 
      .Map(m => m.MapKey("ProductId")); // Map FK in database to ProductId column 
+0

Próbowałem nie wprowadzać płynnego mapowania modelBuilder, oczekując, że konwencja over-over będzie działać (moje klasy są typowe dla tych greenfield), ale niestety, ma błąd. '{" Niepoprawna nazwa kolumny 'Product_ProductId'. \ R \ nNiepoprawna nazwa kolumny "Product_ProductId". \ R \ nNiepoprawna nazwa kolumny "Product_ProductId". "}' – Hao

+0

Czy używasz istniejącej bazy danych? –

+0

Istniejąca baza danych z jednym wierszem tylko dla rodzica (produkt) – Hao

2

To ma prawidłową odpowiedź:

http://agilenet.wordpress.com/2011/04/18/entity-framework-code-first-specify-foreign-key-name-in-one-to-many-relationship-with-fluent-api/

prawie dostał go:

modelBuilder.Entity<ProductPricing>() 
    .HasRequired(x => x.Product) 
    .WithMany() 
    .Map(x => x.MapKey("ProductId")); 

po prostu zapomniał umieścić zależny od zleceniodawcy (np. ProductPriceList.Mam nadzieję, że dostaję właściwej terminologii, chciał się trzymać z dala od macierzystego terminologii dziecięcej^_ ^): Płynna Mapowanie

modelBuilder.Entity<ProductPricing>() 
    .HasRequired(x => x.Product) 
    .WithMany(x => x.ProductPriceList) 
    .Map(x => x.MapKey("ProductId")); 

Entity Framework jest ledwie biegle, istnieje jakiś jąkanie można nieświadomie popełnić jeśli jesteś niezbyt zaznajomieni z niuansami każdej metody :-) Wygląda na to, prawie poprawiłem. Przekazywanie zarówno ProductPricing jak i ProductPriceList wygląda na zbędne, mało intuicyjne.

Płynne odwzorowanie EF nie jest płynne (z czego intuicyjność powinna być wrodzoną jakością), czyż nie?

+0

Właśnie przetestowałem moje mapowanie i robi dokładnie to, co chcesz. To, co opisałeś, jest tym samym odwzorowaniem z odwrotnej strony relacji. –

Powiązane problemy