2013-12-17 4 views
0

Я задал подобный вопрос раньше, но хотел опубликовать обновленный вопрос и включают в себя весь необходимый код, необходимый для иллюстрации:Entity Framework 1: 1 Отношения FK-х

У меня есть 2 объектов; Корзина и покупатель. У них соотношение 1: 1. Бывают случаи, когда я не хочу загружать свойства nav, чтобы читать значение FK. Я создал объекты, как описано ниже, и установил связь между корзиной и покупателем (см. Ниже классы сопоставления), но EF не заполняет свойства FK для сущностей (см. Блок-тест ниже).

using System; 
using System.Collections.Generic; 
using System.Data.Entity; 
using System.Data.Entity.ModelConfiguration; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 

namespace ClassLibrary1 
{ 
    public class Cart 
    { 
     public int ID { get; set; } 
     public int ShopperID { get; set; } 
     public virtual Shopper Shopper { get; set; } 
    } 

    public class Shopper 
    { 
     public int ID { get; set; } 
     public int CartID { get; set; } 
     public virtual Cart Cart { get; set; } 
    } 

    public class CartMap:EntityTypeConfiguration<Cart> 
    { 
     public CartMap() 
     { 
      this.HasKey(t => t.ID); 

      // Properties 

      // Table & Column Mappings 
      this.ToTable("Cart", "Cart2"); 
      this.Property(t => t.ID).HasColumnName("ID"); 
      this.Property(t => t.ShopperID).HasColumnName("ShopperID"); 
      //this.HasRequired(t => t.Shopper) 
      // .WithRequiredPrincipal(t => t.Cart); 
     } 

    } 

    public class ShopperMap : EntityTypeConfiguration<Shopper> 
    { 
     public ShopperMap() 
     { 
      this.HasKey(t => t.ID); 

      // Properties 

      // Table & Column Mappings 
      this.ToTable("Shopper", "Cart2"); 
      this.Property(t => t.ID).HasColumnName("ID"); 
      this.Property(t => t.CartID).HasColumnName("CartID"); 

      //// Relationships 
      this.HasRequired(t => t.Cart) 
       .WithRequiredDependent(t => t.Shopper) 
       .WillCascadeOnDelete(true); 
     } 
    } 

    public class CartDbContext : DbContext 
    { 
     public IDbSet<Cart> Carts { get; set; } 
     public IDbSet<Shopper> Shoppers { get; set; } 
     public CartDbContext():base("name=CartTest") 
     { 

     } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      base.OnModelCreating(modelBuilder); 
      modelBuilder.Configurations.Add(new CartMap()); 
      modelBuilder.Configurations.Add(new ShopperMap()); 
     } 
    } 

    public class DBSeedingData : DropCreateDatabaseAlways<CartDbContext> 
    { 
     protected override void Seed(CartDbContext context) 
     { 
      var cart1 = new Cart{Shopper = new Shopper()}; 
      var cart2 = new Cart {Shopper = new Shopper()}; 
      base.Seed(context); 
      context.Carts.Add(cart1); 
      context.Carts.Add(cart2); 
      context.SaveChanges(); 
     } 
    } 

    [TestClass] 
    public class TestClass 
    { 
     [ClassInitialize] 
     public static void RunOnceForAllTests(TestContext testContext) 
     { 
      Console.WriteLine("Initializing Database"); 
      using (var ctx = new CartDbContext()) 
      { 
       try 
       { 
        Database.SetInitializer(new DBSeedingData()); 
        ctx.Database.Initialize(true); 
        Console.WriteLine("Database Dropped, Created & Seeded."); 
       } 
       catch (Exception ex) 
       { 
        throw ex; 
       } 
      } 
     } 
     [TestMethod] 
     public void CanReadAllCarts() 
     { 
      using (var ctx = new CartDbContext()) 
      { 
       foreach (var cart in ctx.Carts) 
       { 
        Console.WriteLine(" actual: Cart Id: {0} Shopper Id: {1} Shopper's Cart Id: {2}", cart.ID, cart.ShopperID, cart.Shopper.CartID); 
        Assert.IsTrue(cart.ID > 0, "Cart PK was not set"); 
        Assert.IsTrue(cart.ShopperID > 0, "Shopper FK in Cart was not set"); 
        Assert.IsNotNull(cart.Shopper, "Failed to load navigation properties"); 
        Assert.IsTrue(cart.Shopper.CartID > 0, "Cart FK in Shopper was not set"); 
       }  
      }  
     } 
    } 
} 

Что мне здесь не хватает? Я застрял, пытаясь решить эту проблему в течение недели.

ответ

0

Я испытал это раньше, а также не мог сделать один в один в EF. Мы выполнили работу, в которой есть только одно свойство навигации между двумя объектами. В вашем случае выберите, следует ли использовать свойство навигации в классе Корзина или Shopper. В принципе, это отображение в EF, где только одна сторона имеет свойство nav. Недостатком является то, что тот, у которого нет свойства nav, является слепым, и вы не можете сказать, с кем это связано. Вот об этом article.

Допустим, вы положили нав свойство в классе Shopper

public class Cart 
{ 
    public int ID { get; set; } 

    // no nav property for Shopper 
} 

public class Shopper 
{ 
    public int ID { get; set; } 
    public int CartID { get; set; } 
    public virtual Cart Cart { get; set; } 
} 

тогда вы отобразить его следующим образом:

public class ShopperMap : EntityTypeConfiguration<Shopper> 
{ 
    public ShopperMap() 
    { 
     // other mappings 

     // mapping to cart, notice that the WithMany() is empty   
     this.HasRequired(t => t.Cart) 
      .WithMany() 
      .HasForeignKey(t => t.CartID); 
    } 
} 

Вы увидите в этой статье, что EF Code-First (или EF в целом) не поддерживает индивидуальные ассоциации внешних ключей. Эта работа работала для нас, поэтому я надеюсь, что это сработает и для вас.

+0

Bairose - Спасибо за информацию. Я пытаюсь воспроизвести ваше предложение в своем коде. В вашем примере установлено ли значение FK в слепом объекте (в вашем примере, установлен ли Cart.ShopperID?). В моем коде я сделал покупателем слепые объекты и установил отношения на карте корзины как: 'this.HasRequired (t => t.Shopper) .WithMany() .HasForeignKey (t => t.ShopperId); ' , но значение CartId Shopper не устанавливается. – cdarrigo

+0

О, извините, это опечатка. просто скопируйте вставные классы .. Но, нет, Cart.ShopperID не должен быть там. Теперь я отредактирую и удалю его. – Bairose

+0

Хорошо, я удалил его так, так как вы хотите, чтобы Shopper был слепым объектом, просто удалите Shopper.CartId, и я вижу, что ваше сопоставление корректно, поэтому вам должно быть хорошо идти. Shopper.CartId никогда не будет установлен, даже если вы его разместите (извините, я плохой), потому что мы сделали его односторонним сопоставлением, поэтому EF просто видит это как нормальное свойство, а не как внешний ключ, поэтому просто удаляйте его. – Bairose

Смежные вопросы