DataGridView not displaying values using LINQ - c#

It's very simple for the user.
They select the type of part, manufacturer from a ComboBox, and search the part code in a text box. Click search and the results return in a DataGridView.
Code:
var mType = CmbType.SelectedItem.ToString();
var mManufacturer = CmbMfr.SelectedValue.ToString();
var mCode = Convert.ToString(TxtProductCode.Text);
switch (mType)
{
case "Faucets":
var faucets = Resources.Accessor.SearchFaucets(mManufacturer, mCode);
DgInventory.DataSource = faucets;
break;
case "Parts":
var parts = Resources.Accessor.SearchParts(mManufacturer, mCode);
DgInventory.DataSource = parts;
break;
}
Accessor Code:
public static List<TblFaucets> SearchFaucets(string mId, string mCode)
{
var dataConnect = new PxLinqSqlDataContext();
return (from f in dataConnect.GetTable<TblFaucets>()
where (f.Mfr == Convert.ToInt32(mId))
where (f.Code == mCode)
select f).ToList<TblFaucets>();
}
What "messes up" is the results:
ID: correct
Mfr: is the ID from its table, not the name
Code: Correct
Description: correct
Price: correct
Date: correct
Manufacturer: I don't know why this is even here, its result is "PXDB.TblManufacturers

First, PXDB.TblManufacturers seems to be a relation from tblFaucets to tblManufactureres.
Mfr seems to be the foreignKey value within your faucets table refering to a manufacturer.
You may try creating an anonymous type holding only those data you want to. Within your select clause pick your data - as well as any relational data.
public static List<DisplayFaucet> SearchFaucets(string mId, string mCode)
{
var dataConnect = new PxLinqSqlDataContext();
return (from f in dataConnect.GetTable<TblFaucets>()
where (f.Mfr == Convert.ToInt32(mId))
where (f.Code == mCode)
select new DisplayFaucet () { // create anonymous object
ID = f.ID, // only holding the data you want to
Manufacturer = Manufacturer.Name, // assuming there is property Name within your manufacturer table?!
Code = f.Code,
Description = f.Description,
Price = f.Price,
Date = f.Date
}).ToList();
}
Add another class to hold your data to display
public class DisplayFaucet
{
public int ID { get; set; }
public string Manufacturer { get; set; }
public string Code { get; set; } // check type
public string Description { get; set; }
public doublePrice{ get; set; } // check type
public DaetTime Date { get; set; } // check type
}
Note that SearchFaucets(..) may no longer return items of type tblFaucet! Instead I created a new class. This one contains all data which should be displayed!

Related

How to convert a linq query to ToList() to use extended properties

private IQueryable<SubjectDataViewModel> GetData()
{
var subject = this.DbContext.Subjects.AsQueryable(); //sql view
var data =
from subject in subjects
let treatment = this.DbContext.TreatmentFactor.FirstOrDefault(x => x.TreatmentFactorId == subject.ActiveTreatmentFactor)
select new SubjectDataViewModel
{
Name = subject.Name,
Gender = subject.Gender,
Version = subject.Version.IsEnumToValueDisplay() // extented method which displays enum DisplayName property into string
};
return data.AsQueryable();
}
This is the View Model i am populating into as per query above .
public class SubjectDataViewModel
{
public string Name {get;set;}
public string Gender {get;set;}
public string Version {get;set;} // string type return
}
This is Subject Sql View
public class Subjects
{
public string Name {get;set;}
public string Gender {get;set;}
public Version Version {get;set;} // enum return type
}
Enum that is used for Version . Need to Used the ToEnumDiplayValue() extended method in the linq query to pull the Diplay Name i.e Original instead of Database value which is 0 and 1 which will show first or second.
public enum Version
{
[Display(Name = "Original")]
first= 0,
[Display(Name = "Not Original")]
second = 1,
}
So I want to get the DisplayName for the Version which can be done by using our own extended method that using reflection to get the Display name from the enum .
But i cannot use it in the in memoryobject . It has to be converted to .ToList() for.
That is what i want. I hope i am clear. Thank you for your time .
As of now my code will throw ERROR message since i cannot use extended property in Linq.
Try
private IQueryable<SubjectDataViewModel> GetData()
{
var subject = this.DbContext.Subjects.AsQueryable(); //sql view
var data =
from subject in subjects
let treatment = this.DbContext.TreatmentFactor.FirstOrDefault(x => x.TreatmentFactorId == subject.ActiveTreatmentFactor)
select new SubjectDataViewModel
{
Name = subject.Name,
Gender = subject.Gender,
VersionEnum = subject.Version // Version Enum
};
return data.AsQueryable();
}
Use below code to convert GetData() into the list afterwards use IsEnumToValueDisplay() method.
var list = GetData().ToList();
foreach (var item in list)
{
item.Version = item.VersionEnum.IsEnumToValueDisplay(); // Get value from Version Enum
}
Change Model SubjectDataViewModel
public class SubjectDataViewModel
{
public string Name {get;set;}
public string Gender {get;set;}
public Version VersionEnum {get;set;}
public string Version {get;set;}
}

