webgrid view for variable columns - asp.net-mvc-5

I am trying to display variable columns in WebGrid in MVC5. Following shows the snippet. However, I am not sure how to render the list of columns and stuck at it.
public class gridmatx
{ public Grid Grid { get; set; }
}
public class Grid
{ public List<string> Columns { get; set; }
public List<GridRow> Rows { get; set; }
}
public class GridRow
{ public string Label { get; set; }
public List<decimal> Values { get; set; }
public List<GridRow> ChildRows { get; set; }
}
//----- controller-------
public ActionResult Index1()
{ gridmatx g = new gridmatx();
g.Grid = new Grid();
g.Grid.Columns = new List<string> { "2011", "2012", "2013", "2014", "2015" };
g.Grid.Rows = new List<GridRow>
{ new GridRow { Label = "First", Values = new List<decimal> { 5M, 2M, 1M, 8M, 10M } },
new GridRow { Label = "Second", Values = new List<decimal> { 2M, 2M, 4M, 8M, 9M } },
new GridRow { Label = "Third", Values = new List<decimal> { 12M, 8M, 1M, 9M, 3M } }
};
return View(g);
}
var grid = new WebGrid(Model.Grid.Rows, canSort: false, canPage: true, rowsPerPage: 5);
<div>
#{
for (int i = 0; i < Model.Grid.Columns.Count; i++)
{
var index = i;
#grid.GetHtml(columns:
grid.Columns
( grid.Column("Label", "items"),
grid.Column(Model.Grid.Rows[i].Values[index], "columnX")
), mode: WebGridPagerModes.Numeric);
}
I have one "label" column and variable number of "Values" columns.
Appreciate your help in advance.

Related

Navigation property is null

Album navigation property is null in SellingRequest when I try to load it by include() while it seems every thing is OK!
These are the codes:
public class Album
{
public int Id { get; set; }
public string Note { get; set; }
public virtual SellingRequest SellingRequest { get; set; }
public int? SellingRequestId { get; set; }
public List<Photo> Photos { get; set; }
public virtual MortgageAndRent MortgageAndRent { get; set; }
public int? MortgageAndRentId { get; set; }
}
public class SellingRequest
{
#region Properies
public int Id { get; set; }
public virtual Album Album { get; set; }
public int AlbumId { get; set; }
#endregion Properies
}
Here is where I create album for SellingRequest.
public ActionResult DoUpload(HttpPostedFileBase file, UploadPopupViewModel uploadPopupViewModel)
{
if (file != null && file.ContentLength > 0)
{
string path = Path.Combine(Server.MapPath("~/Contents/Images"), Path.GetFileName(file.FileName));
file.SaveAs(path);
Photo photo = new Photo() { Path = path };
ResponseMessage<Album> album = new ResponseMessage<Album>();
if(uploadPopupViewModel.SellingRequestId!=0)
album = _albumService.GetAlbumBySellingRequestId(uploadPopupViewModel.SellingRequestId);
if (uploadPopupViewModel.MortgageAndRentId != 0)
album = _albumService.GetAlbumByMortgageAndRentId(uploadPopupViewModel.SellingRequestId);
if (album.IsSuccess)
{
photo.AlbumId = album.Result.Id;
}
else
{
Album newAlbum = new Album();
if (uploadPopupViewModel.SellingRequestId != 0)
newAlbum.SellingRequestId = uploadPopupViewModel.SellingRequestId;
if (uploadPopupViewModel.MortgageAndRentId != 0)
newAlbum.MortgageAndRentId = uploadPopupViewModel.MortgageAndRentId;
ResponseMessage<Album> beingSavedAlbum = _albumService.Insert(newAlbum);
ResponseMessage<SellingRequest> sellingRequest = _sellingRequestService.GetById(uploadPopupViewModel.SellingRequestId);
if(sellingRequest.IsSuccess)
{
sellingRequest.Result.AlbumId = newAlbum.Id;
_sellingRequestService.Update(sellingRequest.Result);
}
if(beingSavedAlbum.IsSuccess)
photo.AlbumId = beingSavedAlbum.Result.Id;
}
ResponseMessage<Photo> beingSavedPhoto = _photoService.Insert(photo);
if (beingSavedPhoto.IsSuccess)
{
return RedirectToAction("UploadPopup", "Photo", uploadPopupViewModel);
}
else
{
ModelState.AddModelError("ImageError", beingSavedPhoto.ErrorMessages[0]);
return View("AddPhoto");
}
}
else
{
ModelState.AddModelError("ImageError", "Please choose a photo.");
return View("AddPhoto");
}
}
}
And Here is where I Try to query:
public IEnumerable<TEntity> GET(Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = _context.Set<TEntity>();
if (filter != null)
query = query.Where(filter);
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
query = query.Include(includeProperty);
if (orderBy != null)
return orderBy(query).ToList();
else
return query.ToList();
}
And consequently, Here is where I try to load Album by include.
public List<SellingRequest> GetAllSellingRequests()
{
List<SellingRequest> sellingRequests = _sellingRepository.GET(null, includeProperties: "Address,Album.Photos", orderBy: sR => sR.OrderBy(s => s.RegisteredDate).OrderByDescending(s => s.RegisteredDate)).ToList();
return sellingRequests;
}
With this function I have the Address property but Album is null! It also happens vise versa. I mean when I include the sellingRequest from album, it returns me null, as well! This is while I can include all other entities with no problem!
Edit
This is the schema of my table in database:
SellingRequest Table
And this is the picture of Get.
Any suggestion would be appreciated in advance.
Regards

dynamically create textbox and save data MVC

I am new to MVC. I want to dynamically create textboxes upon user click.
<script>
function addRow(tableID) {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
var colCount = table.rows[0].cells.length;
for(var i=0; i<colCount; i++) {
var newcell = row.insertCell(i);
newcell.innerHTML = table.rows[0].cells[i].innerHTML;
switch(newcell.childNodes[0].type) {
case "text":
newcell.childNodes[0].value = "";
break;
case "checkbox":
newcell.childNodes[0].checked = false;
break;
case "select":
newcell.childNodes[0].selectedIndex = 0;
clear_attrib();
break;
}
}
else {
alert("Cannot add another row.");
}
}
function deleteRow(tableID) {
try {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
for(var i=0; i<rowCount; i++) {
var row = table.rows[i];
var chkbox = row.cells[0].childNodes[0];
if(null != chkbox && true == chkbox.checked) {
if(rowCount <= 1) {
alert("Cannot delete all the rows.");
break;
}
table.deleteRow(i);
rowCount--;
i--;
}
}
}catch(e) {
alert(e);
}
}
and the Razor
<table class="table" id="AddSchedule">
<tr>
<td><input type="checkbox" name="chk[]" class="checkbox_style" /></td>
<td>#Html.EditorFor(model => model.Schedule, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Schedule, "", new { #class = "text-danger" })
</td>
<td>#Html.EditorFor(model => model.Room, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Room, "", new { #class = "text-danger" })
</td>
<td>#Html.EditorFor(model => model.Subject, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Subject, "", new { #class = "text-danger" })
</td>
</tr>
the adding and removing of textboxes is OK. But I don't know how to save the data in the database. This is my controller
public ActionResult Create(EmployeeViewModel employeeViewModel)
{
if (ModelState.IsValid)
{
var emp = db.Employee.Create();
emp.ID = employeeViewModel.ID;
emp.LastName = employeeViewModel.LastName;
emp.FirstName = employeeViewModel.FirstName;
db.Employee.Add(emp);
var sched = db.FacultySchedule.Create();
sched.Schedule = employeeViewModel.Schedule;
sched.Room = employeeViewModel.Room;
sched.Subject = employeeViewModel.Subject;
db.FacultySchedule.Add(sched);
db.SaveChanges();
}
I tried using foreach but it still save only the first value, so i removed it... I think I'm missing something in the mark-up... like adding [] to make it an array just like in PHP. And I don't know how to fix it in the controller.
How can I fix the mark-up and the loop for in the controller for saving? Thanks.
Edit
this is the viewmodel
public class EmployeeViewModel
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Schedule { get; set; }
public string Room { get; set; }
public string Subject { get; set; }
public virtual IEnumerable<FacultySchedule> FacultySchedule { get; set; }
}
and these are the domain model
public partial class Employee
{
public Employee()
{
FacultySchedule = new HashSet<FacultySchedule>();
}
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public virtual ICollection<FacultySchedule> FacultySchedule { get; set; }
}
public partial class FacultySchedule
{
public FacultySchedule()
{
Substitution = new HashSet<Substitution>();
}
public int ID { get; set; }
public int EmployeeID { get; set; }
public string Schedule { get; set; }
public string Room { get; set; }
public string Subject { get; set; }
public virtual Employee Employee { get; set; }
}

