Using Linq to aggregate from array to single var - c#

I have an accordion that binds data for each item from an array.
I want that for every time that I bound the data I will loop through all of the array and aggregate all of the items with the same id and create a long string with a name from a cell. In the code the name oneJob.order_id does not exist and I don't know why.
protected string GetAllProffesions(int orderID)
{
IEnumerable<string> allProf;
orderID = 544;
Job[] curItems = null;
curItems = JobManager.GetJobs(RangeID, GetParam());
allProf = from oneJob in curItems
where oneJob.order_id == orderID
select oneJob.profession_name;
return Convert.ToString(allProf);
}

This is because your job class doesn't have a property called order_id. Check your spelling.
Also, you probably don't want to do Convert.ToString(allProf), as I expect this will give you the type name instead of all the professions concatenated. Try this instead:
string.Join(", ", allProf.ToArray());

Related

Query to get list of IDs that have records in the table

I have a DynamoDb table (named Fruit) with the following properties:
FruitId - string
CreatedDate - date
Type - number
Payload - blob
I also have a local list of strings List<string> fruitIds;.
I want to query the Fruit table and get only the Ids that have a corresponding record (i.e. exist) in the table.
What is a good way of doing that? Right now, I am looping over each Id in fruitIds and making a separate query to DyanmoDb to see if I get a record back, if I do, I then save that Id to another local variable called fruitIdsThatExistInDyanmoDb.
Is there a better way?
public IQueryable <fruits> GetAllfruitsIDs() {
return fruits.AsQueryable();
}
var data = GetAllfruitsIDs();
// Or u can use this :
public IEnumerable<fruits> GetAllfruitsIDs() {
return fruits.AsQueryable().ToList;
}
var data = GetAllfruitsIDs();
Using Linq, its very simple, just check if item's FruitId is in fruitIds:
var result = fruits.Where(f => fruitIds.Contains(f.FruitId));
to save their Ids in a new local variable as you said:
List<string> fruitIdsThatExistInDyanmoDb = fruits.Where(f => fruitIds.Contains(f.FruitId))
.Select(f=> f.FruitId).ToList();

Update collection from DbSet object via Linq

i know it is not complicated but i struggle with it.
I have IList<Material> collection
public class Material
{
public string Number { get; set; }
public decimal? Value { get; set; }
}
materials = new List<Material>();
materials.Add(new Material { Number = 111 });
materials.Add(new Material { Number = 222 });
And i have DbSet<Material> collection
with columns Number and ValueColumn
I need to update IList<Material> Value property based on DbSet<Material> collection but with following conditions
Only one query request into database
The returned data from database has to be limited by Number identifier (do not load whole database table into memory)
I tried following (based on my previous question)
Working solution 1, but download whole table into memory (monitored in sql server profiler).
var result = (
from db_m in db.Material
join m in model.Materials
on db_m.Number.ToString() equals m.Number
select new
{
db_m.Number,
db_m.Value
}
).ToList();
model.Materials.ToList().ForEach(m => m.Value= result.SingleOrDefault(db_m => db_m.Number.ToString() == m.Number).Value);
Working solution 2, but it execute query for each item in the collection.
model.Materials.ToList().ForEach(m => m.Value= db.Material.FirstOrDefault(db_m => db_m.Number.ToString() == m.Number).Value);
Incompletely solution, where i tried to use contains method
// I am trying to get new filtered collection from database, which i will iterate after.
var result = db.Material
.Where(x=>
// here is the reasonable error: cannot convert int into Material class, but i do not know how to solve this.
model.Materials.Contains(x.Number)
)
.Select(material => new Material { Number = material.Number.ToString(), Value = material.Value});
Any idea ? For me it is much easier to execute stored procedure with comma separated id values as a parameter and get the data directly, but i want to master linq too.
I'd do something like this without trying to get too cute :
var numbersToFilterby = model.Materials.Select(m => m.Number).ToArray();
...
var result = from db_m in db.Material where numbersToFilterBy.Contains(db_m.Number) select new { ... }