Populating a list that contains an array using linq

I am using visjs.net to display a schedule
I'm having trouble writing LINQ to populate a list that contains a property that is an array
Here is the visjs documentation visjs doco
and some example code visjs source code
Here is an abridged version of the sample in javascript. I need to populate this JSON from a MVC controller instead of javascript
var groups = new vis.DataSet();
groups.add([
{
id: 1,
content: "Lee",
nestedGroups: [11,12]
}
]);
groups.add([
{
id: 11,
content: "cook",
},
{
id: 12,
content: "shop",
}
]);
spoiler alert: I don't know how to populate the nestedGroups property
This is the class I built for it:
public class TimelineGroups
{
public int id { get; set; }
public string content { get; set; }
public string className { get; set; }
public string orderBy { get; set; }
public string[] nestedGroups { get; set; }
}
This is the controller method that populates it, excluding the nestedGroups property, and this works just fine:
public JsonResult EmployeeGroups()
{
List<TimelineGroups> e = (
from emp in db.Employees
where emp.Emp_Status == 1 && emp.EmployeeRole.IsChargeable == "Y"
orderby emp.EmpRole_ID, emp.Emp_Last_Name
select new TimelineGroups()
{
id = emp.Emp_ID,
content = emp.Emp_Name,
orderBy = emp.EmpRole_ID.ToString(),
className = "bte-" + emp.EmployeeRole.EmpRoleName
}
).ToList();
return Json(e, JsonRequestBehavior.AllowGet);
}
This all works correctly but now I want to add nested groups.
But I don't know the LINQ required to 'pivot' the required data into an array inside a collection.
This is what I have so far:
public JsonResult EmployeeClientGroups()
{
// First load the client list which are children of employees
List<TimelineGroups> cg = (
from sw in db.ScheduleWorks
where sw.EndDate > DateTime.Now
select new TimelineGroups()
{
id = sw.Employee.Emp_ID * 1000 + sw.CustomerId,
content = sw.Customer.Customer_Name
}).Take(1000).Distinct().ToList();
// now load the employee list
// This includes client children
List<TimelineGroups> eg = (
from sw in db.ScheduleWorks
where sw.EndDate > DateTime.Now
select new TimelineGroups()
{
id = sw.Employee.Emp_ID,
// How do I populate this with sw.Employee.Emp_ID * 1000 + sw.CustomerId
nestedGroups = // What magic do I put here?
content = sw.Employee.Emp_Name,
}).Take(1000).Distinct().ToList();
// Add the employee groups to the client groups
cg.AddRange(eg);
return Json(cg, JsonRequestBehavior.AllowGet);
}
I need to get all the client ID's for a given Employee and "pivot" them into an array, suitable to post back as JSON
To make them unique and match the children id's, the value I need to pivot in is:
sw.Employee.Emp_ID * 1000 + sw.CustomerId
Can this be done inline in a LINQ statement?
So it turns out this was kind of answered here but I will document my solution
This is the code that I eventually used:
public class TimelineGroups
{
public string id { get; set; }
public string content { get; set; }
public string className { get; set; }
public string orderBy { get; set; }
public List<string> nestedGroups { get; set; }
}
List<TimelineGroups> eg = (
from sw in db.ScheduleWorks
where sw.EndDate > DateTime.Now
where sw.Employee.Emp_Status == 1
group (sw.EmployeeId.ToString() + "." + sw.CustomerId.ToString())
by new {
id = sw.EmployeeId.ToString(),
EmpName = sw.Employee.Emp_Name,
EmpOrder = sw.Employee.EmpRole_ID.ToString()
}
into g
select new TimelineGroups()
{
id = g.Key.id,
// find the list of employee+client keys
nestedGroups = g.ToList(),
content = g.Key.EmpName,
orderBy = g.Key.EmpOrder
})
.Take(1000)
.ToList();
Note no Distinct
The argument to group is the field holding the values that i want to "pivot"
then the part after by is the actual 'key' that will be grouped on
I needed to use a List() rather than an array (maybe I could've used ToArray though?)
Once this is grouped into an intermediate variable g, you can use g.ToList() to get the 'pivoted' values
Hopefully this will help someone else one day, maybe even someone using the visjs library
#Tetsuya Yamamoto fiddle pointed me in the right direction

Binding two lists into one data grid view

So I have two lists (Members and RealEstate)
I want my DataGridView to display results of the MemberID that was written in a text box I have.
Results include:
MemberID, FirstName from the Members List and
EstateType, EstatePrice, EstateArea from the RealEstate List
My code is as follows :
List<Members> member = FrmSell.MembersList.FindAll(owner => owner.MemberID == int.Parse(FrmSell.txt));
List<RealEstate> realestate = FrmSell.EstateList;
dgvProperty.DataSource = member;
dgvProperty.DataSource = realestate;
And when I click on my button it only displays the results from the second list which is the RealEstate list and not the first one, I want to display results from both lists combined into a single data grid view.
If you need any more clarification please do tell me.
Sample data from the list :
//Sample data
Members m1 = new Members(001,"Ahmed","Muhairy",503299999);
MembersList.Add(new Members(002,"Khalfan","AlMarri",502344556));
RealEstate r1 = new RealEstate("Villa",35000,"Quoz",4,2);
EstateList.Add(new RealEstate("House",55000,"Sharjah",6,4));
You will need to combine the fields from the matching entries in the two lists into either a DataSet or DataTable, or into a list of items of a new class that contains the fields from both input types.
For this to work, there must be a field in either the Member or RealEstate class that allows matching up the entries from both input lists.
As an example, I am going to assume the following: your RealEstate class has an OwnerID field, whose value identifies one of the members in the MembersList, because it is equal to the member's MemberID value.
Now you can do the following:
// This combines the fields from Member and RealEstate
// for a row to be displayed in the data grid.
public class MemberRealEstate
{
public int MemberID { get; set; }
public string MemberName { get; set; }
public int EstateID { get; set; }
public string EstateType { get; set; }
public double EstatePrice { get; set; }
public string EstateArea { get; set; }
}
And create a new list, combining entries from the other two:
var forMemberId = int.Parse(FrmSell.txt);
var memberRealEstateList =
(from estate in FrmSell.EstateList
from member in FrmSell.MembersList
where member.MemberID == forMemberId && member.MemberID == estate.OwnerID
select new MemberRealEstate() {
MemberID = member.MemberID,
MemberName = member.FirstName + " " + member.LastName,
EstateID = estate.EstateID,
EstateType = estate.EstateType,
EstatePrice = estate.EstatePrice,
EstateArea = estate.EstateArea
}).ToList();
Now you can assign this list as the DataSource for your DataGridView:
dgvProperty.DataSource = memberRealEstateList;

Dapper: Not able to parse string from dbf(Error parsing column)

I want to use dapper to query over dbf files. In my file example.dbf I have two columns:
Value - type NUMERIC
Name - type CHARACTER
I write class ExampleDbf
class ExampleDbf
{
public int Value { get; set; }
public string Name { get; set; }
}
Now I want to write two simple query
var listOne = connection.Query<ExampleDbf>("SELECT value FROM Example");
var listTwo = connection.Query<ExampleDbf>("SELECT name, value FROM Example");
ListOne are OK but when I execute listTwo I Have following System.Data.DataException:
Additional information: Error parsing column 0 (name=System.Byte[] - Object)
When I use standard DataReader I must write something like that
example.name = System.Text.Encoding.ASCII.GetString((byte[])reader["name"]).Trim();
Of course I may write something like this:
class ExampleDbf2
{
public int Value { get; set; }
public byte[] Name { get; set; }
public string StringName
{
get
{
return System.Text.Encoding.ASCII.GetString((byte[])Name ).Trim();
}
}
}
So now it works
var listTwo = connection.Query<ExampleDbf2>("SELECT name, value FROM Example");
But this solution is very ugly, maybe someone have better solution.
You could always return a dynamic, then map it to your object and perform the transformation operation during object initialization.
var listTwo = connection.Query<dynamic>("SELECT name, value FROM Example")
.Select(x => new ExampleDbf
{
Value = x.value,
Name = System.Text.Encoding.ASCII.GetString((byte[])x.name).Trim()
}).ToList();

C# Find and edit single object on list

public class kDrinki
{
public int id {get; set;}
public string nazwa { get; set; }
public string skladniki { get; set; }
public string opis { get; set; }
public string sciezka { get; set; }
public kDrinki(int _id, string _nazwa, string _skladniki, string _opis, string _sciezka)
{
id = _id;
nazwa = _nazwa;
skladniki = _skladniki;
opis = _opis;
sciezka = _sciezka;
}
}
I have got that class. I created List lst_pDrinkow of object and added some form XML. I don't know how to find only single object (using object id not list id) from list and edit all his data(not only single parameter).
You could try something like this:
var obj = lst_pDrinkow.SingleOrDefault(x=>x.id==Id);
Where Id is the id of the object you are looking for.
If there is an object with the supplied Id, you will get it. Otherwise, the result would be null.
Once you get the object you want, it's very easy to update it's data.
if(obj!=null)
{
obj.nazwa = "new value";
// update the values of the other properties with the same way.
}
Update
While it is not your case, I have to note here that if there are more than one objects with the supplied Id, then you will get an exception. We usually use the SingleOrDefault, when we are sure that the object we are looking for it is unique if at all exists.
More formally:
Returns the only element of a sequence, or a default value if the
sequence is empty; this method throws an exception if there is more
than one element in the sequence.
as it is stated here.
List<kDrinki> items = new List<kDrinki>();
var tmp1 = items.SingleOrDefault(a => a.id == 10);
tmp1.skladniki = "new value";
var tmp2 = items.SingleOrDefault(a => a.opis.Contains("some strings"));
tmp2.skladniki = "new value2";

Categories

Resources