ServiceStack 'ExcludePropertyReferences' dynamically if decorate with datamember attribute

I want to ignore some properties from my Object during run time. The properties are decorated with data member attribute (Without data member attribute excludepropertyreferencces is working fine). Can you please provide some insight? Thanks
Question : HOW TO EXCLUDE PROPERTIES AT RUN TIME, IF THEY ARE DECORATE WITH DATAMEMBER ATTRIBUTE ?
ServiceStack , ExcludePropertyReferences
var model = new Model {
FirstName = "First Name",
LastName = "Last Name",
Children = new List<ModelChild>{
new ModelChild { ChildFirstName = "ChildFirstName 1", ChildLastName = "ChildLastName 1" },
new ModelChild { ChildFirstName = "ChildFirstName 2", ChildLastName = "ChildLastName 2" }
}
};
var model1 = new Model1 {
FirstName = "First Name",
LastName = "Last Name",
Children = new List<Model1Child>{
new Model1Child { ChildFirstName = "ChildFirstName 1", ChildLastName = "ChildLastName 1" },
new Model1Child { ChildFirstName = "ChildFirstName 2", ChildLastName = "ChildLastName 2" }
}
};
Console.WriteLine("Properties won't get ignored because the Model is decorated with Serialization Attributes");
using(MemoryStream stream = new MemoryStream())
using (var jsConfig = JsConfig.BeginScope()) {
jsConfig.ExcludeTypeInfo = true;
jsConfig.ExcludePropertyReferences = new [] { "Model.LastName", "ModelChild.ChildLastName" }.ToArray();
JsonSerializer.SerializeToStream(model, model.GetType(), stream);
LINQPad.Extensions.Dump(System.Text.Encoding.Default.GetString(stream.ToArray()));
}
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("Properties will get ignored because the Model is not decorated with Serialization Attributes");
using(MemoryStream stream = new MemoryStream())
using (var jsConfig = JsConfig.BeginScope()) {
jsConfig.ExcludeTypeInfo = true;
jsConfig.ExcludePropertyReferences = new [] { "Model1.LastName", "Model1Child.ChildLastName" }.ToArray();
JsonSerializer.SerializeToStream(model1, model1.GetType(), stream);
LINQPad.Extensions.Dump(System.Text.Encoding.Default.GetString(stream.ToArray()));
}
// Define other methods and classes here
[DataContract()]
public class Model {
[DataMember(Name = "first_name",EmitDefaultValue = false )]
public string FirstName { get; set; }
[DataMember(Name = "last_name")]
public string LastName { get; set; }
[DataMember(Name = "collections")]
public List<ModelChild> Children { get; set; }
}
[DataContract()]
public class ModelChild {
[DataMember(Name = "child_first_name")]
public string ChildFirstName { get; set; }
[DataMember(Name = "child_last_name")]
public string ChildLastName { get; set; }
}
public class Model1 {
public string FirstName { get; set; }
public string LastName { get; set; }
public List<Model1Child> Children { get; set; }
}
public class Model1Child {
public string ChildFirstName { get; set; }
public string ChildLastName { get; set; }
}

