EF is overriding properties that i have set
I'm using a EF 4.1 Code First setup, here are the entities.
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; }
}
Here are the configurations
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.VendorPro开发者_如何学CductId);
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);
}
Here is the 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());
}
}
Now, what happens is that when it gets to the VendorProducts, the first one is added just fine, but the second one will not save because it looks like EF is not setting the Vendor object, the pattern that i see is that for each vendorproduct that is added if the vendorid and/or productid was used on a previous entity within the same context it will not populate the vendor or product so it sets it to null. As you can see from my code i am explicitly setting VendorId below, but when EF sends the data to the db, VendorId is null. If you need more info please let me know.
Thanks
I have copied and pasted your code into a console app with EF 4.1. When I run it I get this result in the database (SQL Server 2008 R2 Express):
I only have removed the stuff with the image and the Converter.ConvertObjToDecimal
(didn't compile, I have directly used random.Next
).
This is what one would expect from your code, I think. Do you get another result?
精彩评论