I have a requirement to extract a distinct subset of rows from a DataTable, and thought LINQ2DataSets may be a useful and clean way to do this, however it appears that it is not possible to simply identify return rows from a LINQ2DS query as follows
var result = from r in fips.AsEnumerable() select
r.Field<string>("FACILITY_PROCESS_SUB_GROUP_CODE"),
r.Field<string>("PROCESS_SUB_GROUP_NAME"),
r.Field<string>("...
as I start getting errors after the first comma.
Is this a correct assumption, and how would I get around it to return a subset of columns from the dataset that I can apply a Distinct() method to?
You forgot the new statement and field names:
var result = from r
in fips.AsEnumerable()
select new
{
FacProcess = r.Field<string>("FACILITY_PROCESS_SUB_GROUP_CODE"),
GroupName = r.Field<string>("PROCESS_SUB_GROUP_NAME"),
Item3 = r.Field<string>("Item3")
};
You can also explicitly declare that you are going to use a type:
var result = from r
in fips.AsEnumerable()
select new MyType("InitClassParams")
{
FacProcess = r.Field<string>("FACILITY_PROCESS_SUB_GROUP_CODE"),
GroupName = r.Field<string>("PROCESS_SUB_GROUP_NAME"),
Item3 = r.Field<string>("Item3")
};
Scott Guthrie (VP Developer Devision, Microsoft) has some good info about LINQ (he talks about LINQ to SQL, but most of it applies regardless).
Then apply the distinct clause:
var result = from r
in fips.AsEnumerable()
select new
{
FacProcess = r.Field<string>("FACILITY_PROCESS_SUB_GROUP_CODE"),
GroupName = r.Field<string>("PROCESS_SUB_GROUP_NAME"),
Item3 = r.Field<string>("Item3")
}
distinct;
Then put it to a list or iterate over it. Nothing will be selected/distincted/etc until something like on of the following is run:
var list = result.ToList()
foreach(var item in result) {}
Related
I have a datatable in memory and I need to select some records from it, walk through the records making changes to fields and they same the changes back to the datatable. I can do this with filters, views, and sql but I'm trying to do it in Linq.
var results = (from rows in dtTheRows.AsEnumerable()
select new
{
rows.Job,
}).Distinct();
foreach (var row in results)
{
firstRow = true;
thisOnHand = 0;
var here = from thisRow in dtTheRows.AsEnumerable()
orderby thisRow.PromisedDate
select new
{
thisRow.OnHandQuantity,
thisRow.Balance,
thisRow.RemainingQuantity
};
foreach(var theRow in here)
{
// business logic here ...
theRow.OnHandQuantity = 5;
} // foreach ...
The first linq query and foreach are gain the list of subsets of data to be considered. I include it here in case it is relevant. My problem is at this line:
heRow.OnHandQuantity = 5;
My error is:
"Error 19 Property or indexer 'AnonymousType#1.OnHandQuantity' cannot be assigned to -- it is read only"
What am I missing here? Can I update this query back into the original datatable?
var here = from thisRow in dtTheRows.AsEnumerable()
orderby thisRow.PromisedDate
select new
{
thisRow.OnHandQuantity,
thisRow.Balance,
thisRow.RemainingQuantity
};
Instead of passing three variables in select, pass thisRow itself. That may solve error on statement - theRow.OnHandQuantity = 5;
The error is self descriptive, you can't update/modify an anonymous type. You have to return the original entity you want to modify from your query.
select thisRow;
instead of
select new
{
thisRow.OnHandQuantity,
thisRow.Balance,
thisRow.RemainingQuantity
};
query is like this:-
labRequestItem.LabTest.Select(p=>p.LabTestICDCodes= labRequests.ICDCodes.Select(t => new ICDCodeList()
{
ICDCodeId = t.ICDCodeId,
ICDCode = t.ICDCodeName,
ICDDescription = t.ICDDescription,
ICDCodeType = t.ICDCodeType
}).ToArray());
Now the issue is that LabTestICDCodes is not updating with the new list value returning from select statement
I have tested in the Linqpad, following shall work, but please note:
finalResult would be List of type of LabTestICDCodes (which is again IEnumerable itself) with new / modified values, as that's the only column projected. You have to project the whole object you want as a result, values will modify as expected
var finalResult =
labRequestItem.LabTest.Select(p=>p.LabTestICDCodes= labRequests.ICDCodes.Select(t => new ICDCodeList()
{
ICDCodeId = t.ICDCodeId,
ICDCode = t.ICDCodeName,
ICDDescription = t.ICDDescription,
ICDCodeType = t.ICDCodeType
}).ToArray()).ToList();
I found only way to solve this problem by doing following step:-
1.Get the value in local variable
var icdList = labRequests.ICDCodes.Select(t => new ICDCodeList()
{
ICDCodeId = t.ICDCodeId,
ICDCode = t.ICDCodeName,
ICDDescription = t.ICDDescription,
ICDCodeType = t.ICDCodeType
}).ToArray();
Now assign the value by usinf foreach loop.
foreach (var test in labRequestItem.LabTest)
{
test.LabTestICDCodes = icdList;
}
In Last step I have to use foreach loop, if any other solution then
please reply otherwise I will use the same as it mentioned above.
I have 2 data tables. Each one has one column and I want to compare them and get same values on them but it does not work.
This is my code:
string CurrentRequestUrl = (HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.ToString());
DataTable dt_Item = ERP.BLL_Menu_Item.Custom_Item_ID(CurrentRequestUrl);
DataTable dt2_SysRole = ERP.BLL_Sys_User_Role.Custom_Role(Convert.ToInt64(App.UserID));
var dtOne = (dt_Item.AsEnumerable()).ToList();
var dtTwo = (dt2_SysRole.AsEnumerable()).ToList();
IEnumerable<DataRow> objIntersectResult = ((dtOne).Intersect((dtTwo))).ToList();
How can I find the matching values?
Intersect does not work here because on DataRow it just compares references. Because all rows are different references you get an empty list. Instead you want to compare values. Therefore you can use Join. But which row do you want to return from both tables? If you want both rows you could create an anonymous type of both:
var objJoinResult = from rowItem in dt_Item.AsEnumerable()
join rowSysRole in dt2_SysRole.AsEnumerable()
on rowItem.Field<string>("ColumnName") equals rowSysRole.Field<string>("ColumnName")
select new { rowItem, rowSysRole };
Output:
foreach (var both in objJoinResult)
{
Console.WriteLine("rowItem:{0} rowSysRole:{1}",
string.Join(",", both.rowItem.ItemArray),
string.Join(",", both.rowSysRole.ItemArray));
}
I have a function which searches some articles in the Sitecore content items and give me the value. So far I have build up my indexes and it is showing in my IndexViewer. But the return of the function is 0. I looked up this link: http://sitecoregadgets.blogspot.com/2009/11/working-with-lucene-search-index-in_25.html for more information.
protected IEnumerable<Item> ShowHomePageNews(int numOfArticles, string stringofCountries)
{
List<Item> items = new List<Item>();
Sitecore.Search.Index indx = SearchManager.GetIndex("newsArticles");
using (IndexSearchContext searchContext = indx.CreateSearchContext())
{
var db = Sitecore.Context.Database;
CombinedQuery query = new CombinedQuery();
QueryBase catQuery = new FieldQuery("countries", stringofCountries); //FieldName, FieldValue.
SearchHits results = searchContext.Search(catQuery); //Searching the content items by fields.
SearchResultCollection result = results.FetchResults(0, numOfArticles);
foreach (SearchResult i in result)
{
items = result
.Where(r => !r.Title.StartsWith("*"))
.Select(r => db.GetItem(new Sitecore.Data.ItemUri(r.Url).ToDataUri()))
.ToList();
//Lucene.Net.Documents.Field url = i.Document.GetField("_url");
//Sitecore.Data.ItemUri itemUri = new Sitecore.Data.ItemUri(url.StringValue());
//Sitecore.Data.Items.Item item = Sitecore.Context.Database.GetItem(itemUri.ToDataUri());
//items.Add(item);
}
}
return items;
}
Over here the result is 0. What I am doing wrond here?
This is the snapshot of what I am seeing in my IndexViewer:
EDIT:
I am passing a "NZ" in the 'catQuery' and I am getting the result back. Because in my index viewer I am seeing the Field Name = _name, which contains NZ in it. I got this part. However, I want my every field to be indexed. I am seeing only 3 fields in my IndexViewer: _url, _group & _name.
So your countries should be tokenized by the indexer. As a multilist, they will be tokenized by GUID. Searching for a single country by GUID with your code above should work. However, if you want to search for multiple countries, where any of the passed in countries can trigger a match, you need to structure your query differently.
CombinedQuery query = new CombinedQuery();
//apply other filters here to query if need be
//and country filter by creating a new clause (combinedquery) and "ORing" within it (QueryOccurance.Should)
CombinedQuery query3 = new CombinedQuery();
//here you would actually iterate over your country list
query3.Add(new FieldQuery("countries", country1GUID), QueryOccurance.Should);
query3.Add(new FieldQuery("countries", country2GUID), QueryOccurance.Should);
query.Add(query3, QueryOccurance.Must);
I have a web page in which I am giving USER the options of writing notes. Now when ever the web page checks that a USER is:abc then it pulls up the note from the MEMO Table.
Here is my code in Page_Load():
using (EntityMemoDataContext em = new EntityMemoDataContext())
{
int getEntity = Int16.Parse(Session["EntityIdSelected"].ToString());
var showMemo = from r in em.EntityMemoVs_1s
where r.EntityID == getEntity
select r.Memo;
tbShowNote.Text = String.Join(#"<br />", showMemo);
}
tbShowNote is showing me value like this:
test<br />test1<br />test1<br />test4<br />test4
And I want it like this:
Test
Test1
Test2 ...
tbShowNote is a TextBox!
You only asked for the first memo, so that's what you got back. If you want it enumerated with each one on it's own line in html, you could do this:
using (EntityMemoDataContext em = new EntityMemoDataContext())
{
int getEntity1 = Int16.Parse(Session["EntityIdSelected"].ToString());
var showMemo = from r in em.EntityMemoVs_1s
where r.EntityID == getEntity1
select new
{
r.Memo
};
tbShowNote.Text = String.Join(#"<br />", showMemo);
}
The key takeaway is if r.Memo is of type string, then the LINQ query you executed gave you back a IQueryable<string>. It's on you to decide if you want to flatten that list later.
Edit: Equiso made a good observation in that you're actually returning an IQueryable of an anonymous type, not IQueryable<string> due to the new { ... } syntax. I'd say combine his answer with mine and run with it:
var showMemo = from r in em.EntityMemoVs_1s
where r.EntityID == getEntity1
select r.Memo;
tbShowNote.Text = String.Join(#"<br />", showMemo);
The problem is in the select part of your linq query, you are wrapping your results in an anonymous type, that is why when you call ToString() you see { Memo = test }. You probably want it like this:
var showMemo = from r in em.EntityMemoVs_1s
where r.EntityID == getEntity1
select r.Memo;
After that showMemo will contain just strings.
It looks like your showMemo is a collection and you are then just assigning the top value? If you are putting them in one string then you need to aggregate them together.