繁体   English   中英

实体框架1:1关系FK

[英]Entity Framework 1:1 Relationship FK's

我之前曾问过类似的问题,但想发布一个更新的问题,并包括所有必要的代码来说明:

我有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");
                }    
            }    
        }
    }  
}

我在这里想念什么? 我一直在努力解决这个问题一个星期。

我以前曾经经历过,并且在EF中一对一进行时也遇到了麻烦。 我们进行了一项工作,其中两个实体之间只有一个导航属性。 在您的情况下,选择是否将导航属性放在Cart或Shopper类中。 基本上,这是EF中的映射,其中只有一侧具有nav属性。 缺点是没有导航属性的人是盲人的,您无法分辨出它与谁有关。 这是一篇关于它的文章

假设您将nav属性放在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)不支持一对一的外键关联。 这项工作对我们有用,所以我希望对您也有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM