2sxc - Get Calendar data - linq

I have Entity "News" with many fields and entity "EventTime" which contains field "DateTime"
In "News" there is also field for List of "EventTime"
I am able to filter and sort "News" on many fields of "News" entity...
var data = AsDynamic(App.Data["News"]);
data = data.Where(x => ....);
data = data.OrderBy(x => ...);
But I don't know how to make linq query to get list of "News" for all "EventTime"..
eg.:
if I have this data:
News[0]-Title1 with EventTime[0]-2019/05/01 and EventTime[1]-2019/06/02
News[1]-Title2 with EventTime[0]-2019/05/10 and EventTime[1]-2019/06/10
I want to get list of "News" like this:
Title1 - 2019/05/01
Title2 - 2019/05/10
Title1 - 2019/06/02
Title2 - 2019/06/10
How to get this?

This seems to mostly be a LINQ question, basically you want to have a result where the original items occur more than once, and the final sort uses multiple possible values. I recommend to something along these lines:
create a list of all items with their new date, do this using Linq SelectMany and in that, do an newsItem.Select return something like a new { Date = the-date-you-need, Item = the-as-dynamic }.
Now OrderBy the Date
That's basically it :)

Related

.Where in LinQ not working correctly

I have Documents table and Signs table. Document record can be related with many records in Signs table.
Now, I want to get all records of Documents table when document ID appears in Signs table.
Here I get all documents:
var documents = (from c in context.documents select c);
Here I get all my signs and save into List:
var myDocuments = (from s in context.signs where s.UserId== id select s.ID).ToList();
This list contains collection on document ID.
And here, I'm trying to get all documents that exists in myDocuments list:
documents.Where(item => myDocuments.Contains(item.ID));
But, when I do .ToList() allways return all records (in database only exists one compatible record)
What is wrong in LinQ statement?
The problem is that this statement doesn't modify the contents of documents, it merely returns the results (which you're not doing anything with):
documents.Where(item => myDocuments.Contains(item.ID));
documents is still the full list.
Change this line to something like:
var matchingIDDocs = documents.Where(item => myDocuments.Contains(item.ID));
And then use matchingIDDocs in place of "documents" later in your code.

Linq SelectMany query not working

I have the following database tables where the relationship between Topic and Comment is 1:N
Category
id
name
Topic
id
title
category_id
Comment
id
details
topic_id
deleted (boolean)
I want a query to count total comments in each category. I have the following LINQ query but it doesn't work:
#foreach (var cat in Model.AllPermissionSets.Keys)
{
var commentCount = cat.Topics.Where(c => c.Comments.deleted != 0).SelectMany(x => x.Comments).Count();
#* some other stuff *#
}
In Visual studio I get error IList<Comment> doesn not contain a definition for deleted...
What's the correct syntax to do the above?
Comments is a collection type property on each Topic instance. This collection does not have a deleted property. But each item in the collection(a single instance of Comment) has it.
var commentCount = cat.Topics.Where(c => c.Comments.Any(s=>!s.deleted))
.SelectMany(x => x.Comments).Count();
This will give you the count of non deleted comments from all the posts of the category.
The first part, cat.Topics.Where(c => c.Comments.Any(s=>!s.deleted)) will give you a filtered list of Topic collection which has at least one non deleted comment. In the second part, you are selecting the Comments of All those posts and doing a Count.
Copied from Ivan Stoev's comment below.
The below query will also produce the same result, but more clean.
var commentCount =cat.Topics.SelectMany(t => t.Comments.Where(c => !c.Deleted)).Count();

Finding items from a list in an array stored in a DB field

