How can I read the reult of LINQ query row by row .(Is it possible)?
I want to implemente this one but doesn't possible:
aspnetdbDataContext aspdb = new aspnetdbDataContext();
var res = from r in aspdb.RouteLinqs
where r.UserId == userId
select r;
foreach (DataRow row in res)
{
// ...
An exception is thrown:
Cannot convert type 'QuickRoutes.DAL.RouteLinq' to 'System.Data.DataRow'
Edit:
in the foreach block I have:
foreach (var row in res)
{
var routeId = (int)row["RouteId"];
var route = new Route(routeId)
{
Name = (string)row["SourceName"],
Time = row["CreationTime"] is DBNull ? new DateTime() :
Convert.ToDateTime(row["CreationTime"])
};
route.TrackPoints = GetTrackPointsForRoute(routeId);
result.Add(route);
}
If I use var this error in some lines occure:
Cannot apply indexing with [] to an expression of type 'QuickRoutes.DAL.RouteLinq'
use
foreach (RouteLinq row in res)
{
// ...
or simply:
foreach (var row in res)
{
// ...
Your Linq query doesnt return a collection of DataRow objects, but instead objects of a class that was autogenerated from your database table name.
Edit, to account for the edit in your question:
Why are you accessing the members of your objects like they are still DataRow objects?
You want to access it like:
int routeId = row.RouteId;
I really recommend you to look at a few basic Linq-to-SQL (or ORM in general) tutorials.
Try this
foreach (var row in res)
{.....
Update : I would like to give you smaller syntax, hope you don't mind
foreach(var routeLinq in aspdb.RouteLinqs.Where(rl => rl.UserId == userId) )
{
int routeId = routeLinq.RouteId;
}
Related
I would like to create an anonymous type from linq. Then change the value of a single property(status) manually and give the list to a repeater as data source. But doesn't let me do that as theay are read-only. Any suggestion?
var list = from c in db.Mesai
join s in db.MesaiTip on c.mesaiTipID equals s.ID
where c.iseAlimID == iseAlimID
select new
{
tarih = c.mesaiTarih,
mesaiTip = s.ad,
mesaiBaslangic = c.mesaiBaslangic,
mesaiBitis = c.mesaiBitis,
sure = c.sure,
condition = c.onaylandiMi,
status = c.status
};
foreach (var item in list)
{
if (item.condition==null)
{
item.status == "Not Confirmed";
}
}
rpCalisanMesai.DataSource = list.ToList();
rpCalisanMesai.DataBind();
Instead of trying to change the value after creating the list, just set the right value while creating the list.
var list = from c in db.Mesai
join s in db.MesaiTip on c.mesaiTipID equals s.ID
where c.iseAlimID == iseAlimID
select new
{
tarih = c.mesaiTarih,
mesaiTip = s.ad,
mesaiBaslangic = c.mesaiBaslangic,
mesaiBitis = c.mesaiBitis,
sure = c.sure,
condition = c.onaylandiMi,
status = c.onaylandiMi != null ? c.status : "Not Confirmed"
};
Also, if you could change the property, your problem would be executing the query twice: first in the foreach-loop, and then again by calling list.ToList() (which would create new instances of the anonymous type).
You cannot, anonymous type's properties are read-only.
You need to set it during object creation. See #Dominic answer for code sample.
You can. For instance:
var data = (from a in db.Mesai select new { ... status = new List<string>() .. }).ToList();
Next, compute your status:
foreach (var item in data) {
item.status.Add("My computed status");
}
And then on rendering:
foreach (var item data) {
Response.Write(item.status[0]);
}
EDIT: The list can even be intialized as per your requirement:
var data = (from a in db.Mesai select new { ... status = new List<string>(new
string[] { c.status }) .. }).ToList();
foreach (var item in data) {
item.status[0] = "My computed status";
}
EDIT2: Seems like you must initialize the list, preferably with e.g. c.rowid.ToString(), otherwise the optimizer assigns the same new List() to all items, thinking that this might be some game or something.
I have a dictionary Dictionary<string, List<string>> FilterDictionary which contains a column name as the key and the value of that key is a list of criteria that is going to be used as a where clause.
I need to query my database and for each column thats in the dictionary query that column with the criteria thats in the list for that key.
Just wondering what the best way to do this was?
This is what I would like to achieve but obviously I know its not as simple as columnName == filterCriteria.
var originalQuery = from p in productContext.Products
select p;
foreach (var item in FilterDictionary)
{
string columnName = item.Key;
foreach (var filterCriteria in FilterDictionary)
{
originalQuery.Where(columnName == filterCriteria);
}
}
I'd do something like this instead to hold your collection of filter conditions:
var filters = new List<Expression<Func<Product, Boolean>>>();
filters.Add(e => e.Name == "some name");
var originalQuery = from p in productContext.Products
select p;
originalQuery = filters
.Aggregate(originalQuery, (current, condition) => current.Where(condition));
At the end of the foreach loop, originalQuery will have logically ANDed together all of the criteria held in filters.
I am new to LINQ but am trying to tackle a tough one right off the bat. I am trying to do LINQ to dataset and emulate the following query...
SELECT smID, MIN(entID) FROM table
WHERE exID = :exID
AND smID IN (1,2,3,4,5,6,7,8, etc)
GROUP BY smID
The code I have so far is as follows...
DataTable dt = ds.Tables["myTable"];
var query =
from g in dt.AsEnumerable()
where g.Field<string>("exID") == exID
&& smIDs.Contains(g.Field<string>("smID"))
group g by g.Field<string>("smID") into rowGroup
select new
{
smID = rowGroup.Key,
minEntID = rowGroup.Min(g => g.Field<int>("entID"))
};
exID is a string variable in the method and smIDs is a List of strings also created earlier in the method. I created the following code to try and see my results and it throws an "System.InvalidCastException" error at query.Count...
if (query.Count() > 0)
{
foreach (var item in query)
{
string s = item.smID;
int i = (int)item.minEntID;
}
}
I have been unable to figure out what I am doing wrong.
VS points to...
minEntID = rowGroup.Min(g => g.Field<int>("entID"))
This is the first two lines of the stack trace...
at System.Data.DataRowExtensions.UnboxT`1.ValueField(Object value)
at System.Data.DataRowExtensions.Field[T](DataRow row, String columnName)
Any pointers would be most appreciated. Thanks.
Judging by the exception and stack trace, the type you're specifying for the endID field in your query doesn't match the DataType for that column in the DataTable. These must match -- you cannot use the Field method to cast the value to a different type.
I used Linqer to come up with this code:
from t in db.Table // your C# table / collection here, of course
where t.ExId == stackoverflow.ExId
&& (new int[] {1, 2, 3 }).Contains(t.SmId)
group t by new { t.SmId } into g
select new {
SmId = g.Key.SmId,
minEntID = g.Min(p => p.EntId)
}
I have a datatable which contains a load of dates. I wanted to group these by date and give each row a count.
I have managed to do this by dong the following:
IEnumerable query = from row in stats.AsEnumerable()
group row by row.Field<string>("date") into grp
select new { Date = grp.Key, Count = grp.Count(t => t["date"] != null) };
(where "stats" is the datatable)
I can see from debugging that this brings back the values all grouped as I need, but now I need to loop them and get each date and count.
My problem is I don't know how to retrieve the values!
I have a foreach loop
foreach (var rw in query)
{
string date = rw.Date; // <---- this is my problem?
}
I don't know what type my Ienumerable is to be able to reference the values in it!
So my question is how can I retrieve each date and count for each row by doing similar to the above?
I hope this makes sense!
This link on my blog should help you
http://www.matlus.com/linq-group-by-finding-duplicates/
Essentially your type is an anonymous type so you can't reference it as a type but you can access the properties like you're trying to do.
I think I see your issue. If you're trying to return it from a method, you should define a type and reuturn it like shown below:
public IEnumerable<MyType> GetQuery()
{
var query = from row in stats.AsEnumerable()
group row by row.Field<string>("date") into grp
select new { Date = grp.Key, Count = grp.Count(t => t["date"] != null) };
foreach (var rw in query)
{
yield return new MyType(rw.Date, rw.Count);
}
}
declare your "query" variable using "var" as shown above.
I guess you don't have access to the properties of the anonymous class because you're using IEnumerable query = .... Try var query = ... instead.
Going by your comment "I am returning the query from a function", which I take to mean that you want to do the query in a method, return the data to the caller, and then iterate the data in the caller, I suggest you return a Dictionary<DateTime, int>, like this:
static Dictionary<DateTime, int> GetSummarisedData()
{
var results = (
from row in stats.AsEnumerable()
group row by row.Field<string>("date") into grp
select new { Date = grp.Key, Count = grp.Count(t => t["date"] != null) })
.ToDictionary(val => val.Date, val => val.Count);
return results;
}
then in the caller you can just
foreach (var kvp in GetSummarisedData())
{
// Now kvp.Key is the date
// and kvp.Value is the count
}
I have the following in my NotSelectedList.
public List<TestModel> SelectedList = new List<TestModel>();
public List<TestModel>NotSelectedList = new List<TestModel>();
NotificationDetailsModel projects = new NotificationDetailsModel();
projects.ProjectID = Convert.ToInt32(Row["ProjectID"]);
projects.Valid= Convert.ToBoolean(Row["Validity"]);
NotSelectedList.Add(projects);
How can I write a simple code in LINQ to select from the NotSelectedList where Validity == True and store the data in SelectedList?
var query = from ns in NotSelectedList
from n in SelectedList
where ns.Valid && ns.ProjectID == n.ProjectID
select ns;
Hope this will help you
The following would select the items with Validity = true from NotSelectedList and place them in SelectedList:
SelectedList.AddRange(NotSelectedList.Where(item => item.Validity));
Try this:
var results = NotSelectedList.Where(x => x.Valid);
foreach (var item in results)
SelectList.Add(item);
Although for performance reasons you may be better off doing something like this:
foreach (var item in NotSelectedList)
{
if (item.Valid)
SelectList.Add(item);
}