DevExpress LookUpEdit Column Binding To Navigation Property - winforms

Good day!
I'm having an issue with the DevExpress LookUpEdit I can't figure out what the problem is.
I'm use Entity Framework list as a datasource.
public partial class provider_scheme : BaseEntity
{
public provider_scheme()
{
}
public int Provider_Scheme_RowID { get; set; }
public int Currency_RowID { get; set; }
public string Provider_Scheme_Name { get; set; }
public virtual currency currency { get; set; }
}
public partial class currency : BaseEntity
{
public currency()
{
provider_scheme = new HashSet<provider_scheme>();
}
public int Currency_RowID { get; set; }
public string Currency_ISOCode { get; set; }
public virtual ICollection<provider_scheme> provider_scheme { get; set; }
}
I'm setting the Datasource property of the LookUpEdit to IEnumerable<provider_scheme>, and setting up two column field names in my LookUpEdit. One for 'Provider_Scheme_Name' and one for 'currency.Currency_ISOCode'. But for some reason only the 'Provider_Scheme_Name' column values are showing. I've also checked and the 'currency' navigation property is being loaded.
Thanks in advance for your help

A bit late for an answer, but you might consider using the GridLookupEdit control instead. It permits adding all the columns you want

Related

Entity Framework Core - How to include/populate a navigation property with custom(1-to-1) query in EF?

How to include/populate a navigation property with custom(1-to-1) query in EF?
e.g.
public class Item {
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("Id")]
public ItemCost LatestCost {get; set; }
}
public class ItemCost {
public int Id { get; set; }
public DateTime From { get; set; }
public DateTime? To { get; set; }
public decimal Cost { get; set; }
}
Goal is to populate the LatestCost property of the Item with it's latest cost from ItemCosts. How is this being accomplished with EF or what's your take on this?
Is it possible to do a custom query within .Include/.ThenInclude methods?
e.g.
.ThenInclude(a => { a.LatestCost = (from a _db.ItemCosts
where... select a).SingleOrDefault() })...
You could use a virtual get-only property. Your nav property should really be an ICollection<ItemCost>. In this example I'm assuming the Id property in the ItemCost class is the id of the related Item, but it's not clear. Tip: using nameof(property) instead of hard-coding the property name will allow the compiler to catch errors with the name if you were to change it for some reason. The [NotMapped] attribute tells Entity Framework to not try and map the property to a database field.
public class Item {
public int Id { get; set; }
public string Name { get; set; }
public ICollection<ItemCost> ItemCosts {get; set; }
[NotMapped]
public virtual ItemCost LatestCost
{
get
{
return ItemCosts.OrderByDescending(x => x.From).FirstOrDefault();
}
}
}
public class ItemCost {
public int Id { get; set; }
public DateTime From { get; set; }
public DateTime? To { get; set; }
public decimal Cost { get; set; }
[ForeignKey(nameof(Id))]
public virtual Item Item { get; set; }
}

Update 2 tables from Edit Action (ViewModel).