I have a legacy database that has data elements stored as a comma delimited list in a single database field. (I didn't design that, I'm just stuck with it.)
I have a list of strings that I would like to match to any of the individual values in the "array" in the DB field and am not sure how to do this in Linq.
My list:
List<string> items= new List<string>();
items.Add("Item1");
items.Add("Item2");
The DB field "Products" would contain data something like:
"Item1,Item3,Item4"
"Item3,Item5,Item6"
"Item2,Item7,Item6"
"Item1,Item2"
"Item1"
My first pass at the Linq query was:
var results = (from o in Order
.Where(p=> items.Contains(p.Products)
But I know that won't work. because it will only return the records that contain only "Item1" or "Item2". So with the example data above it would return 0 records. I need to have it return two records.
Any suggestions?
There is a simple clever trick for searching comma-separated lists. First, add an extra , to the beginning and end of the target value (the product list), and the search value. Then search for that exact string. So for example, you would search ,Item1,Item3,Item4, for ,Item1,. The purpose of this is to prevent false positives, i.e., Item12,Item3 finding a match for Item1, while allowing items at the beginning/end of the list to be properly found.
Then, you can use the LINQ .Any method to check that any item in your list is a match to the product list, like the following:
var results = (from o in Order
.Where(o => items.Any(i => (","+o.Products+",").Contains(","+i+",")))
One way would be to parse the list in the Products field:
var results = (from o in Order
.Where(o => items.Any(i => o.Products.Split(',').Contains(i))
But that would parse the string multiple times for each record. You could try pulling back ALL of the records, parsing each record once, then doing the comparison:
var results = from o in Order
let prods = o.Products.Split(',')
where items.Any(i => prods.Contains(i))
select o;

Imroving/Modifying LINQ query

I already have a variable containing some groups. I generated that using the following LINQ query:
var historyGroups = from payee in list
group payee by payee.Payee.Name into groups
orderby groups.Key
select new {PayeeName = groups.Key, List = groups };
Now my historyGroups variable can contain many groups. Each of those groups has a key which is a string and Results View is sorted according to that. Now inside each of those groups there is a List corresponding to the key. Inside that List there are elements and each one those element is an object of a particular type. One of it's fields is of type System.DateTime. I want to sort this internal List by date.
Can anyone help with this? May be modify the above query or a new query on variable historyGroups.
Thanks
It is not clear to me what you want to sort on (the payee type definition is missing as well)
var historyGroups = from payee in list
group payee by payee.Payee.Name into groups
orderby groups.Key
select new {
PayeeName = groups.Key,
List = groups.OrderBy(payee2 => payee2.SomeDateTimeField)
};
Is most straightforward.
If you really want to sort only by date (and not time), use SomeDateTimeField.Date.
Inside that List there are elements and each one those element is an object of a particular type. One of it's fields is of type System.DateTime
This leads me to maybe(?) suspect
List = groups.OrderBy(payee2 => payee2.ParticularTypedElement.DateTimeField)
Or perhaps even
List = groups.OrderBy(payee2 => payee2.ObjectsOfParticularType
.OfType<DateTime>()
.FirstOrDefault()
)
I hope next time you can clarfy the question a bit better, so we don't have to guess that much (and come up with a confusing answer)

LINQ to SQL many to many int ID array criteria query

Ok this should be really simple, but I am doing my head in here and have read all the articles on this and tried a variety of things, but no luck.
I have 3 tables in a classic many-to-many setup.
ITEMS
ItemID
Description
ITEMFEATURES
ItemID
FeatureID
FEATURES
FeatureID
Description
Now I have a search interface where you can select any number of Features (checkboxes).
I get them all nicely as an int[] called SearchFeatures.
I simply want to find the Items which have the Features that are contained in the SearchFeatures.
E.g. something like:
return db.Items.Where(x => SearchFeatures.Contains(x.ItemFeatures.AllFeatures().FeatureID))
Inside my Items partial class I have added a custom method Features() which simply returns all Features for that Item, but I still can't seem to integrate that in any usable way into the main LINQ query.
Grr, it's gotta be simple, such a 1 second task in SQL. Many thanks.
The following query will return the list of items based on the list of searchFeatures:
from itemFeature in db.ItemFeatures
where searchFeatures.Contains(itemFeature.FeatureID)
select itemFeature.Item;
The trick here is to start with the ItemFeatures table.
It is possible to search items that have ALL features, as you asked in the comments. The trick here is to dynamically build up the query. See here:
var itemFeatures = db.ItemFeatures;
foreach (var temp in searchFeatures)
{
// You will need this extra variable. This is C# magic ;-).
var searchFeature = temp;
// Wrap the collection with a filter
itemFeatures =
from itemFeature in itemFeatures
where itemFeature.FeatureID == searchFeature
select itemFeature;
}
var items =
from itemFeature in itemFeatures
select itemFeature.Item;

Resources