This question already has answers here:
EF: Include with where clause [duplicate]
(5 answers)
Closed 7 years ago.
I have a table of parents (InventoryItem) and another table of children (InventoryItemLines) and each parent can have an undetermined number of children
I need to get all the parents and for each parent, I need to get the list of children that respect a specific condition.
Example: I have an "Inactive" bit column in the children tables and i use this statement to get the data:
"_repository is a IRepository < InventoryItem >
var entities = _repository.GetAsQueryable().Include(x => x.InventoryItemLines.Where(i => i.Inactive));
but i get an ArgumentException with the message:" The Include path expression must refer to a navigation property defined on the type. Use dotted paths for reference navigation properties and the Select operator for collection navigation properties.
Parameter name: path"
Can you please show me a good practice for this kind of situation ?
The code will look something like this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataTable InventoryItem = new DataTable();
InventoryItem.Columns.Add("Item", typeof(string));
InventoryItem.Rows.Add(new object[] { "Shoes" });
InventoryItem.Rows.Add(new object[] { "Ties" });
InventoryItem.Rows.Add(new object[] { "Dresses" });
DataTable InventoryItemLines = new DataTable();
InventoryItemLines.Columns.Add("Item", typeof(string));
InventoryItemLines.Columns.Add("Color", typeof(string));
InventoryItemLines.Columns.Add("Active", typeof(Boolean));
InventoryItemLines.Rows.Add(new object[] { "Shoes", "Red", true });
InventoryItemLines.Rows.Add(new object[] { "Shoes", "Blue", true });
InventoryItemLines.Rows.Add(new object[] { "Shoes", "Turquoise", false });
InventoryItemLines.Rows.Add(new object[] { "Ties", "Red", true });
InventoryItemLines.Rows.Add(new object[] { "Ties", "Stripped", true });
InventoryItemLines.Rows.Add(new object[] { "Ties", "Pokerdot", false });
InventoryItemLines.Rows.Add(new object[] { "Dresses", "Yellow", true });
InventoryItemLines.Rows.Add(new object[] { "Dresses", "Blue", true });
InventoryItemLines.Rows.Add(new object[] { "Dresses", "Violet", true });
InventoryItemLines.Rows.Add(new object[] { "Tresses", "Stripped", false });
var results = InventoryItem.AsEnumerable().Select(x => new
{
item = x.Field<string>("Item"),
inactive = InventoryItemLines.AsEnumerable().Where(y => (y.Field<string>("Item") == x.Field<string>("Item")) && !y.Field<Boolean>("Active")).ToList()
}).ToList();
}
}
}
Related
I would like to have two different counts in a single query; I wrote it with SQL Server with the COUNT function as
COUNT(CASE WHEN Status = 'opened' THEN 1 ELSE NULL)
which returns my desired count.
However, in the current situation, I have datatable and am not sure if the above two counts are possible in Linq.
My data is as below.
Email Status
------------------
email1 opened
email1 opened
email2 clicked
email2 clicked
email2 clicked
email1 clicked
email2 opened
The output needs to be:
Email Opened Clicked
-------------------------------
email1 2 1
email2 1 3
Using C# Linq try something like this:
var test = context.stats.GroupBy(x=> x.Email).Select(groupedBy=> new {
Email = groupedBy.FirstOrDefault().Email,
Opened = groupedBy.Where(y=> y.Status == "opened").Count(),
Clicked = groupedBy.Where(y=> y.Status == "clicked").Count()
});
You want a pivot table. See code below :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication40
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("Email", typeof(string));
dt.Columns.Add("Status", typeof(string));
dt.Rows.Add(new object[] { "email1", "opened"});
dt.Rows.Add(new object[] { "email1", "opened" });
dt.Rows.Add(new object[] { "email2", "clicked" });
dt.Rows.Add(new object[] { "email2", "clicked" });
dt.Rows.Add(new object[] { "email2", "clicked" });
dt.Rows.Add(new object[] { "email1", "clicked" });
dt.Rows.Add(new object[] { "email2", "opened" });
string[] statusTypes = dt.AsEnumerable().Select(x => x.Field<string>("Status")).Distinct().OrderBy(x => x).ToArray();
var groups = dt.AsEnumerable().GroupBy(x => x.Field<string>("Email")).ToList();
DataTable pivot = new DataTable();
pivot.Columns.Add("Email",typeof(string));
foreach(string statusType in statusTypes)
{
pivot.Columns.Add(statusType, typeof(int));
}
foreach(var group in groups)
{
DataRow row = pivot.Rows.Add();
row["Email"] = group.Key;
foreach(string statusType in statusTypes)
{
row[statusType] = group.Where(x => x.Field<string>("Status") == statusType).Count();
}
}
}
}
}
I'm new to C#. I know that datatable is very efficient for reading an entire SQL table and outputting data to griddataview. However I need to do some parsing before storing the data in my griddataview. I was thinking reading the table row by row and grouping the data when applicable. Would a datatable or a list be more applicable in my case?
ORIGINAL TABLE PARSED TABLE I need to pass to datagridview
Name Workdate Name M T W TH F SAT SUN
Nicole WED Nicole Y Y Y
Nicole THR Jason Y
Nicole MON
Jason Tue
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Dictionary<string, string> dict = new Dictionary<string, string>() {
{"MON", "M"},{"TUE", "T"},{"WED", "W"},{"THR", "TH"},{"FRI", "F"},{"SAT", "SAT"},{"SUN", "SUN"}};
DataTable dt = new DataTable();
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Workdate", typeof(string));
dt.Rows.Add(new object[] { "Nicole", "WED" });
dt.Rows.Add(new object[] { "Nicole", "THR" });
dt.Rows.Add(new object[] { "Nicole", "MON" });
dt.Rows.Add(new object[] { "Jason", "TUE" });
DataTable pivot = new DataTable();
pivot.Columns.Add("Name",typeof(string));
DataColumn[] columns = dict.Select(x => new DataColumn(x.Value, typeof(string))).ToArray();
pivot.Columns.AddRange(columns);
var people = dt.AsEnumerable().GroupBy(x => x.Field<string>("Name")).ToArray();
foreach (var person in people)
{
DataRow pivotRow = pivot.Rows.Add();
pivotRow["Name"] = person.Key;
foreach (DataRow row in person)
{
string day = row.Field<string>("Workdate");
pivotRow[dict[day]] = "Y";
}
}
}
}
}
I have four tables (employees, allowances,deductions and Ajenda these are main tables , when i save employees financial details i save them in a different tables as image .
I want to display the employees detail and financial details in a horizontally way .
I'm using C# and SQLServer 2012 .
first table contains employees main details , second contain employees id with there allowances and other tables .
My tables
Here is my code before somebody closes it again. I decided not to use group since there would be a lot of left outer joins which would complicate solution. Decided just to create a table and then add the data directly to the results table.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataTable employees = new DataTable();
employees.Columns.Add("empID", typeof(int));
employees.Columns.Add("emp_name", typeof(string));
employees.Columns.Add("emp_tele", typeof(string));
employees.Rows.Add(new object[] { 1, "David", "025896325" });
employees.Rows.Add(new object[] { 2, "John", "856985658" });
employees.Rows.Add(new object[] { 3, "Micheal", "654687887" });
DataTable allowances = new DataTable();
allowances.Columns.Add("empID", typeof(int));
allowances.Columns.Add("allow_name", typeof(string));
allowances.Columns.Add("allow_Amount", typeof(int));
allowances.Rows.Add(new object[] { 1, "allow1", 100 });
allowances.Rows.Add(new object[] { 1, "allow2", 200 });
allowances.Rows.Add(new object[] { 1, "allow3", 300 });
allowances.Rows.Add(new object[] { 2, "allow1", 100 });
allowances.Rows.Add(new object[] { 2, "allow2", 200 });
DataTable deductions = new DataTable();
deductions.Columns.Add("empID", typeof(int));
deductions.Columns.Add("Dedu_name", typeof(string));
deductions.Columns.Add("Dedu_Amount", typeof(int));
deductions.Rows.Add(new object[] { 1, "ded1", 10 });
deductions.Rows.Add(new object[] { 1, "ded2", 5 });
deductions.Rows.Add(new object[] { 2, "ded1", 10 });
DataTable ajenda = new DataTable();
ajenda.Columns.Add("empID", typeof(int));
ajenda.Columns.Add("ajenda_name", typeof(string));
ajenda.Columns.Add("ajenda_Amount", typeof(int));
ajenda.Rows.Add(new object[] { 1, "aj1", 200 });
ajenda.Rows.Add(new object[] { 1, "aj1", 200 });
ajenda.Rows.Add(new object[] { 1, "aj2", 300 });
DataTable results = employees.Clone();
string[] allow_names = allowances.AsEnumerable().Select(x => x.Field<string>("allow_name")).Distinct().OrderBy(x => x).ToArray();
foreach (string name in allow_names)
{
results.Columns.Add(name, typeof(string));
}
string[] dedu_names = deductions.AsEnumerable().Select(x => x.Field<string>("Dedu_name")).Distinct().OrderBy(x => x).ToArray();
foreach (string name in dedu_names)
{
results.Columns.Add(name, typeof(string));
}
string[] ajenda_names = ajenda.AsEnumerable().Select(x => x.Field<string>("ajenda_name")).Distinct().OrderBy(x => x).ToArray();
foreach (string name in ajenda_names)
{
results.Columns.Add(name, typeof(string));
}
//add employees to result table
foreach(DataRow row in employees.AsEnumerable())
{
results.Rows.Add(row.ItemArray);
}
var groupAllownaces = allowances.AsEnumerable().GroupBy(x => x.Field<int>("empID"));
foreach (var group in groupAllownaces)
{
DataRow employeeRow = results.AsEnumerable().Where(x => x.Field<int>("empID") == group.Key).First();
foreach (DataRow row in group)
{
employeeRow[row.Field<string>("allow_name")] = row.Field<int>("allow_Amount");
}
}
var groupDeductions = deductions.AsEnumerable().GroupBy(x => x.Field<int>("empID"));
foreach (var group in groupDeductions)
{
DataRow employeeRow = results.AsEnumerable().Where(x => x.Field<int>("empID") == group.Key).First();
foreach (DataRow row in group)
{
employeeRow[row.Field<string>("Dedu_name")] = row.Field<int>("Dedu_Amount");
}
}
var groupAjenda = ajenda.AsEnumerable().GroupBy(x => x.Field<int>("empID"));
foreach (var group in groupAjenda)
{
DataRow employeeRow = results.AsEnumerable().Where(x => x.Field<int>("empID") == group.Key).First();
foreach (DataRow row in group)
{
employeeRow[row.Field<string>("ajenda_name")] = row.Field<int>("ajenda_Amount");
}
}
}
}
}
I have a table like this.
Date |Name |Id|Item |
23-March-2017|Vinod |1|USB |
02-May-2017 |Sureka|2|Cable |
23-March-2017|Mahesh|6|Mouse |
24-May-2017 |Raju |7|Keyboard|
09-May-2017 |Raju |2|Cable |
23-March-2017|Mahesh|6|Mouse |
02-May-2017 |Ganga |7|Keyboard|
I want get the Data according to Date in table Uisng LINQ Like
24-May-2017
Raju-Keyboard
09-May-2017
Raju-Cable
02-May-2017
Sureka-Cable
Ganga-Keyboard
23-March-2017
Vinod-USB
Mahesh-Cable
Mahesh-Mouse
context.Table.Select(o => new { Date = o.Date, Text = o.Name + "-" + o.Item }).GroupBy(o => o.Date);
Should do the trick, without me knowing you variable names and the like.
I recommend using a dictionary
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication55
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("Date", typeof (DateTime));
dt.Columns.Add("Name", typeof (string));
dt.Columns.Add("Id", typeof (int));
dt.Columns.Add("Item", typeof (string));
dt.Rows.Add(new object[] { DateTime.Parse("23-March-2017"), "Vinod", 1, "USB"});
dt.Rows.Add(new object[] { DateTime.Parse("02-May-2017"), "Sureka", 2, "Cable"});
dt.Rows.Add(new object[] { DateTime.Parse("23-March-2017"), "Mahesh",6, "Mouse"});
dt.Rows.Add(new object[] { DateTime.Parse("24-May-2017"), "Raju",7, "Keyboard"});
dt.Rows.Add(new object[] { DateTime.Parse("09-May-2017"), "Raju", 2, "Cable"});
dt.Rows.Add(new object[] { DateTime.Parse("23-March-2017"), "Mahesh", 6, "Mouse"});
dt.Rows.Add(new object[] { DateTime.Parse("02-May-2017"), "Ganga", 7, "Keyboard"});
Dictionary<DateTime, List<string>> dict = dt.AsEnumerable().GroupBy(x => x.Field<DateTime>("Date")).ToDictionary(x => x.Key, y => y.Select(z => z.Field<string>("Name") + "-" + z.Field<string>("Item")).ToList());
}
}
}
I need to populate a pie with data which are the result of a query (LINQ To SQL)
The problem is i cannot manage to add a foreach inside this code to insert my data instead of the static Firefox,Chrome,IE ect ...
protected void Page_Load(object sender, EventArgs e)
{
//RepeaterVersionsForPie.DataSource = DAaccess.LibDataVersion.LibDataVersion.GetNumberOfCompaniesUsingEachVersions();
//RepeaterVersionsForPie.DataBind();
var test = DAaccess.LibDataVersion.LibDataVersion.GetNumberOfCompaniesUsingEachVersions();
Highcharts chart = new Highcharts("chart")
.InitChart(new Chart { PlotShadow = false })
.SetTitle(new Title { Text = "Browser market shares at a specific website, 2010" })
.SetTooltip(new Tooltip { Formatter = "function() { return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %'; }" })
.SetPlotOptions(new PlotOptions
{
Pie = new PlotOptionsPie
{
AllowPointSelect = true,
Cursor = Cursors.Pointer,
DataLabels = new PlotOptionsPieDataLabels
{
Color = ColorTranslator.FromHtml("#000000"),
ConnectorColor = ColorTranslator.FromHtml("#000000"),
Formatter = "function() { return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %'; }"
},
Point = new PlotOptionsPiePoint
{
Events = new PlotOptionsPiePointEvents
{
Click = "function() { alert (this.category +': '+ this.y); }"
}
}
}
})
.SetSeries(new Series
{
Type = ChartTypes.Pie,
Name = "Browser share",
Data = new Data(new object[]
{
new object[] { "Firefox", 45.0 },
new object[] { "IE", 26.8 },
new DotNet.Highcharts.Options.Point
{
Name = "Chrome",
Y = 12.8,
Sliced = true,
Selected = true
},
new object[] { "Safari", 8.5 },
new object[] { "Opera", 6.2 },
new object[] { "Others", 0.7 }
})
});
ltrChart.Text = chart.ToHtmlString();
}
Actually , i need to be able to insert something like this:
foreach ( var item in test )
{
new object[] { item.name, item.count}
}
But VS doesn't allow me to do such thing
Thanks in advance for your help ...
You could create an extension method for whatever type DAaccess.LibDataVersion.LibDataVersion.GetNumberOfCompaniesUsingEachVersions() returns and have it return the results in the Pie-shaped Series format.
public static class DotNetHighChartsExtensions
{
public static object[] ToPieChartSeries(this WhateverThatTypeIs data)
{
var returnObject = new List<object>();
foreach ( var item in data )
{
returnObject.Add(new object[] { item.name, item.count});
}
return returnObject.ToArray();
}
}
Then in your code where you have your static code, you'd just replace it with:
Data = new Data(test.ToPieChartSeries())
Alternatively, you could have the ToPieChartSeries method return the Data object that is being sought for by the Series object.
While I haven't worked with this DotNet.HighCharts project, I have worked with and built my own HighCharts objects for a couple of MVC projects. On the face of it, it looks like this are ultimately doing the same thing I did: Create a .NET object that could be serialized as JSON and recognized by the HighCharts javascript library.
SetSeries(new Series {
Type = ChartTypes.Pie,
Data = new Data(test.Select(d => new { Name = d.name, Y = d.count }).ToArray())
})