Ok, so I have been facing this issue several times now but I always seemed to figure it out.
This time, ive been stuck and ive tried multiple things, but nothing is working.
I have a combobox of customers in a customer form. When i create a new customer, my combobox is not updating. It only refreshes when closing and re-opening the form.
I am aware of the "ugly and quick" solutions, but I don't want to use this unless I have no other choise. So ive been using BindingLists because of the events... BUT this is not working in my case.
Ive been staring to this for a time now, let it aside, tried again, but keep on failing.
Does anyone know whats missing in this puzzle?
Now the code: Presenter
public class CustomerPresenter
{
private tbl_customer customer = new tbl_customer();
private CustomerView customerView = new CustomerView();
public CustomerPresenter(tbl_customer customer, CustomerView customerView)
{
this.customer = customer;
this.customerView = customerView;
customerView.customerPresenter = this;
}
// Get a list of customers
public List<tbl_customer> customerList;
public BindingList<tbl_customer> getCustomers()
{
using (var customers = new DBCrownfishEntities())
{
var customer = from c in customers.tbl_customer
where c.IsDeleted == false
select c;
this.customerList = customer.ToList();
var listBinding = new BindingList<tbl_customer>(this.customerList);
return listBinding;
}
}
public void testAdd()
{
tbl_customer customer = new tbl_customer();
customer.CustomerPrefix = "Pref";
customer.CustomerName = "Name";
customer.CustomerAddress = "Address";
customer.CustomerPostalCode = "1111";
customer.CustomerCity = "City";
customer.CustomerCountry = "Country";
customer.CustomerCountryCode = "BE";
customer.CustomerVat = "123456789";
customer.hasVatNumber = true;
try
{
using (var cust = new DBCrownfishEntities())
{
cust.tbl_customer.Add(customer);
cust.SaveChanges();
MessageBox.Show("A new customer is succesfully added!");
}
}
catch (EntityException exception)
{
MessageBox.Show(exception.InnerException.Message.ToString(), "Error Connecting database");
}
catch (Exception)
{
throw;
}
}
}
View:
BindingSource bsCustomers = new BindingSource();
private void CustomerView_Load(object sender, EventArgs e)
{
bsCustomers.DataSource = customerPresenter.getCustomers();
cbCustomers.DataSource = bsCustomers;
cbCustomers.DisplayMember = "CustomerName";
cbCustomers.ValueMember = "CustomerId";
radioButton1_CheckedChanged(null, null);
}
private void button1_Click_1(object sender, EventArgs e)
{
customerPresenter.testAdd();
}
Model:
public partial class tbl_customer
{
public tbl_customer()
{
this.tbl_invoices = new HashSet<tbl_invoices>();
}
public int CustomerID { get; set; }
public string CustomerPrefix { get; set; }
public string CustomerName { get; set; }
public string CustomerEmailaddress { get; set; }
public string CustomerAddress { get; set; }
public string CustomerPostalCode { get; set; }
public string CustomerCity { get; set; }
public string CustomerVat { get; set; }
public string CustomerCountryCode { get; set; }
public string CustomerCountry { get; set; }
public bool IsDeleted { get; set; }
public bool hasVatNumber { get; set; }
public virtual ICollection<tbl_invoices> tbl_invoices { get; set; }
}
Related
Trying to populate an ObservableCollection from a database using the Entity Framework. Everything was fine until I started working with linked tables.
I created the DeviceCategory and DeviceComplexity model, and now in the WyeModel I try to integrate them into the DeviceCategoryViewModel. Further, in DeviceCategoryViewModel, I indicated a request for taking information from the database, but I ran into a problem. How to fill in ObservableCollection with this information? I tried different ways, but it didn’t lead to anything, I just got more confused.
DeviceCategoriesViewModel
class DeviceCategoryViewModel
{
TechDContext dc = new TechDContext();
public int Device_category_id { get; set; }
public string Device_category_name { get; set; }
public int Device_complexity_id { get; set; }
public string Device_complexity_name { get; set; }
public static DeviceCategoryViewModel DeviceCaterogyVM(DeviceCategory deviceCategory, DeviceComplexity deviceComplexity)
{
return new DeviceCategoryViewModel
{
Device_category_id = deviceCategory.Device_category_id,
Device_category_name = deviceCategory.Category_name,
Device_complexity_id = deviceCategory.Device_complexity_id,
Device_complexity_name = deviceComplexity.Device_complexity_name
};
}
public void FillDeviceDategories()
{
var q = from cat in dc.DeviceCategories
join com in dc.DeviceComplexities on cat.Device_complexity_id equals com.Device_complexity_id
select new
{
Device_category_id = cat.Device_category_id,
Category_name = cat.Category_name,
Device_complexity_id = com.Device_complexity_id,
Device_complexity_name = com.Device_complexity_name
};
items = q;
deviceCategories = Convert(items);
}
public ObservableCollection<DeviceCategoryViewModel>
Convert(IEnumerable<object> original)
{
return new ObservableCollection<DeviceCategoryViewModel>(original.Cast<DeviceCategoryViewModel>());
}
private IEnumerable<object> items;
public IEnumerable<object> Items
{
get
{
return items;
}
}
private ObservableCollection<DeviceCategoryViewModel> deviceCategories;
public ObservableCollection<DeviceCategoryViewModel> DeviceCategories
{
get
{
FillDeviceDategories();
return deviceCategories;
}
}
DeviceCategory Model
[Table("device_categories")]
public class DeviceCategory
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Device_category_id { get; set; }
public string Category_name { get; set; }
//[ForeignKey]
public int Device_complexity_id { get; set; }
public DeviceCategory()
{
}
public DeviceCategory(string name, int complexity_id)
{
Category_name = name;
Device_complexity_id = complexity_id;
}
}
DeviceCompexity Model
[Table("device_complexities")]
public class DeviceComplexity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Device_complexity_id { get; set; }
public string Device_complexity_name { get; set; }
public DeviceComplexity()
{
}
public DeviceComplexity(string name)
{
Device_complexity_name = name;
}
}
I now get an error in the conversion method
You'd try to cast your LINQ query result to ObservableCollection<DeviceCategoryViewModel> in separate Convert function.
Why not to directly collect your LINQ query result to ObservableCollection<DeviceCategoryViewModel>
Just use like this
var q = from cat in dc.DeviceCategories
join com in dc.DeviceComplexities on cat.Device_complexity_id equals com.Device_complexity_id
select new DeviceCategoryViewModel // <= Note This Line
{
Device_category_id = cat.Device_category_id,
Category_name = cat.Category_name,
Device_complexity_id = com.Device_complexity_id,
Device_complexity_name = com.Device_complexity_name
};
deviceCategories = new ObservableCollection<DeviceCategoryViewModel>(q);
OR if you want to get result after list then simply use q.ToList()
deviceCategories = new ObservableCollection<DeviceCategoryViewModel>(q.ToList());
I am having a problem where when I try to save a new entity that has existing entities nested. Instead of creating a relationship with existing entities it is duplicating them.
This is roughly my model:
public class Record
{
public int ID { get; set; }
public string RecordValue { get; set; }
public virtual ICollection<AddressLine> AddressLines { get; set; }
}
public class AddressLine
{
public int ID { get; set; }
public string AddressLineValue { get; set; }
public virtual ICollection<AddressLineType> AddressLineTypes { get; set; }
}
public class AddressLineType
{
public int ID { get; set; }
public string AddressLineTypeValue { get; set; }
}
I don't want any duplicate AddressLineTypes added so in my code I am doing something like this:
public void button1_Click(object sender, EventArgs e)
{
Record r = new Record();
r.RecordValue = "Record value";
AddressLine al = new AddressLine();
al.AddressLineValue = "Address line value";
AddressLineType alt;
using (var db = new MyDbContext())
{
alt = db.AddressLineTypes.Single(x => x.Value == "TypeValue");
}
al.AddressLineTypes.Add(alt);
r.AddressLines.Add(al);
SaveRecord(r);
}
public void SaveRecord(Record r)
{
using (var db = new MyDbContext())
{
db.Records.Add(r);
db.SaveChanges();
}
}
I have hit a breakpoint before db.SaveChanges() and the AddressLineType ID is populated but it creates new entries in the database as if ID == 0.
How do I stop the existing AddressLineTypes duplicating on save?
Try using a single Context:
...
using (var db = new MyDbContext())
{
alt = db.AddressLineTypes.Single(x => x.Value == "TypeValue");
al.AddressLineTypes.Add(alt);
r.AddressLines.Add(al);
SaveRecord(r, db);
}
}
public void SaveRecord(Record r, MyDbContext db)
{
db.Records.Add(r);
db.SaveChanges();
}
I am trying to make a project in visual studio 2013 and i have a problem with my code.
This is my code:
namespace Firma
{
public partial class Angajare : System.Web.UI.Page
{
private bool isEdit = false;
private int id = 0;
protected void Page_Load(object sender, EventArgs e)
{
FirmeContext db = new FirmeContext();
Angajare editedAngajare = new Angajare();
if (Request.QueryString.Count == 1 && Request["id"] != null)
{
isEdit = true;
id = Convert.ToInt32(Request["id"]);
editedAngajare = db.Angajari.SingleOrDefault<Angajare>(a => a.IDAngajare == id);
if (editedAngajare != null && !IsPostBack)
txtExperienta.Text = editedAngajare.Experienta.ToString();
}
else
isEdit = false;
{
if (!IsPostBack)
{
PostList.DataSource = db.Posturi.ToList();
PostList.DataTextField = "Denumire";
PostList.DataValueField = "ID";
PostList.DataBind();
AngajatList.DataSource = db.Angajati.ToList();
AngajatList.DataTextField = "Nume";
AngajatList.DataValueField = "ID";
AngajatList.DataBind();
}
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
FirmeContext db = new FirmeContext();
Angajare editedAngajare;
try
{
if (isEdit)
{
editedAngajare = db.Angajari.SingleOrDefault<Angajare>(d => d.IDAngajare == id);
if (editedAngajare != null)
{
editedAngajare.Experienta = int.Parse(txtExperienta.Text);
editedAngajare.Angajat = db.Angajati.SingleOrDefault<Angajat>(n => n.ID == int.Parse(AngajatList.SelectedValue));
editedAngajare.Post = db.Posturi.SingleOrDefault<Post>(p => p.IDPost == int.Parse(PostList.SelectedValue));
db.Entry(editedAngajare).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
litMsg.Text = "Record updated!";
}
}
else
{
Angajare newan = new Angajare();
newan.Experienta = int.Parse(txtExperienta.Text);
int idAngajat=int.Parse(AngajatList.SelectedValue);
newan.Angajat = db.Angajati.SingleOrDefault<Angajat>(n => n.ID == idAngajat);
int idPost = int.Parse(PostList.SelectedValue);
newan.Post = db.Posturi.SingleOrDefault<Post>(p => p.IDPost == idPost);
db.Angajari.Add(newan);
db.Entry(newan).State = System.Data.Entity.EntityState.Added;
db.SaveChanges();
litMsg.Text = "New Record Added!";
}
}
catch (Exception ex)
{
litMsg.Text = "Error: " + ex.Message;
}
}
protected void btnCancel_Click(object sender, EventArgs e)
{
Server.Transfer("Default.aspx");
}
}
}
i have a lot of errors. for example, in this line
editedAngajare = db.Angajari.SingleOrDefault<Angajare>(d => d.IDAngajare == id);
It says :
"Error 10 'Firma.Angajare' does not contain a definition for 'IDAngajare' and no extension method 'IDAngajare' accepting a first argument of type 'Firma.Angajare' could be found (are you missing a using directive or an assembly reference?)"
The same thing for Experienta, Angajat, Post
editedAngajare.Experienta = int.Parse(txtExperienta.Text);
editedAngajare.Angajat = db.Angajati.SingleOrDefault<Angajat>(n => n.ID == int.Parse(AngajatList.SelectedValue));
editedAngajare.Post = db.Posturi.SingleOrDefault<Post>(p => p.IDPost == int.Parse(PostList.SelectedValue));
db.Entry(editedAngajare).State = System.Data.Entity.EntityState.Modified;
I will also show you my database:
public class Angajare
{
[Key]
public int IDAngajare { get; set; }
public int Experienta { get; set; }
public virtual Post Post { get; set; }
public virtual Angajat Angajat { get; set; }
}
public class Angajat
{
[Key]
public int ID { get; set; }
public string Nume { get; set; }
public string Prenume { get; set; }
public DateTime DataAngajare { get; set; }
public virtual ICollection<Angajare> Angajari { get; set; }
}
public class Post
{
[Key]
public int IDPost { get; set; }
public string Denumire { get; set; }
public int ExperientaNecesara { get; set; }
public virtual ICollection<Angajare> Angajari { get; set; }
}
Please help me because i have no idea what is going wrong.
Thanks in advice.
It seems that you have two classes Angajare. One a Web.UI.Page and one in your database model. Try to specify namespace in your linq query.
I am fairly new to working with collections so please bear with me my jargon might not even be accurate.
I have PetaPoco returning query results as an IEnumerable, one collection for each result. I want to evaluate the collections to get a specific string from a specific field in each collection. So far I am able to iterate the Enumerable and seeming able to get access an object as per my snippet below but when i view c.Language in debug, it is only the first character of the string (eg where c.Language should equal "JPY" it equals only "J")
am I doing this completely wrong? Thanks for the advice
public void AddContactOrder(object sender, EventArgs e)
{
IEnumerable OrderFact = new OrdersFactsController().getOrderFacts(base.ModuleId);
IEnumerator enumerator = OrderFact.GetEnumerator();
var test = "";
List<string> lang = new List<string>();
while (enumerator.MoveNext())
{
OrderFact c = (OrderFact)enumerator.Current;
if (c.Language == "JPY")
{
test = "okay";
}
}
}
getorderFacts() returns an IEnumerable where T is OrderFact
public class OrderFact
{
public int ID { get; set; }
public int ModuleId { get; set; }
public string ProdCode { get; set; }
public string Language { get; set; }
public string Currency { get; set; }
public string KeyCodes { get; set; }
public string OrderSourceCode { get; set; }
public string OfferingCode { get; set; }
public string JobNumber { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
}
You're better off just using a foreach loop:
foreach (var c in new OrdersFactsController().getOrderFacts(base.ModuleID))
{
if (c.Language == "JPY")
test = "okay";
}
You could use System.Linq's Any extension method:
public void AddContactOrder(object sender, EventArgs e)
{
var orderFacts = new OrdersFactsController().getOrderFacts(base.ModuleId);
var test = orderFacts.Any(x => x.Language == "JPY") ? "okay" : "";
}
public void AddContactOrder(object sender, EventArgs e)
{
IEnumerable<OrderFact> orderFacts = new OrdersFactsController().getOrderFacts(base.ModuleId);
var test = "";
if(orderFacts.Any(x => x.Language == "JPY")) test="okay";
}
LINQ!
In my controller I'm looping through items and saving them to my db. The problem is that it saves the first item, but none of the others. I put a breakpoint on the "SaveItem()" line in the loop and it hits it every time, but what seems odd to me is that it only goes through to the method for the 1st item.
What am I doing wrong?
public void SubmitItem(Cart cart, ShippingDetails shippingDetails, ProcessedItems processedItem, string orderID)
{
var cartItems = cart.Lines;
//CartIndexViewModel cartIndex = new CartIndexViewModel();
//var customID = cartIndex.OrderID;
foreach(var item in cartItems)
{
processedItem.OrderID = orderID;
processedItem.ProductID = item.Product.ProductID;
processedItem.Name = item.Product.Name;
processedItem.Description = item.Product.Description;
processedItem.Price = item.Product.Price;
processedItem.Category = item.Product.Category;
processedItem.ImageName = item.Product.ImageName;
processedItem.Image2Name = item.Product.Image2Name;
processedItem.Image3Name = item.Product.Image3Name;
processedItem.BuyerName = shippingDetails.Name;
processedItem.Line1 = shippingDetails.Line1;
processedItem.Line2 = shippingDetails.Line2;
processedItem.Line3 = shippingDetails.Line3;
processedItem.City = shippingDetails.City;
processedItem.State = shippingDetails.State;
processedItem.Zip = shippingDetails.Zip;
processedItem.Country = shippingDetails.Country;
processedItem.Status = "Submitted";
processedItems.SaveItem(processedItem);
}
}
public class EFProcessedItemsRepository : IProcessedItems
{
private EFDbContext context = new EFDbContext();
public IQueryable<ProcessedItems> ProcessedItem
{
get { return context.ProcessedItems; }
}
public void SaveItem(ProcessedItems processedItem)
{
if(processedItem.ProcessedID == 0)
{
try
{
context.ProcessedItems.Add(processedItem);
context.SaveChanges();
}
catch (Exception)
{
throw;
}
}
else
{
context.Entry(processedItem).State = EntityState.Modified;
}
}
public void DeleteItem(ProcessedItems processedItem)
{
context.ProcessedItems.Remove(processedItem);
context.SaveChanges();
}
}
here is the class for the processedItem:
public class ProcessedItems
{
[Key]
public int ProcessedID { get; set; }
public string OrderID { get; set; }
public int ProductID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
public string ImageName { get; set; }
public string Image2Name { get; set; }
public string Image3Name { get; set; }
public string Status { get; set; }
//shipping
public string BuyerName { get; set; }
public string Line1 { get; set; }
public string Line2 { get; set; }
public string Line3 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string Country { get; set; }
}
Interface:
public interface IProcessedItems
{
IQueryable<ProcessedItems> ProcessedItem { get; }
void SaveItem(ProcessedItems processedItem);
void DeleteItem(ProcessedItems processedItem);
}
try calling context.SaveChanges() after adding all of the items, I think it should persist them all in one go.
Another thing to try:
Refactor your code so that SaveItem accepts only one item to save, Add it and call SaveChanges()
Loop through the cart items outside the method and call the method with one item to save at a time.
// set orderID, shippingDetails above
foreach(var item in cartItems)
{
ProcessedItems processedItem = new ProcessedItems();
processedItem.OrderID = orderID;
processedItem.ProductID = item.Product.ProductID;
processedItem.Name = item.Product.Name;
processedItem.Description = item.Product.Description;
processedItem.Price = item.Product.Price;
processedItem.Category = item.Product.Category;
processedItem.ImageName = item.Product.ImageName;
processedItem.Image2Name = item.Product.Image2Name;
processedItem.Image3Name = item.Product.Image3Name;
processedItem.BuyerName = shippingDetails.Name;
processedItem.Line1 = shippingDetails.Line1;
processedItem.Line2 = shippingDetails.Line2;
processedItem.Line3 = shippingDetails.Line3;
processedItem.City = shippingDetails.City;
processedItem.State = shippingDetails.State;
processedItem.Zip = shippingDetails.Zip;
processedItem.Country = shippingDetails.Country;
SubmitItem(processedItem);
}
public void SubmitItem(ProcessedItems processedItem)
{
processedItem.Status = "Submitted";
processedItems.SaveItem(processedItem);
}
I think it is because processedItem is the same instance for each loop iteration. So after it has been through SaveItem once, it has its ProcessedID set and therefore won't get processed again.
My first guess is that you always store one entity, which is stored in processedItem, which is a input parameter. Try to create new Entity on each loop and then save it. In other words, you assign values to input parameter
processedItem.OrderID = orderID;
and then store same entity each time, but with changed fields
processedItems.SaveItem(processedItem);