I have a windows forms application where I have a views with multiple tables. The tables get built dynamically by setting the name of their columns by the properties of the object, and then adding them to the dataset. There's also an empty row added for each table. The issue I'm having is that out of the 9 objects being used to create these tables, 2 of the tables aren't getting any columns set or an empty row.
I've looked at the debug and have compared the objects properties that are getting columns to the one's without, and cannot decipher what the issue is. Has anyone ever had this issue before? And if so, what was the problem?
Here's my code, let me know if there's any other information needed:
protected override DataSet GetDefaultFilterTypes()
{
return DataSetUtility.ToDataSet(new List<Type> { typeof(Counterparty), typeof(Address), typeof(Contact),
typeof(Customer), typeof(Broker), typeof(ExchangeBroker), typeof(ExchangeBrokerAccount), typeof(Supplier), typeof(SupplierTerminalPriceMapping) });
}
public static DataSet ToDataSet(IList<Type> list)
{
DataSet ds = new DataSet();
foreach (Type item in list)
{
DataTable ta = new DataTable(item.ToString());
ds.Tables.Add(ta);
//add a column to table for each public property on T
foreach (var propInfo in item.GetProperties())
{
Type colType = Nullable.GetUnderlyingType(propInfo.PropertyType) ?? propInfo.PropertyType;
ta.Columns.Add(propInfo.Name, colType);
}
DataRow row = ta.NewRow();
foreach (var propInfo in item.GetProperties())
{
row[propInfo.Name] = DBNull.Value;
}
ta.Rows.Add(row);
}
return ds;
}
Here's the class definitions for ExchangeBroker and Supplier - the objects not getting columns:
public partial class Supplier : MomentumEntityBase
{
#region *** Properties
[DataMember(Order = 1, IsRequired = true)]
[Key,Required]
[GreaterThanZero]
public int SupplierId
{
get { return _supplierId; }
set
{
if (Equals(value, _supplierId)) return;
_supplierId = value;
NotifyPropertyChanged("SupplierId");
}
}
private int _supplierId;
[DataMember(Order = 2, IsRequired = true)]
[Required(AllowEmptyStrings = false),StringLength(64)]
public string CreationName
{
get { return _creationName; }
set
{
if (Equals(value, _creationName)) return;
_creationName = value;
NotifyPropertyChanged("CreationName");
}
}
private string _creationName;
[DataMember(Order = 3, IsRequired = true)]
[Required]
public DateTime CreationDate
{
get { return _creationDate; }
set
{
if (Equals(value, _creationDate)) return;
_creationDate = value;
NotifyPropertyChanged("CreationDate");
}
}
private DateTime _creationDate;
[DataMember(Order = 4, IsRequired = false)]
[StringLength(64)]
public string RevisionName
{
get { return _revisionName; }
set
{
if (Equals(value, _revisionName)) return;
_revisionName = value;
NotifyPropertyChanged("RevisionName");
}
}
private string _revisionName;
[DataMember(Order = 5, IsRequired = false)]
public DateTime? RevisionDate
{
get { return _revisionDate; }
set
{
if (Equals(value, _revisionDate)) return;
_revisionDate = value;
NotifyPropertyChanged("RevisionDate");
}
}
private DateTime? _revisionDate;
#endregion
#region *** Reverse Navigation
#endregion
#region *** Foreign Keys
// Foreign keys
public Counterparty Counterparty
{
get { return _counterparty; }
set
{
if (Equals(value, _counterparty)) return;
_counterparty = value;
CounterpartyChangeTracker = _counterparty == null ? null : new ChangeTrackingCollection<Counterparty> { _counterparty };
NotifyPropertyChanged("Counterparty");
}
}
private Counterparty _counterparty;
private ChangeTrackingCollection<Counterparty> CounterpartyChangeTracker { get; set; }
#endregion
#region *** CTOR / Initialize
public Supplier()
{
InitializePartial();
}
partial void InitializePartial();
#endregion
#region *** Error
public override string Error
{
get
{
var error = new StringBuilder();
if (TrackingState != TrackableEntities.TrackingState.Deleted)
{
if (!string.IsNullOrEmpty(base.Error))
{
error.AppendLine(base.Error);
}
}
return error.ToString();
}
}
#endregion
}
[DataContract]
public enum ExchangeBrokerColumns
{
[EnumMember]
ExchangeBrokerId = 0,
[EnumMember]
CreationName = 1,
[EnumMember]
CreationDate = 2,
[EnumMember]
RevisionName = 3,
[EnumMember]
RevisionDate = 4
}
// ExchangeBroker
//[DataContract]
[GeneratedCodeAttribute("EF.Reverse.POCO.Generator", "2.17.1.0")]
public partial class ExchangeBroker : MomentumEntityBase
{
#region *** Properties
[DataMember(Order = 1, IsRequired = true)]
[Key,Required]
[GreaterThanZero]
public int ExchangeBrokerId
{
get { return _exchangeBrokerId; }
set
{
if (Equals(value, _exchangeBrokerId)) return;
_exchangeBrokerId = value;
NotifyPropertyChanged("ExchangeBrokerId");
}
}
private int _exchangeBrokerId;
[DataMember(Order = 2, IsRequired = true)]
[Required(AllowEmptyStrings = false),StringLength(64)]
public string CreationName
{
get { return _creationName; }
set
{
if (Equals(value, _creationName)) return;
_creationName = value;
NotifyPropertyChanged("CreationName");
}
}
private string _creationName;
[DataMember(Order = 3, IsRequired = true)]
[Required]
public DateTime CreationDate
{
get { return _creationDate; }
set
{
if (Equals(value, _creationDate)) return;
_creationDate = value;
NotifyPropertyChanged("CreationDate");
}
}
private DateTime _creationDate;
[DataMember(Order = 4, IsRequired = false)]
[StringLength(64)]
public string RevisionName
{
get { return _revisionName; }
set
{
if (Equals(value, _revisionName)) return;
_revisionName = value;
NotifyPropertyChanged("RevisionName");
}
}
private string _revisionName;
[DataMember(Order = 5, IsRequired = false)]
public DateTime? RevisionDate
{
get { return _revisionDate; }
set
{
if (Equals(value, _revisionDate)) return;
_revisionDate = value;
NotifyPropertyChanged("RevisionDate");
}
}
private DateTime? _revisionDate;
#endregion
#region *** Reverse Navigation
// Reverse navigation
public ChangeTrackingCollection<ExchangeBrokerAccount> ExchangeBrokerAccounts
{
get { return _exchangeBrokerAccounts; }
set
{
if (Equals(value, _exchangeBrokerAccounts)) return;
_exchangeBrokerAccounts = value;
//NotifyPropertyChanged("ExchangeBrokerAccounts");
}
}
private ChangeTrackingCollection<ExchangeBrokerAccount> _exchangeBrokerAccounts;
#endregion
#region *** Foreign Keys
// Foreign keys
public Counterparty Counterparty
{
get { return _counterparty; }
set
{
if (Equals(value, _counterparty)) return;
_counterparty = value;
CounterpartyChangeTracker = _counterparty == null ? null : new ChangeTrackingCollection<Counterparty> { _counterparty };
NotifyPropertyChanged("Counterparty");
}
}
private Counterparty _counterparty;
private ChangeTrackingCollection<Counterparty> CounterpartyChangeTracker { get; set; }
#endregion
#region *** CTOR / Initialize
public ExchangeBroker()
{
ExchangeBrokerAccounts = new ChangeTrackingCollection<ExchangeBrokerAccount>();
InitializePartial();
}
partial void InitializePartial();
#endregion
#region *** Error
public override string Error
{
get
{
var error = new StringBuilder();
if (TrackingState != TrackableEntities.TrackingState.Deleted)
{
if (!string.IsNullOrEmpty(base.Error))
{
error.AppendLine(base.Error);
}
if (ExchangeBrokerAccounts.HasError())
{
error.AppendLine("ExchangeBrokerAccounts contains validation error(s).");
}
}
return error.ToString();
}
}
#endregion
}
Related
I think I'm getting stupid because I can't get my LINQ query to work as I expect. I have one class that has 3 relationships to other classes.
This is the main class
[Table(Name = "scanResult")]
public class SniffResult
{
public SniffResult()
{
}
public SniffResult(Address address)
{
this.address = address;
}
private int _pk_SniffResult;
[Column(IsPrimaryKey = true, IsDbGenerated = true, Storage = "_pk_SniffResult", Name ="pk_scanResult")]
public int pk_SniffResult { get { return _pk_SniffResult; } set { this._pk_SniffResult = value; } }
private int _fk_scan;
[Column(Storage = "_fk_scan", Name = "scan")]
public int fk_scan { get { return _fk_scan; } set { this._fk_scan = value; } }
private Scan _scan;
[Association(Storage = "_scan", IsForeignKey = true, ThisKey = "fk_scan", OtherKey = "pk_scan")]
public Scan scan { get { return _scan; } set { this._scan = value; } }
private int _fk_address;
[Column(Storage = "_fk_address", Name = "address")]
public int fk_adress { get { return _fk_address; } set { this._fk_address = value; } }
private Address _address;
[Association(Storage ="_address", IsForeignKey = true, ThisKey = "fk_adress", OtherKey = "pk_address")]
public Address address { get { return _address; } set { this._address = value; } }
private string _rawResult;
[Column(Storage = "_rawResult", Name = "raw")]
public string rawResult { get { return _rawResult; } set { this._rawResult = value; } }
private int _code = -5;
[Column(Storage = "_code")]
public int code { get { return _code; } set { this._code = value; } }
private DateTime _scanDate = DateTime.Now;
[Column(Storage = "_scanDate")]
public DateTime scanDate { get { return _scanDate; } set { this._scanDate = value; } }
private int? _fk_proxy;
[Column(Storage = "_fk_proxy", Name = "usedProxy", CanBeNull = true)]
public int? fk_proxy { get { return _fk_proxy; } set { this._fk_proxy = value; } }
private ProxyData _usedProxy;
[Association(Storage = "_usedProxy", IsForeignKey = true, ThisKey = "fk_proxy", OtherKey = "pk_proxy")]
public ProxyData usedProxy { get { return _usedProxy; } set { this._usedProxy = value; } }
public string message { get; set; } = "";
public bool availability { get; set; }
public int planCode { get; set; }
public string planning { get; set; }
public override string ToString()
{
return string.Format("availability={0}, code={1}, message={2}", availability, code, message);
}
}
This is one of the child classes
[Table(Name = "address")]
public class Address
{
private int _pk_address;
[Column(IsPrimaryKey = true, IsDbGenerated = true, Storage = "_pk_address")]
public int pk_address { get { return _pk_address; } set { this._pk_address = value; } }
private string _provId;
[Column(Storage = "_provId")]
public string provId { get { return _provId; } set { this._provId = value; } }
private string _zipcode;
[Column(Storage = "_zipcode")]
public string zipcode { get { return _zipcode; } set { this._zipcode = value; } }
private int _houseNumber;
[Column(Storage = "_houseNumber")]
public int houseNumber { get { return _houseNumber; } set { this._houseNumber = value; } }
private string _addressAddition;
[Column(Storage = "_addressAddition")]
public string addressAddition { get { return _addressAddition; } set { this._addressAddition = value; } }
public string ToAddresString()
{
return string.Format("{0} {1}{2}", this.provId, zipcode, houseNumber, addressAddition);
}
public override string ToString()
{
return string.Format("{0}:\t{1}\t{2}{3}", this.provId, zipcode, houseNumber, addressAddition);
}
}
I want to get SniffResult including the associated fields. But they are all null. This is the code I use:
SniffDAO dao = new SniffDAO();
var test = from sr in dao.SniffResults
where sr.fk_scan == 3
select sr;
foreach (var one in test)
{
Console.WriteLine(one.pk_SniffResult);
Console.WriteLine(one.address);
}
one.address gives me a null, what am I doing wrong?
This is the Dao class
public class SniffDAO
{
private string currentDir;
private DataContext db;
public Table<Scan> Scans { get; set; }
public Table<SniffResult> SniffResults { get; set; }
public Table<Address> Addresses { get; set; }
public SniffDAO()
{
db = new DataContext(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=********;Integrated Security=True;Asynchronous Processing=True");
db.ObjectTrackingEnabled = true;
Scans = db.GetTable<Scan>();
SniffResults = db.GetTable<SniffResult>();
Addresses = db.GetTable<Address>();
currentDir = Directory.GetCurrentDirectory();
}
public void save()
{
db.SubmitChanges();
}
}
You need to Include related entities like this:
SniffDAO dao = new SniffDAO();
var test = dao.SniffResults.Include(x=>x.address).Where(sr.fk_scan == 3);
foreach (var one in test)
{
Console.WriteLine(one.pk_SniffResult);
Console.WriteLine(one.address);
}
I found the solution thanks to #Kris. I now use:
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<SniffResult>(sr => sr.address);
dlo.LoadWith<SniffResult>(sr => sr.usedProxy);
dlo.LoadWith<SniffResult>(sr => sr.scan);
db.LoadOptions = dlo; //db is the DataContext
See https://msdn.microsoft.com/en-us/library/bb548760(v=vs.110).aspx for more info
public class AMCOMDB : DataContext
{
public Table<student> allStudents;
public Table<aClass> allClasses;
public AMCOMDB(string connection) : base(connection) { }
}
[Table(Name = "student")]
public class student
{
private string _studentName;
[Column(IsPrimaryKey =true,Storage ="_studentName")]
public string studentName
{
get { return this._studentName; }
set { this._studentName = value; }
}
private string _LARType;
[Column(Storage ="_LARType")]
public string LARType
{
get { return this._LARType; }
set { this._LARType = value; }
}
private string _studentType;
[Column(Storage = "_studentType")]
public string studentType
{
get { return this._studentType; }
set { this._studentType = value; }
}
private string _aviationLevel;
[Column(Storage = "_aviationLevel")]
public string aviationLevel
{
get { return this._aviationLevel; }
set { this._aviationLevel = value; }
}
private string _airDefenseLevel;
[Column(Storage = "_airDefenseLevel")]
public string airDefenseLevel
{
get
{
return this._airDefenseLevel;
}
set
{
this._airDefenseLevel = value;
}
}
private string _emergencyContact;
[Column(Storage = "_emergencyContact")]
public string emergencyContact
{
get
{
return this._emergencyContact;
}
set
{
this._emergencyContact = value;
}
}
[Table(Name = "grades")]
public class grades
{
private string _studentName;
[Column(IsPrimaryKey = true, Storage = "_studentName")]
public string studentName
{
get
{
return this._studentName;
}
set
{
this._studentName = value;
}
}
private int _ET;
[Column(Storage = "_ET")]
public int ET
{
get
{
return this._ET;
}
set
{
this._ET = value;
}
}
private int _CP;
[Column(Storage = "_CP")]
public int CP
{
get
{
return this._CP;
}
set
{
this._CP = value;
}
}
private int _SB;
[Column(Storage = "_SB")]
public int SB
{
get
{
return this._SB;
}
set
{
this._SB = value;
}
}
private int _EC;
[Column(Storage = "_EC")]
public int EC
{
get
{
return this._EC;
}
set
{
this._EC = value;
}
}
private int _finalGrade;
[Column(Storage = "_finalGrade")]
public int finalGrade
{
get
{
return this._finalGrade;
}
set
{
this._finalGrade = value;
}
}
}
[Table(Name = "classes")]
public class aClass
{
private string _classNumber;
[Column(IsPrimaryKey = true, Storage = "_classNumber")]
public string classNumber
{
get
{
return this._classNumber;
}
set
{
this._classNumber = value;
}
}
private string _courseSeries;
[Column(Storage = "_courseSeries")]
public string courseSeries
{
get
{
return this._courseSeries;
}
set
{
this._courseSeries = value;
}
}
private string _courseNumber;
[Column(Storage = "_courseNumber")]
public string courseNumber
{
get
{
return this._courseNumber;
}
set
{
this._courseNumber = value;
}
}
private string _distanceLearning;
[Column(Storage = "_distanceLearning")]
public string distanceLearning
{
get
{
return this._distanceLearning;
}
set
{
this._distanceLearning = value;
}
}
private string _classStartDate;
[Column(Storage = "_classStartDate")]
public string classStartDate
{
get
{
return this._classStartDate;
}
set
{
this._classStartDate = value;
}
}
private string _classEndDate;
[Column(Storage = "_classEndDate")]
public string classEndDate
{
get
{
return this._classEndDate;
}
set
{
this._classEndDate = value;
}
}
private string _primaryInstructor;
[Column(Storage = "_primaryInstructor")]
public string primaryInstructor
{
get
{
return this._primaryInstructor;
}
set
{
this._primaryInstructor = value;
}
}
private string _secondaryInstructor;
[Column(Storage = "_secondaryInstructor")]
public string secondaryInstructor
{
get
{
return this._secondaryInstructor;
}
set
{
this._secondaryInstructor = value;
}
}
private string _location;
[Column(Storage = "_location")]
public string location
{
get
{
return this._location;
}
set
{
this._location = value;
}
}
private string _TDYCosts;
[Column(Storage = "_TDYCosts")]
public string TDYCosts
{
get
{
return this._TDYCosts;
}
set
{
this._TDYCosts = value;
}
}
private string _studentCount;
[Column(Storage = "_studentCount")]
public string studentCount
{
get
{
return this._studentCount;
}
set
{
this._studentCount = value;
}
}
private List<grades> _classGrades;
[Column(Storage = "_classGrades")]
public List<grades> classGrades
{
get
{
return this._classGrades;
}
set
{
this._classGrades = value;
}
}
AMCOMDB ADB = new AMCOMDB(connectionString);
if (ADB.DatabaseExists())
{
var stud = ADB.GetTable<student>();
var clas = ADB.GetTable<aClass>();
IQueryable<string> query = from c in stud
where c.studentName.Length > 5
orderby c.studentName.Length
select c.studentName.ToUpper();
foreach (string name in query)
{
}
//var q = from a in ADB.GetTable<student>()
// select a;
//dtStudents = LinqQuerytoDataTable(q);
//var q1 = from a in ADB.GetTable<aClass>()
// select a;
//aClass c = new aClass();
//dtClasses = reformatDataTable(q1);
}
I receive the following when I try to get information from the database at (foreach (string name in query))
An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
Additional information: Invalid object name 'student'.
I also get this when I first create the database:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Data.Linq.dll
Additional information: Unable to determine SQL type for 'System.Collections.Generic.List`1[WindowsFormsApplication1.Form1+grades]'.
remove the word Name that is what worked for me
[Table("student")]
public class student
This is my model structure from which I want to use to create a treeview, with checkboxes on leaf nodes:
public class CategoryEntity : BaseEntity
{
public CategoryEntity()
: base()
{
}
private Guid _categoryId;
public Guid CategoryId
{
get { return _categoryId; }
set { _categoryId = value; InvokePropertyChanged("CategoryId"); IsDirty = true; }
}
private string _categoryname;
public string CategoryName
{
get { return _categoryname; }
set { _categoryname = value; InvokePropertyChanged("CategoryName"); IsDirty = true; }
}
private string _categorydescription;
public string CategoryDescription
{
get { return _categorydescription; }
set { _categorydescription = value; InvokePropertyChanged("CategoryDescription"); IsDirty = true; }
}
private string _categorytype;
public string CategoryType
{
get { return _categorytype; }
set { _categorytype = value; InvokePropertyChanged("CategoryType"); IsDirty = true; }
}
private Guid? _parentcategoryId;
public Guid? ParentCategoryId
{
get { return _parentcategoryId; }
set { _parentcategoryId = value; InvokePropertyChanged("ParentCategoryId"); IsDirty = true; }
}
}
The problem is that I am new to MVC and I don't know which controls to use to display this values in a tree structure. Can anyone suggest a way of doing this?
I populate a data grid with a list of objects that come from a repository like this:
public static IEnumerable<Order> GetOrdersForDataGrid()
{
IEnumerable<Order> query;
using (RSDContext = new RSDContext())
{
query = context.Orders.Include(o=>o.OrderDetails).ToList();
}
return query;
}
When I want to edit an order I pass the selected row to a new window like this:
OrderEditWindow orderEdit = new OrderEditWindow();
orderEdit.SelectedOrder = SelectedOrder;
orderEdit.ShowDialog();
Here I set the DataContext of the Window to:
DataContext = SelectedOrder;
In this window I have another data grid that binds to OrderDetails collection property of Order. The problem is on CRUD operations on OrderDetails. For example, after I add a new orderDetail like this:
private void AddProductDetailButton_OnClick(object sender, RoutedEventArgs e)
{
if (!ValidateProductDetail())
return;
var _selectedProduct = ProductAutoCompleteBox.SelectedItem as Product;
var selectedProduct = ProductsRepository.GetProductById(_selectedProduct.ProductId);
OrderDetail orderDetail = new OrderDetail();
orderDetail.Price = selectedProduct.Price;
orderDetail.ProductCode = selectedProduct.Code;
orderDetail.ProductName = selectedProduct.Name;
orderDetail.Quantity = int.Parse(QuantityNumericUpDown.Value.ToString());
orderDetail.Um = selectedProduct.Um;
orderDetail.Total = selectedProduct.Price * int.Parse(QuantityNumericUpDown.Value.ToString());
orderDetail.Group = selectedProduct.Subgroup.Group.Name;
orderDetail.Subgroup = selectedProduct.Subgroup.Name;
orderDetail.SupplierName = selectedProduct.Supplier.Name;
//orderDetail.Order=SelectedOrder;
//orderDetail.OrderId = SelectedOrder.OrderId;
SelectedOrder.OrderDetails.Add(orderDetail);
ProductAutoCompleteBox.Text = string.Empty;
QuantityNumericUpDown.Value = 1;
ProductAutoCompleteBox.Focus();
}
and then I call the update method from repository:
public static void UpdateOrder(Order order)
{
using (RSDContext context = new RSDContext())
{
context.Orders.Attach(order);
context.Entry(order).State = EntityState.Modified;
context.SaveChanges();
}
}
I get an error about OrderId. If i set manualy the navigation property and the id I don't get an error but changes dont get saved into db.
My Order model look like this:
public class Order : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public Order()
{
_OrderDetails = new ObservableCollection<OrderDetail>();
_OrderDetails.CollectionChanged += _OrderDetails_CollectionChanged;
}
void _OrderDetails_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
AttachProductChangedEventHandler(e.NewItems.Cast<OrderDetail>());
if (e.OldItems != null)
CalcualteTotals();
}
[NotMapped]
public decimal CalculatedTotal
{
get
{
return OrderDetails.Sum(x => x.Total);
}
}
public int OrderId { get; set; }
private int _Number;
public int Number
{
get { return _Number; }
set
{
_Number = value;
NotifyPropertyChanged("Number");
}
}
private DateTime _Date;
public DateTime Date
{
get { return _Date; }
set
{
_Date = value;
NotifyPropertyChanged("Date");
}
}
private bool _Canceled;
public bool Canceled
{
get { return _Canceled; }
set
{
_Canceled = value;
NotifyPropertyChanged("Canceled");
}
}
private string _ClientName;
public string ClientName
{
get { return _ClientName; }
set
{
_ClientName = value;
NotifyPropertyChanged("ClientName");
}
}
private string _ClientPhone;
public string ClientPhone
{
get { return _ClientPhone; }
set
{
_ClientPhone = value;
NotifyPropertyChanged("ClientPhone");
}
}
private string _DeliveryAddress;
public string DeliveryAddress
{
get { return _DeliveryAddress; }
set
{
_DeliveryAddress = value;
NotifyPropertyChanged("DeliveryAddress");
}
}
private decimal _Transport;
public decimal Transport
{
get { return _Transport; }
set
{
_Transport = value;
NotifyPropertyChanged("Transport");
}
}
private decimal _Total;
public decimal Total
{
get { return _Total; }
set
{
_Total = value;
NotifyPropertyChanged("Total");
}
}
private ObservableCollection<OrderDetail> _OrderDetails;
public virtual ObservableCollection<OrderDetail> OrderDetails
{
//get { return _OrderDetails ?? (_OrderDetails = new ObservableCollection<OrderDetail>()); }
get
{
return _OrderDetails;
}
set
{
_OrderDetails = value;
NotifyPropertyChanged("OrderDetails");
}
}
private void AttachProductChangedEventHandler(IEnumerable<OrderDetail> orderDetails)
{
foreach (var p in orderDetails)
{
p.PropertyChanged += (sender, e) =>
{
switch (e.PropertyName)
{
case "Quantity":
case "Price":
case "Total":
CalcualteTotals();
break;
}
};
}
CalcualteTotals();
}
public void CalcualteTotals()
{
NotifyPropertyChanged("CalculatedTotal");
}
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
}
And my OrderDetail model look like this:
public class OrderDetail : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public int OrderDetailId { get; set; }
public int OrderId { get; set; }
public Order Order { get; set; }
private int _ProductCode;
public int ProductCode
{
get { return _ProductCode; }
set
{
_ProductCode = value;
NotifyPropertyChanged("ProductCode");
}
}
private string _ProductName;
public string ProductName
{
get { return _ProductName; }
set
{
_ProductName = value;
NotifyPropertyChanged("ProductName");
}
}
private string _Um;
public string Um
{
get { return _Um; }
set
{
_Um = value;
NotifyPropertyChanged("Um");
}
}
private decimal _Price;
public decimal Price
{
get { return _Price; }
set
{
_Price = value;
NotifyPropertyChanged("Price");
NotifyPropertyChanged("Total");
}
}
private int _Quantity;
public int Quantity
{
get { return _Quantity; }
set
{
_Quantity = value;
NotifyPropertyChanged("Quantity");
NotifyPropertyChanged("Total");
}
}
private string _SupplierName;
public string SupplierName
{
get { return _SupplierName; }
set
{
_SupplierName = value;
NotifyPropertyChanged("SupplierName");
}
}
private string _Subgroup;
public string Subgroup
{
get { return _Subgroup; }
set
{
_Subgroup = value;
NotifyPropertyChanged("Subgroup");
}
}
private string _Group;
public string Group
{
get { return _Group; }
set
{
_Group = value;
NotifyPropertyChanged("Group");
}
}
public decimal _Total;
public decimal Total
{
get { return Quantity * Price; }
set
{
_Total = value;
NotifyPropertyChanged("Total");
}
}
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
}
I'm really trying to use some sort of unit of work and I don't understand how i'm supposed to apply CRUD on objects with child collections and keep the UI updated in the same time (by working in a ObservableCollection and using Binding ClientPhone, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged my parent window is updated as I type)
A final working solution:
using (RSDContext context = new RSDContext())
{
var details = order.OrderDetails;
order.OrderDetails = null;
List<int> OriginalOrderDetailsIds =
context.OrderDetails.Where(o => o.OrderId == order.OrderId).Select(o => o.OrderDetailId).ToList();
List<int> CurrentOrderDetailsIds = details.Select(o => o.OrderDetailId).ToList();
List<int> DeletedOrderDetailsIds = OriginalOrderDetailsIds.Except(CurrentOrderDetailsIds).ToList();
context.Entry(order).State = EntityState.Modified;
foreach (var deletedOrderDetailId in DeletedOrderDetailsIds)
{
context.Entry(context.OrderDetails.Single(o => o.OrderDetailId == deletedOrderDetailId)).State = EntityState.Deleted;
}
foreach (OrderDetail detail in details)
{
// Add.
if (detail.OrderDetailId == 0)
{
detail.OrderId = order.OrderId;
context.Entry(detail).State = EntityState.Added;
}
// Update.
else
{
context.Entry(detail).State = EntityState.Modified;
}
}
context.SaveChanges();
}
You could do this way for adding and updating the child, but not sure about deleted order details in the ui. If you don't want to get the order from entity, you need some kind of marking in the OrderDetail for deleted OrderDetail.
using (RSDContext context = new RSDContext())
{
var details = order.OrderDetails;
order.OrderDetails = null;
context.Entry(order).State = EntityState.Modified;
foreach (var detail in details)
{
if (detail.Id == 0)
{
// Adds.
detail.OrderId = order.Id;
context.Entry(detail).State = EntityState.Added;
}
else if (detail.IsDeleted)
// Adds new property called 'IsDeleted'
// and add [NotMapped] attribute
// then mark this property as true from the UI for deleted items.
{
// Deletes.
context.Entry(detail).State = EntityState.Deleted;
}
else
{
// Updates.
context.Entry(detail).State = EntityState.Modified;
}
}
order.OrderDetails = details;
context.SaveChanges();
}
public List<Empleado> ListarEmpleados()
{
List<Empleado> returnList = new List<Empleado>();
var lista = from u in DB.tabEmpleado
select new
{
u.idEmpleado,
u.idUsuario,
u.Nombre,
u.Apellidos,
u.Telefono1
};
foreach (var e in lista)
{
Empleado empleado = new Empleado();
empleado.idEmpleado = e.idEmpleado;
empleado.idUsuario = e.idUsuario;
empleado.nombre = e.Nombre;
empleado.apellidos = e.Apellidos;
empleado.telefono1 = e.Telefono1;
returnList.Add(empleado);
}
return returnList;
}
This is a WCF service, when is called it returns StackOverflow error in the class definition, exactly in the Set property of idEmpleado.
Class definition is here.
[DataContract]
public class Empleado
{
private int _idEmpleado;
[DataMember(IsRequired = false)]
public int idEmpleado
{
get { return _idEmpleado; }
set { idEmpleado = value; } ERROR
}
private int _idUsuario;
[DataMember(IsRequired = false)]
public int idUsuario
{
get { return _idUsuario; }
set { idUsuario = value; }
}
private string _nombre;
[DataMember(IsRequired = false)]
public string nombre
{
get { return _nombre; }
set { nombre = value; }
}
private string _apellidos;
[DataMember(IsRequired = false)]
public string apellidos
{
get { return _apellidos; }
set { apellidos = value; }
}
private string _telefono1;
[DataMember(IsRequired = false)]
public string telefono1
{
get { return _telefono1; }
set { telefono1 = value; }
}
}
}
Does anybody know where the error is?
Thanks in advance.
You are setting the value of the property by calling the property setter again, instead of directly setting its backing field. This causes an infinite recursion and a stack overflow as a result.
public int idEmpleado
{
get { return _idEmpleado; }
set { idEmpleado = value; } // SHOULD BE _idEmpleado = value
}