Linq to Sql Projection Help - linq

I've reached the end of my Linq rope. Need your help!
Heres my table structure first(all linq to sql objects):
InventoryItems
-ID
-AmtInStock
IventoryKits
-ID
InventoryKits_to_InventoryItems
-InventoryItemID
-InventoryKitID
So i need to do a projection like the following
var q2=from k in GetAllKits()//returns IQueryable<InventoryKit>
select new VMPublication()//ViewModel Object
{
ID = k.ID,
Name = k.Name,
WebAmountInStock = ,//need to get the Min() AmtInStock from InventoryItems here
ItemCode = k.ItemCode,
WebAmountOrdered = k.AmtOrdered.ToString(),
WebReminderAmount = "",
WebAmountWarning="",
Type = "Kit"
};
i have no idea how to get that Min() of InventoryItem's AmtInStock in that query.
Please help! Very Appreciated!

I'm guessing at your association names, but try something like:
var q2=from k in GetAllKits()//returns IQueryable<InventoryKit>
select new VMPublication()//ViewModel Object
{
ID = k.ID,
Name = k.Name,
WebAmountInStock = (from i in k.InventoryKits_to_InventoryItems
select i.InventoryItem.AmtInStock).Min(),
ItemCode = k.ItemCode,
WebAmountOrdered = k.AmtOrdered.ToString(),
WebReminderAmount = "",
WebAmountWarning="",
Type = "Kit"
};

Related

IQueryable.Union/Concat in .net core 3

I want to add a dummy member to an IQueryable and came up with this solution:
IQueryable<Geography> geographies = _unitOfWork.GeographyRepository.GetAll(); //DbSet<Geography>
var dummyGeographies = new Geography[] { new Geography { Id = -1, Name = "All" } }.AsQueryable();
var combinedGeographies = geographies.Union(dummyGeographies);
var test = combinedGeographies.ToList(); //throws runtime exc
But it throws the following exception:
Processing of the LINQ expression 'DbSet
.Union(EnumerableQuery { Geography, })' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core.
How could I make it work?!
you can only union on data structure which are the same
IQueryable is only applicable if the query expression not been been expressed (ToList) before its run against db and you want the expression modifiable . aka nothing which which is not going to db as a query needs to be IQueryable (simple explanation better to research and understand this yourself)
List<Geography> geographies = _unitOfWork.GeographyRepository
.GetAll() //DbSet<Geography>
.Select(o => new Geography { Id = o.Id, Name = o.Name })
.ToList();
List<Geography> dummyGeographies = new List<Geography>() {
new Geography[] { new Geography { Id = -1, Name = "All" } }
};
var combinedGeographies = geographies.Union(dummyGeographies);
var test = combinedGeographies.ToList();
I was able to achieve it with the following code:
IQueryable<Geography> geographies = _unitOfWork.GeographyRepository.GetAll().Select(o => new Geography { Id = o.Id, Name = o.Name });
IQueryable<Geography> dummyGeographies = _unitOfWork.GeographyRepository.GetAll().Select(o => new Geography { Id = -1, Name = "All" });
var combinedGeographies = geographies.Union(dummyGeographies);

Linq CopyToDataTable using extension methods

