【问题标题】:EF is overriding properties that i have setEF 覆盖了我设置的属性
【发布时间】:2011-09-14 16:58:40
【问题描述】:

我使用的是 EF 4.1 Code First 设置,这里是实体。

public class Vendor
{
    public int VendorId { get; set; }
    public string Name { get; set; }
    public virtual ICollection<VendorProduct> VendorProducts { get; set; }
}
public class VendorProduct
{
    public int VendorProductId { get; set; }
    public int ProductId { get; set; }
    public int VendorId { get; set; }
    public string VendorProductNumber { get; set; }
    public int Quantity { get; set; }
    public decimal SalesPrice { get; set; }
    public Product Product { get; set; }
    public Vendor Vendor { get; set; }
}
public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public string Manufacturer { get; set; }
    public string ManufacturerNumber { get; set; }
    public string UPC { get; set; }
    public decimal SalesPrice { get; set; }
    public string Description { get; set; }
    public virtual ICollection<VendorProduct> VendorProducts { get; set; }
}

这里是配置

public class VendorConfiguration : EntityTypeConfiguration<Vendor>
{
    public VendorConfiguration()
    {
        Property(p => p.Name).IsOptional().HasMaxLength(128);
    }
}
public class ProductConfiguration : EntityTypeConfiguration<Product>
{
    public ProductConfiguration()
    {
        //HasKey(p => p.ProductId);
        //HasMany(p => p.Images).WithOptional();
        Property(p => p.Name).IsOptional().HasMaxLength(128);
        Property(p => p.Manufacturer).IsOptional().HasMaxLength(64);
        Property(p => p.ManufacturerNumber).IsOptional().HasMaxLength(32);
        Property(p => p.UPC).IsOptional().HasMaxLength(32);
        Property(p => p.SalesPrice).IsOptional();
    }
}
    public VendorProductConfiguration()
    {
        //HasKey(v => v.VendorProductId);
        Property(o => o.Quantity).IsRequired();
        Property(o => o.SalesPrice).IsRequired();
        Property(o => o.VendorId).IsRequired();
        Property(o => o.ProductId).IsRequired();
        Property(o => o.VendorProductNumber).IsOptional().HasMaxLength(50);
        HasRequired(o => o.Product).WithMany(p => p.VendorProducts).HasForeignKey(o => o.ProductId).WillCascadeOnDelete(false);
    }

这里是 DbContext。

public class UbidContext : DbContext
{
    public IDbSet<Product> Products { get; set; }
    public IDbSet<Vendor> Vendors { get; set; }
    public IDbSet<VendorProduct> VendorProducts { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Add any configuration or mapping stuff here
        modelBuilder.Configurations.Add(new VendorConfiguration());
        modelBuilder.Configurations.Add(new VendorProductConfiguration());
        modelBuilder.Configurations.Add(new ProductConfiguration());
    }


    public void Seed(UbidContext context)
    {
        //Create our indexes
        context.Database.ExecuteSqlCommand("CREATE INDEX IX_Products_Name ON Products (Name)");
        context.Database.ExecuteSqlCommand("CREATE INDEX IX_Products_Manufacturer ON Products (Manufacturer)");
        context.Database.ExecuteSqlCommand("CREATE INDEX IX_Products_ManufacturerNumber ON Products (ManufacturerNumber)");
        context.Database.ExecuteSqlCommand("CREATE INDEX IX_Products_UPC ON Products (UPC)");

        //Add vendors to the database
        AddVendors(context);
        context.SaveChanges();

        //Add products to the database
        AddProducts(context);
        context.SaveChanges();

        //Add vendor products to the database
        AddVendorProducts(context);
    }

    private static void AddVendors(UbidContext context)
    {
        new List<Vendor>
            {
                new Vendor()
                    {
                        Name = "TestVendor1",
                    },
                new Vendor()
                    {
                        Name = "TestVendor2",
                    },
                new Vendor()
                    {
                        Name = "TestVendor3",
                    }
            }.ForEach(v => context.Vendors.Add(v));
    }

    private static void AddProducts(UbidContext context)
    {
        Image[] images = new Image[1];
        images[0] = new Image
        {
            Url = "http://content.etilize.com/Thumbnail/10006997.jpg"
        };

        new List<Product>
            {
                new Product()
                    {
                        Manufacturer = "StarTech.com",
                        ManufacturerNumber = "SV211K",
                        Name = "StarTech.com SV211K KVM Switch - 2 x 1 - 2 x HD-15 Video",
                        UPC = "SV211K",
                        Images = images
                    },
                new Product()
                    {
                        Manufacturer = "Targus Group International",
                        ManufacturerNumber = "CBT300",
                        Name = "Targus BlackTop Standard Notebook Case - Clamshell - Carrying Strap - 5 Pocket - Nylon - Black, Blue",
                        UPC = "CBT300"
                    },
                new Product()
                    {
                        Manufacturer = "Lenovo Group Limited",
                        ManufacturerNumber = "31P8700",
                        Name = "Lenovo Optical ScrollPoint Pro Mouse - Optical - USB, PS/2",
                        UPC = "31P8700"
                    },
                new Product()
                    {
                        Manufacturer = "Epson Corporation",
                        ManufacturerNumber = "C823071",
                        Name = "Epson Serial Interface Board with 32K Buffer - 1 x RS-232 Serial",
                        UPC = "C823071"
                    },
                new Product()
                    {
                        Manufacturer = "Cisco Systems, Inc",
                        ManufacturerNumber = "WSX4013",
                        Name = "Cisco Catalyst 4000 Series Supervisor Engine II-Plus - 2 x GBIC, 1 x - Supervisor Engine",
                        UPC = "WSX4013"
                    }
            }.ForEach(p => context.Products.Add(p));
    }