ServiceStack OrmLite How can I achieve automatic setting of foreign key/related properties?

I have created the following example to test Foreign Keys and up to this point, it works well. What I would like to be able to do, is use this framework that I built to set the property of the relationship and have it Save the child object when the Parent is saved and automatically set the PrimaryKey and Foreign Key.
The DataManager class exposes the Connection
public class DataManager
{
DataManager()
{
OrmLiteConfig.DialectProvider = SqliteDialect.Provider;
ConnectionString = SqliteFileDb;
updateTables();
}
private void updateTables()
{
using (var dbConn = OpenDbConnection())
{
dbConn.DropAndCreateTable<Person>();
dbConn.DropAndCreateTable<PhoneNumber>();
}
}
public static string SqliteFileDb = "~/App_Data/db.sqlite".MapAbsolutePath();
private static DataManager manager;
public static DataManager Manager {
get
{
if (manager == null)
manager = new DataManager();
return manager;
}
}
public IDbConnection InMemoryDbConnection { get; set; }
public IDbConnection OpenDbConnection(string connString = null)
{
connString = ConnectionString;
return connString.OpenDbConnection();
}
protected virtual string ConnectionString { get; set; }
protected virtual string GetFileConnectionString()
{
var connectionString = SqliteFileDb;
return connectionString;
}
}
These are my POCO's with the BaseClass used to Achieve my results:
public class Person : LiteBase
{
[AutoIncrement]
[PrimaryKey]
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
private List<PhoneNumber> numbers;
public List<PhoneNumber> PhoneNumbers {
get
{
if (numbers == null)
numbers = GetList<PhoneNumber>(p => p.Person == Id);
return numbers;
}
}
}
public class PhoneNumber
{
public string Number { get; set; }
public string Description { get; set; }
[AutoIncrement]
[PrimaryKey]
public int Id { get; set; }
[References(typeof (Person))]
public int Person { get; set; }
public void AddPerson(Person person)
{
Person = person.Id;
}
}
public class LiteBase:INotifyPropertyChanged
{
public List<T> GetList<T>(Expression< Func<T,bool>> thefunction) where T : new()
{
var objects = new List<T>();
using (var conn = Data.DataManager.Manager.OpenDbConnection())
{
objects = conn.Where<T>(thefunction);
}
return objects;
}
public T GetItem<T>(Expression<Func<T, bool>> thefunction) where T : new()
{
T obj = new T();
using (var conn = Data.DataManager.Manager.OpenDbConnection())
{
obj = conn.Where<T>(thefunction).FirstOrDefault<T>();
}
return obj;
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
Simple Class to Create Person and PhoneNumber objects
public class PersonManager
{
public void CreatePerson(string name, string surname, string number)
{
using (var conn = DataManager.Manager.OpenDbConnection())
{
var pnum = new PhoneNumber { Number = number };
var person = new Person
{
Name=name,
Surname = surname,
};
conn.Save<Person>(person);
var id = conn.GetLastInsertId();
person.Id = (int)id;
pnum.AddPerson(person);
conn.Save<PhoneNumber>(pnum);
}
}
public List<Person> GetPeople()
{
List<Person> people;
using (var conn = DataManager.Manager.OpenDbConnection())
{
people = conn.Select<Person>();
}
return people;
}
public List<PhoneNumber> GetNumbers()
{
List<PhoneNumber> numbers;
using (var conn = DataManager.Manager.OpenDbConnection())
{
numbers = conn.Select<PhoneNumber>();
}
return numbers;
}
}
And here is the usage:
var manager = new PersonManager();
manager.CreatePerson("John", "Doe", "12345679");
manager.CreatePerson("Jack", "Smith", "12345679");
manager.CreatePerson("Peter", "Jones", "12345679");
manager.CreatePerson("Dan", "Hardy", "12345679");
var people = manager.GetPeople();
var numbers = manager.GetNumbers();
for (int i = 0; i < people.Count; i++)
{
Console.WriteLine("{0} {1} {2}",
people[i].Name,people[i].Surname,people[i].Id);
}
for (int n = 0; n < numbers.Count; n++)
{
Console.WriteLine("PN: {0} {1}",
numbers[n].Number,numbers[n].Person);
}
for (int p = 0; p < people.Count; p++)
{
var person = people[p];
Console.WriteLine("{0}: {1} {2} {3}",
person.Id,person.Name,person.Surname,person.GetItem<PhoneNumber>(x=>x.Person==person.Id).Number);
}
The output is as I expected :
John Doe 1
Jack Smith 2
Peter Jones 3
Dan Hardy 4
PN: 12345679 1
PN: 12345679 2
PN: 12345679 3
PN: 12345679 4
1: John Doe 12345679
2: Jack Smith 12345679
3: Peter Jones 12345679
4: Dan Hardy 12345679
What I really would like to be able to do is the following:
var john = new Person
{
Name = "John",
Surname = "Smith",
PhoneNumber = new PhoneNumber { Number = "123456789" }
};
conn.Save<Person>(john);
var number = john.PhoneNumber.Number
Is this at all possible?
By default OrmLite v3 blobs all complex types properties in a string field and you need to explicitly set all references.
In the next major v4 release (ETA late Nov 2013), OrmLite adds some support for external references with the [Reference] attribute, which lets you tell OrmLite these properties should be stored in an external table and not blobbed, e.g:
public class Customer
{
[AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
[Reference]
public CustomerAddress PrimaryAddress { get; set; }
[Reference]
public List<Order> Orders { get; set; }
}
This will allow you to call db.SaveReferences() to save the reference properties, e.g:
var customer = new Customer
{
Name = "Customer 1",
PrimaryAddress = new CustomerAddress {
AddressLine1 = "1 Humpty Street",
City = "Humpty Doo",
State = "Northern Territory",
Country = "Australia"
},
Orders = new[] {
new Order { LineItem = "Line 1", Qty = 1, Cost = 1.99m },
new Order { LineItem = "Line 2", Qty = 2, Cost = 2.99m },
}.ToList(),
};
Assert.That(customer.Id, Is.EqualTo(0)); //Id is not saved yet
//Inserts customer, populates auto-incrementing customer.Id
//Specify `references:true` to populate the ForeignKey ids and
//save the related rows as well, e.g:
db.Save(customer, references:true);
Assert.That(customer.Id, Is.GreaterThan(0));
Assert.That(customer.PrimaryAddress.CustomerId, Is.EqualTo(customer.Id));
Assert.That(customer.Orders.All(x => x.CustomerId == customer.Id));
Saving References manually
For more fine-grained control you can also choose which references you want to save, e.g:
db.Save(customer); //Doesn't save related rows
//1:1 PrimaryAddress Reference not saved yet
Assert.That(customer.PrimaryAddress.CustomerId, Is.EqualTo(0));
//1:1 PrimaryAddress Reference saved and ForeignKey id populated
db.SaveReferences(customer, customer.PrimaryAddress);
//1:Many Orders References saved and ForeignKey ids populated
db.SaveReferences(customer, customer.Orders);
Loading all related rows with the entity
You can then load the master row and all its references with db.LoadSingleById, e.g:
var dbCustomer = db.LoadSingleById<Customer>(customer.Id);
dbCustomer.PrintDump();
Assert.That(dbCustomer.PrimaryAddress, Is.Not.Null);
Assert.That(dbCustomer.Orders.Count, Is.EqualTo(2));

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.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);
}
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?

Resources