I want first to say sorry, because I'm new to this programming language, so forgive me if I say or do something wrong.
I created a project with 3 class libraries (1 of them contains the tables from sql server). I made a ViewModel based on the tutorial from: "http://tutlane.com/tutorial/aspnet-mvc/how-to-use-viewmodel-in-asp-net-mvc-with-example", and now I want to be able to update the data in those tables, but I don't know how. I tried to do something but it failed.
`namespace BOL2.ViewModel
{
public class NIRIO
{
[Key]
public int ID { get; set; }
public int Number { get; set; }
public Nullable Date { get; set; }
public int NirID { get; set; }
[DisplayName("TypeID")]
public int TipID { get; set; }
public int SupplierID { get; set; }
public int ProductID { get; set; }
public Nullable<System.DateTime> EntryDate { get; set; }
public Nullable<System.DateTime> ExitDate { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
public decimal Total { get; set; }
public BOL2.tbl_NIR tbnir;
public BOL2.tbl_I_O tblio { get; set; }`
This is my ViewModel. It contains data from those 2 tables (tbl_NIR, first 3, and the others from tbl_I_O. I saw something on my research that they had a repository class, but I don't now if I should do another class for the viewmodel or I sould use the 2 that I already have? Any help is greatly appreciated.
You could do something similar to this.
public void UpdateCar(CarViewModel viewModel)
{
using (DataContext context = new DataContext())
{
CarEntity dataModel = context.CarEntities.where(x => x.Id == viewModel.Id).First();
dataModel.Name = viewModel.Name;
dataModel.Type = viewModel.Type;
context.SaveChanges();
}
}
You need to create your model objects from your view model and set the values for the models.
I'm not quite sure what is the method you used and didn't work. Just in case you tried to update the tables through the view, then you cannot do that. Because you have join
inform IT explanation
I recommend you to create a stored procedure in your database. Then call the procedure trough the code. It's secure and fast. explained here

EntityWrapper Confusion

WPF
Entity Framework 6.0
Database first, entities are generated by TT file.
I'm having some problems with EntityWrapper, and can't find any useful information about it.
I have some entities, that when generated looks like this:
//generated code
public partial class scm_SupplierDepot : IPartsEntity, INotifyPropertyChanged
{
[...]
public virtual dms_Address dms_Address { get; set; }
}
public partial class dms_Address : IPartsEntity, INotifyPropertyChanged
{
//shortened for brevity
public System.Guid AddressId { get; set; }
public string StreetNumber { get; set; }
public string StreetName { get; set; }
public string ApartmentNumber { get; set; }
public string City { get; set; }
public string StateProvince { get; set; }
public string PostalCode { get; set; }
public string HouseName { get; set; }
public string Country { get; set; }
public string Address2 { get; set; }
public string County { get; set; }
//INotifyPropertyChanged
[..]
}
I extend the address class slightly with an interface:
public partial class dms_Address : IAddress { }
public interface IAddress
{
String StreetNumber { get; set; }
String StreetName { get; set; }
String ApartmentNumber { get; set; }
String Address2 { get; set; }
String City { get; set; }
String StateProvince { get; set; }
String PostalCode { get; set; }
String County { get; set; }
String Country { get; set; }
}
I am having some confusion and issues around getting the dms_Address entity from the scm_SupplierDepot entity. In most cases I can cast the Depot.dms_Address as IAddress and work with the entity with no issues.
But when I try binding this object to a Custom Control, the actual object that the control receives is a EntityWrapper< dms_Address > or EntityWrapperWithoutRelationships< dms_Address >
I had to make my control's dependency property accept an object, rather than an IAddress as I would prefer. Now I cannot work with the object as it will not cast to IAddress. I can't even cast it to EntityWrapper as I can't figure out the correct namespace to include.
public static readonly DependencyProperty AddressProperty = DependencyProperty.Register("Address", typeof(object), typeof(AddressForm), new FrameworkPropertyMetadata(null, AddressChanged));
public object Address
{
get { return (object)GetValue(AddressProperty); }
set { SetValue(AddressProperty, value); }
}
More information about my Custom Control and this Dependency Property issue can be read in a previous question: WPF Custom Control: DependencyProperty never Set (on only 1 of many properties)
Questions:
Can anyone explain to me what is going on here?
I don't understand where this wrapper is coming from. How can I make it go away?
How can I get the control to receive the IAddress instead of the wrapper?
Or how can I cast the EntityWrapper object to IAddress so I can access the properties in code? (oddly enough the template bindings work fine)
I figured out how to do what I needed by using Reflection.
Type objectType = Address.GetType();
Type iAdd = objectType.GetInterface("IAddress");
if (iAdd != null)
{
PropertyInfo info = objectType.GetProperty("StateProvince");
if (info != null)
{
string currentProvince = info.GetValue(Address) as string;
if (currentProvince != newValue)
info.SetValue(Address, newValue);
}
}
I am still stumped on why I'm seeing this behaviour; if it has the interface, why can't I cast it?
Type iAdd = Address.GetType().GetInterface("IAddress"); //iAdd is not null,
IAddress IA = (Address as IAddress); //IA is null
.
In the end I managed to switch my code around to make all of this code unnecessary >.<

WPF DataGrid build from List<SomeInterface> using AutoGenerateColumns

I'm trying to load data to DataGrid from a generic list.
the relevant code:
XAML:
<Grid>
<DataGrid DataContext="{Binding Lines}"
ItemsSource="{Binding}"
AutoGenerateColumns="True">
</DataGrid>
</Grid>
C#:
public IList<IReportLine> Lines { get; set; }
public interface IReportLine {}
public class ReportLine : IReportLine
{
public string A { get; set; }
public string B { get; set; }
}
It seems that the columns are taken from the type IReportLine - so I'm getting an empty DataGrid.
Of course, if I'm changing IReportLine definition to:
public interface IReportLine
{
string A { get; set; }
string B { get; set; }
}
it works perfectly, but i can't do that because every class that implement IReportLine has different Properties.
What can I do in order to make the columns be generated from the dynamic type of IReportLine?
Or have any other idea to solve my problem?
Thanks!
EDIT:
The interface holding the Lines property and the class implementing the interface(one of many):
interface IReport
{
string Header { get; set; }
IList<IReportLine> Lines { get; set; }
}
public class Report : IReport
{
public string Header
{
get;
set;
}
public IList<IReportLine> Lines
{
get;
set;
}
}
The DataContext of the DataGrid is IReport object.
So I can't Change
public IList<IReportLine> Lines { get; set; }
to
public IList<ReportLine> Lines { get; set; }
Instead of defining members in interface, make the list to be more verbose. You gotta tell dataGrid at least some specific type so that it can look for properties in it.
Change
public IList<IReportLine> Lines { get; set; }
to
public IList<ReportLine> Lines { get; set; }
UPDATE
Like I mentioned above, if you want columns to be auto generated, you gotta supply some specific type.
Consider scenario where you have another class say AnotherReportLine implementing IReportLine:
public class AnotherReportLine : IReportLine
{
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
}
Now, you can add both class instances in Lines collection like this:
Lines = new List<IReportLine>();
Lines.Add(new ReportLine() { A = "A1", B = "B1" });
Lines.Add(new AnotherReportLine() { A = "A1", B = "B1", C = "C1" });
What should be the columns list now?
A | B OR A | B | C.
WPF engine cannot infer that without your help.
That brings you down to three possible ways:
Move properties to interface.
Make the list of more specific type.
Last set AutoGenerateColumns to False and provide your own list of columns you want to show.

RIA Services validation order

So I have some validations in my metadata like the following:
internal sealed class Metadata
{
[Key]
[ReadOnly(true)]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string CountryCode { get; set; }
[CustomValidation(typeof(PCNValidator), "SetNumber")]
public string Number { get; set; }
}
I have some code to validate the Number property as you can see here, but I need the other Required properties of some of the attributes to fire first.
How can I achieve that?
You could make your PCNValidator return success until name and countryCode have been completed. Once that condition had been satisfied you could then do the remaining validation checks on Number. Not a wonderful solution but it does allow for your ordering requirement.
As far as I could find out, the answer to this question is NO, there's no way to tell an order in property-level validation.
Having said that, every Required property is validated before the others.
What I did in order to achive what I wanted was adding a type validator for the class. Type validators are always fired after property validators, which is exactly what I needed.
here's my code:
[MetadataType(typeof(PCN.Metadata))]
[CustomValidation(typeof(PCNValidator), "ValidateInsert")]
public partial class PCN : IValidate
{
internal sealed class Metadata
{
[Key]
[ReadOnly(true)]
public int Id { get; set; }
[Required(AllowEmptyStrings=false)]
public string Name { get; set; }
[Required]
public string CountryCode { get; set; }
}
}

Resources