    private static void AddVendorProducts(UbidContext context)
    {
        Random random = new Random();

        var vps = new List<VendorProduct>()
            {
                new VendorProduct()
                    {
                        ProductId = 1,
                        VendorId = 1,
                        Quantity = random.Next(3, 40),
                        SalesPrice = Converter.ConvertObjToDecimal(random.Next(20, 400)),
                    },
                new VendorProduct()
                    {
                        ProductId = 2,
                        VendorId = 1,
                        Quantity = random.Next(3, 40),
                        SalesPrice = Converter.ConvertObjToDecimal(random.Next(20, 400)),
                    },
                new VendorProduct()
                    {
                        ProductId = 3,
                        VendorId = 1,
                        Quantity = random.Next(3, 40),
                        SalesPrice = Converter.ConvertObjToDecimal(random.Next(20, 400)),
                    },
                 new VendorProduct()
                    {
                        ProductId = 4,
                        VendorId = 2,
                        Quantity = random.Next(3, 40),
                        SalesPrice = Converter.ConvertObjToDecimal(random.Next(20, 400)),
                    },
                new VendorProduct()
                    {
                        ProductId = 4,
                        VendorId = 3,
                        Quantity = random.Next(3, 40),
                        SalesPrice = Converter.ConvertObjToDecimal(random.Next(20, 400)),
                    }
            };
        foreach (var vp in vps)
            context.VendorProducts.Add(vp);
    }

    public class DropCreateIfChangeInitializer : DropCreateDatabaseIfModelChanges<UbidContext>
    {
        protected override void Seed(UbidContext context)
        {
            context.Seed(context);

            base.Seed(context);
        }
    }

    static UbidContext()
    {
        Database.SetInitializer<UbidContext>(new DropCreateIfChangeInitializer());
    }
}

现在,发生的情况是,当它到达 VendorProducts 时,第一个添加得很好,但第二个不会保存,因为看起来 EF 没有设置 Vendor 对象,我看到的模式是如果 vendorid 和/或 productid 在同一上下文中的先前实体上使用,则对于添加的每个 vendorproduct,它不会填充供应商或产品,因此将其设置为 null。从我的代码中可以看出,我在下面明确设置了 VendorId,但是当 EF 将数据发送到数据库时,VendorId 为空。如果您需要更多信息,请告诉我。

谢谢

【问题讨论】:

  • 嗯,问题:1)“第一个添加就好了,但是第二个不会保存”是什么意思? SaveChanges 是一个事务,要么什么都没有保存,要么什么都没有。您是否在SaveChanges 中遇到异常,或者只是数据库中的第一个而其他人都丢失了? 2)“但是当 EF 将数据发送到数据库时,VendorId 为空”:VendorIdint,它不能是null - 你到底是什么意思?

标签: c#-4.0 entity-framework-4 ef-code-first fluent-interface


【解决方案1】:

我已将您的代码复制并粘贴到带有 EF 4.1 的控制台应用程序中。当我运行它时,我会在数据库中得到这个结果(SQL Server 2008 R2 Express):

我只删除了带有图像和Converter.ConvertObjToDecimal的东西(没有编译,我直接使用了random.Next)。

我认为这是人们对您的代码的期望。你得到另一个结果了吗?

【讨论】:

  • 非常感谢您的回复和测试代码,当我在本地运行它时,我在第 2 行得到 ProductId 2:VendorId NULL,对于第 3 行,我得到 ProductId 3:VendorId NULL,第 4 行是很好,第 5 行我得到 ProductId NULL : VendorId 3.
  • 我通过移除 Seed 函数中的额外 context.SaveChanges 来修复它。
  • @no1ross:但是ProductIdVendorId 不可能在数据库中是NULL。它们是数据库中的不可为空的列,其中包含您在问题中显示的代码。如果您真的在数据库中得到NULL,我相信您实际使用的代码与您在问题中提供的代码之间一定存在重要差异。
  • 是的,我明白你在说什么,我试图上传回复,但它不允许我添加图片,因为这是我的第一篇文章,哈哈。无论如何,我实际上更改了 pocos 以允许 FK 中的空值只是为了解决这个问题。发送查询时实际 id 不为空,但供应商/产品是,这是导致问题的原因,一旦我摆脱了种子函数中的所有保存,并将所有数据一次发送到数据库它工作得很好。
  • @no1ross:我明白了。是的,无论如何,最后只调用一次SaveChanges 似乎是更好、更直接的解决方案。很好,它现在可以工作了:)
猜你喜欢
  • 2019-07-28
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 2016-01-30
  • 1970-01-01
  • 2017-08-29
  • 2016-07-29
  • 1970-01-01
相关资源
最近更新 更多