How to display an object property in a drop down list in VB.Net/C# and ASP.NET

I am working with VB.Net and ASP.net, but C# code are welcome too.
I have a list of Clients, the client attributes are:
-ClientID
-FullName
Sample data:
-ClientID:1
-FullName:John Binder
-ClientID:2
-FullName:Leah Brown
And I have a list of Agreements "lstAgreements", their attributes are:
-AgreementID
-ClientID
-Date
Sample data:
AgreementID:5
ClientID:2
Date:12/30/16
AgreementID:7
ClientID:1
Date:12/29/16
"Client" and "Agreement" are entities classes with an existing relation:One client can have many Agreements.
I can retrieve all the agreements with:
Dim lstAgreements As List(Of Agreement) =GetAllAgreements()
And the Agreement Class has a property to get the client object:
lstAgreements(0).ClientObject.FullName
Then I can populate a drop down list with "lstAgreements"
myDropDownList.DataSource = lstAgreements
myDropDownList.DataValueField = "AgreementID"
myDropDownList.DataTextField = "ClientID"
myDropDownList.DataBind()
My question is, how can I display "ClientFullName" instead "ClientID" in the drop Down List?
I am trying this code but it does not work:
myDropDownList.DataSource = lstAgreements
myDropDownList.DataValueField = "AgreementID"
myDropDownList.DataTextField = "ClientObject.FullName"
myDropDownList.DataBind()
I noticed that using "ClientObject.FullName" in a DataList control it works fine, but in Drop Down List it doesn't.
Any suggestion?
Thanks in advance
You could loop through lst Agreements rather than using a datasource/databind and create the list items yourself?
something like
foreach (Agreement a in lstAgreements)
{
myDropDownList.Items.Add(new ListItem(a.ClientObject.FullName, a.AgreementId))
}
or use linq to set your full name from the client list if you have no full name method to return full name in agreement.
Why didn't you just use it like this :
myDropDownList.DataTextField = "FullName";
Update:
Obviously , Agreement does not contain a property with the name 'FullName'. it has -AgreementID -ClientID -Date properties.
I would recommend using Linq to retrive the data you need from multiple lists (C#):
public class CustomList
{
public string FullName { get; set; }
public int AgreementID{ get; set; }
}
var Custom = from i in listofClients
from j in listofAgreements
Where i.ClientID == j.ClientID
select new CustomList{
FullName = i.FullName ,
AgreementID = j.AgreementID
}.ToList();
Now you can use Custom to bind it to your DropDownList:
myDropDownList.DataSource = Custom ;
myDropDownList.DataValueField = "AgreementID";
myDropDownList.DataTextField = "FullName";
myDropDownList.DataBind();
Depending on your controls (though I think this is a default behavior), you can also do this by overriding the ToString() method for your object. Normally, this would give a string representation of its type, but if you change the return value to be the desired property, that will be the value of ToString(). If you then bind to something like IEnumerable lstAgreements, you don't even have to property search. The value for the dropdownlist item will be the object, and the text will be its ToString() output.
Pseudo:
prop int AgreementID
prop int ClientID
prop DateTime Date
prop ClientObject CO;
public IEnumerable<Agreement> GetAllAgreements()...
public override string ToString()
{
return this.CO.FullName;
}
-----------
mydropdown.DataSource = GetAllAgreements(); Databind();

Lambda SQL Query / Manipulate String At Query Or After Result

I'm using C#, EF5, and Lambda style queries against SQL.
I have the usual scenario of binding data to gridviews. Some of the results for my columns may be too long (character count) and so I only want to display the first 'n' characters. Let's say 10 characters for this example. When I truncate a result, I'd like to indicate this by appending "...". So, let's say the following last names are returned:
Mercer, Smith, Garcia-Jones
I'd like them to be returned like this:
Mercer, Smith, Garcia-Jon...
I was doing something like this:
using (var context = new iaiEntityConnection())
{
var query = context.applications.Where(c => c.id == applicationPrimaryKey);
var results = query.ToList();
foreach (var row in results)
{
if (row.employerName.Length > 10)
{
row.employerName = row.employerName.Substring(0, Math.Min(10, row.employerName.ToString().Length)) + "...";
}
if (row.jobTitle.Length > 10)
{
row.jobTitle = row.jobTitle.Substring(0, Math.Min(10, row.jobTitle.ToString().Length)) + "...";
}
}
gdvWorkHistory.DataSource = results;
gdvWorkHistory.DataBind();
However, if I change my query to select specific columns like this:
var query2 = context.applications.Select(c => new
{
c.id,
c.applicationCode,
c.applicationCategoryLong,
c.applicationType,
c.renew_certification.PGI_nameLast,
c.renew_certification.PGI_nameFirst,
c.renew_certification.PAI_homeCity,
c.renew_certification.PAI_homeState,
c.reviewStatusUser,
c.dateTimeSubmittedByUser
})
The result appears to become read-only if specific columns are selected, and I really should be selecting just the columns I need. I'm losing my ability to edit the result set.
So, I'm rethinking the entire approach. There must be away to select the first 'n' characters on select, right? Is there anyway to append the "..." if the length is > 10 on select? That seems trickier. Also, I guess I could parse through the gridview after bind and make this adjustment. Or, perhaps there is a way to maintain my ability to edit the result set when selecting specific columns?
I welcome your thoughts. Thanks!
To quote MSDN
Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to explicitly define a type first.
So you would have to define a class and select into that if you want read write capability.
e.g.
public class MyClass {
public int id { get; set; }
public string applicationCode {get; set; }
// rest of property defintions.
}
var query2 = context.applications.Select(c => new MyClass {
id = c.id,
applicationCode = c.applicationCode,
// Rest of assignments
};
As to just providing 10 character limit with ... appended. I'm going to assume you mean on the applicationcategoryLog field but you can use the same logic on other fields.
var query2 = context.applications.Select(c => new
{
c.id,
c.applicationCode,
applicationCategoryLong = (c.applicationCategoryLong ?? string.Empty).Length <= 10 ?
c.applicationCategoryLong :
c.applicationCategoryLong.Substring(0,10) + "...",
c.applicationType,
c.renew_certification.PGI_nameLast,
c.renew_certification.PGI_nameFirst,
c.renew_certification.PAI_homeCity,
c.renew_certification.PAI_homeState,
c.reviewStatusUser,
c.dateTimeSubmittedByUser
})

Add List output cumulatively

I have a class, I am using list to get (assigning multiple list entry values in c#).
// This will return me more than 1 records.
List<ClassEmpInfo> employeeDetails =GetEmployeeInformation();
List<ClassEmployee> empInfo = null;
foreach (ClassEmployee employee in employeeDetails)
{
//This needs to show all the ids belonging to employeeDetails.
//If there are 3 different employee ids ,
//the list empInfo should hold the output of all the 3,
//but i am getting the last 3rd one alone.
//How to cumulatively add 3 different employee ids.
empInfo = GetEmployeeDetails(Id, EmpId);
}
I am getting the last employee information rather than all the employee details in the empInfo list.
If the type is string I can do something like:
if (strType.Length > 0)
{
strType = strType + returned values;
}
else
{
strType = strType;
}
How do I add the list values cumulatively?
I think what you want to do is the following:
List empInfo = new List<detail_type>(); // whatever type is returned by GetEmployeeDetails
foreach (ClassEmployee employee in employeeDetails)
{
empInfo.Add(GetEmployeeDetails(id, EmpId));
}
It's rather unclear to me, though, if GetEmployeeDetails returns a single value or a list of values. If it returns a list of values, then change the line in the loop to:
empInfo.AddRange(GetEmployeeDetails(id, EmpId));
You add stuff to a list with .Add() this is per definition cumulative.

Categories

Resources