Hello I'm trying to copy the following linq results to a datatable. The only examples I see of copytodatatable is using the query format, and not the extension methods. Wondering if anyone knows how to use it with the extension methods (I've tried casting the results to IEnumerable datarow but it didn't work).
DataTable dtItemPricingBreakDown =
SiteHelper.getItemPricingBreakDown(CustomerId,
PriceBookID,
deliveryZip,
dtItems,
db,
departmentId);
dtItemPricingBreakDown.AsEnumerable()
.GroupBy(i => new {
sku = i.Field<string>("sku"),
deptid = i.Field<int>("department_id")
})
.Select(group => new
{
sku = group.Key.sku,
deptid = group.Key.deptid,
cnt = group.Count()
});
Update
Better late than never, sorry for the delay in response. My actual issue appears to be for both the query syntax and the extension methods.
Something like this works according to msdn
(http://msdn.microsoft.com/en-us/library/bb386921(v=vs.110).aspx):
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable orders = ds.Tables["SalesOrderHeader"];
DataTable details = ds.Tables["SalesOrderDetail"];
var query =
from order in orders.AsEnumerable()
join detail in details.AsEnumerable() on order.Field<int>("SalesOrderID") equals detail.Field<int>("SalesOrderID")
where order.Field<bool>("OnlineOrderFlag") == true
&& order.Field<DateTime>("OrderDate").Month == 8
select new
{
SalesOrderID = order.Field<int>("SalesOrderID"),
SalesOrderDetailID = detail.Field<int>("SalesOrderDetailID"),
OrderDate = order.Field<DateTime>("OrderDate"),
ProductID = detail.Field<int>("ProductID")
};
DataTable orderTable = query.CopyToDataTable();
But when I try this...
var query = from exx in dtItemPricingBreakDown.AsEnumerable()
group exx by new { sku = exx.Field<string>("sku"), companyId = exx.Field<int>("department_id") } into grp
select new { sku = grp.Key.sku, DepartmentID = grp.Key.companyId, Cnt = grp.Count() };
DataTable dt3 = query.CopyToDataTable();
I get this exception: "No implicit reference conversion from anonymoustype1 to system.data.datarow". I've tried doing what they did with the dataset in the msdn example as well and I still get the error. Extension method wise I was trying something like this...and still got the same exception.
DataTable dt3 = dtItemPricingBreakDown.AsEnumerable().GroupBy(i => new
{
sku = i.Field<string>("sku"),
deptid = i.Field<int>("department_id")
}).Select(group => new
{
sku = group.Key.sku,
DepartmentID = group.Key.deptid,
cnt = group.Count()
}).Cast<DataRow>().CopyToDataTable();

Replacing foreach loops with LINQ expressions

replacing the foreach loop
IList<EmployeeSearch> empItems = new List<EmployeeSearch>();
EmployeeSearch empItem = new EmployeeSearch();
foreach (var _emp in mediaResults.results)
{
empItem.Title = _emp.title;
empItem.Desc = _emp.description;
empItems.Add(empItem);
}
with the following linq expression and getting error:
empItems = from _emp in employeeResults.results
select new EmployeeSearch
{
Title = _emp.title,
Desc = _emp.description
};
Error:
Error 2 Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'System.Collections.Generic.IList'. An explicit conversion exists (are you
You need to convert it to a List:
(from _emp in employeeResults.results
select new EmployeeSearch
{
Title = _emp.title,
Desc = _emp.description
}).ToList();
Or...change your empItems definitions to use a var implicit typing:
var empItems = from _emp in employeeResults.results
select new EmployeeSearch
{
Title = _emp.title,
Desc = _emp.description
};
empItems will be an IEnumerable of EmployeeSearch objects.
Either add a call to the ToList extension method at the end of your query:
empItems =
(from _emp in employeeResults.results
select new EmployeeSearch
{
Title = _emp.title,
Desc = _emp.description
})
.ToList();
Or if you can possibly refactor your code to use an IEnumerable<T> instead, that could possibly be better:
IEnumerable<EmployeeSearch> empItems =
from _emp in employeeResults.results
select new EmployeeSearch
{
Title = _emp.title,
Desc = _emp.description
};
This should generally be used if you're just looping through the results and you don't actually need to add / remove elements from the result set or have per-index access to the results. Converting the query results to a list requires allocation of a single, contiguous array in memory, which is a fairly expensive operation.

dataset to List<T>using linq

I have a DataSet and I want to convert the DataSet into List<T>
T - type object
How convert my DataSet? It has 10 columns, with all 10 properties my object has and it's returning over 15000 rows. I want to return that dataset into List<obj> and loop it how do I do that?
This is pretty much the same as the other answers, but introduces strongly-typed columns.
var myData = ds.Tables[0].AsEnumerable().Select(r => new {
column1 = r.Field<string>("column1"),
column2 = r.Field<int>("column2"),
column3 = r.Field<decimal?>("column3")
});
var list = myData.ToList(); // For if you really need a List and not IEnumerable
I think this should do it.
var output = yourDataSet.Tables[0].Rows.Cast<DataRow>().Select(r => new
{
Column1 = r["Column1"].ToString(),
Column2 = r["Column2"].ToString(),
Column3 = r["Column3"].ToString(),
Column4 = r["Column4"].ToString(),
Column5 = r["Column5"].ToString(),
Column6 = r["Column6"].ToString(),
Column7 = r["Column7"].ToString(),
Column8 = r["Column8"].ToString(),
Column9 = r["Column9"].ToString(),
Column10 = r["Column10"].ToString()
}).ToList();
First of all, you're on the right track, but you should be thinking in terms of IEnumerable<T> rather than List<T>. And here is how you would do that:
var myData = ds.Tables[0].AsEnumerable()
.Select(r => new {column1 = r[0].ToString(),
column2 = r[1].ToString()
/*etc*/
});
Never convert an IEnumerable to a List before you absolutely need to.
I know #bharat asked for a solution using LINQ, but mainly for myself I wanted to compare #Kelsey's solution to the old fashioned way of doing this:
List<Obj> list = new List<Obj>();
foreach (DataRow r in yourDataSet.Tables[0].Rows)
{
Obj obj = new Obj();
obj.Column1 = r["Column1"];
obj.Column2 = r["Column2"];
obj.Column3 = r["Column3"];
obj.Column4 = r["Column4"];
obj.Column5 = r["Column5"];
obj.Column6 = r["Column6"];
obj.Column7 = r["Column7"];
obj.Column8 = r["Column8"];
obj.Column9 = r["Column9"];
obj.Column10 = r["Column10"];
list.Add(obj);
}
Or via constructor:
List<Obj> list = new List<Obj>();
foreach (DataRow r in yourDataSet.Tables[0].Rows)
{
Obj obj = new Obj(r["Column1"], r["Column2"], r["Column3"], r["Column4"], r["Column5"],r["Column6"], r["Column7"], r["Column8"], r["Column9"],r["Column10"]);
list.Add(obj);
}
I intentionally left off .ToString() because I think using it depends on the situation.
Thanks for all the above posts...
I have done it with using Linq Query, for detail visit the link
http://codenicely.blogspot.com/2012/02/converting-your-datatable-into-list.html
A very simple approach that I use is following:
List<Obj> objList = new List<Obj>();
foreach (DataRow _dataRow in dataSet.Tables[0].Rows)
{
Obj obj = new Obj();
obj.Col1 = Convert.ToInt32(_dataRow["Col1"]);
obj.Col2 = Convert.ToInt32(_dataRow["Col2"]);
obj.Col3 = Convert.ToString(_dataRow["Col3"]);
objList.Add(obj);
}

How can I convert a DataTable to an IEnumerable<Dictionary<string, object>>?

I'd like to convert a DataTable to an IEnumerable<> of Dictionary<string, object>. I tried the following LINQ query,
from DataRow row in ds.Tables[0].AsEnumerable()
let rowDictionary = new Dictionary<string, object>()
from DataColumn column in row.Table.Columns.Cast<DataColumn>()
select rowDictionary.Add(column.ColumnName, row[column]).ToArray();
but I get the following error:
error CS1943: An expression of type
'System.Collections.Generic.IEnumerable<System.Data.DataColumn>' is not
allowed in a subsequent from clause in a query expression with source type
'System.Data.EnumerableRowCollection<AnonymousType#1>'. Type inference
failed in the call to 'SelectMany'.
I know I can brute-force this with a loop, but it seems like something I should be able to do in LINQ. Thanks in advance for any help!
I assume that what you want is a Dictionary for each row mapping column to value:
var dt = new DataTable();
var columns = dt.Columns.Cast<DataColumn>();
dt.AsEnumerable().Select(dataRow => columns.Select(column =>
new { Column = column.ColumnName, Value = dataRow[column] })
.ToDictionary(data => data.Column, data => data.Value));
Here is a way I do it in the Linq format
var registerdataVerify = (from o in dt.AsEnumerable()
select new
{
DataDef =o["shortName"].ToString(),
Value = Convert.ToInt32(o["valueDec"])
}).ToDictionary(n => n.DataDef, n => n.Value);
Why not something simpler since you have linq?
var dt = new DataTable();
var columnIndex = 0;
var columnName = "UserID";
var Dict = dt.AsEnumerable().ToDictionary( _
row => row(columnName), _
row => row(columnIndex));
It becomes even easier if you're working with strongly-typed datasets:
var dt = new dsData.UsersDataTable();
var Dict = dt.ToDictionary(dr => dr.UserName, dr => dr.UserID);

Resources