How to use selectmany in linq? - c#

The following is my linq query
var meetingIndividualQuery = meetingsList.SelectMany(o => o.Attendies.Distinct().Where(x => x.CompanyId == company.CompanyId));
I have the following class
public class Meetings
{
public string IndustryCouncil { get; set; }
public string MeetingType { get; set; }
public string MeetingDescription { get; set; }
public string MeetingDate { get; set; }
public string MeetingHours { get; set; }
public string MeetingHourlyValue { get; set; }
public string MeetingTotal { get; set; }
public List<Individual> Attendies { get; set; }
}
With the above query I am getting the correct list of individaul but how I can I use the same query with the same condition to retrieve the list of Meetings. Can you please provide me any code

Following query will return list of meetings, which have at least one attendee with provided company id:
var query = meetingsList.Where(m => m.Attendies.Any(i => i.CompanyId == company.CompanyId));
You can also apply Distinct to Attendies before verifying Any

Related

SQL Query to Linq Query Result into complex object

I have SQL Query ready, and that I want its result into a complex SQL object. I want to use Linq to achieve the result.
public class VMPackageList
{
public string PackageName { get; set; }
public string ShortTitle { get; set; }
}
public class VMPackageItenary
{
public string PackageName { get; set; }
public string Day { get; set; }
public string Title { get; set; }
public string Detail { get; set; }
}
public class VMPackageHighlight
{
public string PackageName { get; set; }
public string Highlightname { get; set; }
public string HighlightDesc { get; set; }
}
The expected result in below class
public class VMPackageDetails
{
public VMPackageList vmPackage { get; set; }
public VMPackageItenary[] vmPackageItenary { get; set; }
public VMPackageHighlight[] vmPackageHighlights { get; set; }
}
Below are the SQL query and its result, the same way I want to get into
SQL table data query
This is my result query
I had tried with below code to achieve but I did not get success
var packages = packageRepository.Table;
var highlights = packageHighlightRepository.Table;
var itenaries = packageItenaryRepository.Table;
var data = (from package in packages
join highlight in highlights on package.PackageName equals highlight.PackageName
join iteratory in itenaries on package.PackageName equals iteratory.PackageName //&&
where package.PackageName == packageName //&& highlight.PackageName equals iteratory.PackageName
select new VMPackageDetails
{
// vmPackage = package
}).ToList();
Can anyone help me to get the result?

Querying nested collection in RavenDb document

I have a filter method using Lucene extensions for a list of Store documents with the following structure:
public class Store {
public string Id { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string Address { get; set; }
public ICollection<Product> Products { get; set; }
}
public class Product {
public string Name { get; set; }
public double Price { get; set; }
}
my filter method:
public IEnumerable<Store> Filter(string term = null)
{
var query = session.Advanced.DocumentQuery<Store>();
if (!string.IsNullOrEmpty(term))
{
var search = $"*{term}*";
var escapeQueryOptions = EscapeQueryOptions.AllowAllWildcards;
query = query
.Search(n => n.Name, search, escapeQueryOptions)
.OrElse()
.Search(n => n.Url, search, escapeQueryOptions)
.OrElse()
.Search(n => n.Address, search, escapeQueryOptions);
}
return query;
}
Now I would like to allow the filter by product's name but I'm unable to figure out how to express this with lucene.

Find a particular element in List<> and fetch whole data of that row if element is found

I have a List<> which contains collection of objects after getting this list of BillSheetDetail I want to find that billWorkDetails[].details_classification =="xyz" and if it is found then fetch all the data of that particular array index of billWorksDetails[] and store it in other array to display.
How can I do this? I am new to C#
public class BillSheetDetail
{
public DateTime creation_date { get; set; }
public string customer_name { get; set; }
public string subject { get; set; }
public decimal tax_rate { get; set; }
public int total_amount { get; set; }
public string special_instruction { get; set; }
public string comment { get; set; }
public List<BillWorkDetail> billWorkDetails { get; set; }
}
[Serializable]
public class BillWorkDetail
{
public string product_name { get; set; }
public decimal quantity { get; set; }
public string unit { get; set; }
public int unit_cost { get; set; }
public int amount { get; set; }
public string remarks { get; set; }
public int row_no { get; set; }
public string details_classifiction { get; set; }
}
You have to combine Enumerable.Where and Any.
List<BillWorkDetail>[] matchingSheetDetails = billSheetDetailList
.Where(sd => sd.billWorkDetails.Any(d => d.details_classifiction == "xyz"))
.Select(sd => sd.billWorkDetails)
.ToArray();
This creates an array of all matching lists. Since your question is unclear, if you actually only want an array of the matching BillWorkDetail objects:
BillWorkDetail[] matchingBillWorkDetails = billSheetDetailList
.SelectMany(sd => sd.billWorkDetails.Where(d => d.details_classifiction == "xyz"))
.ToArray();
SelectMany selects all matching BillWorkDetail out of the List<BillSheetDetail>. Note that both approaches lose the reference to the BillSheetDetail instance from where it came from.
The solution is using the Where clause:
mySheetDetail.billWorkDetails.Where(x => x.details_classification == "xyz").ToList();
Here is a demonstration of the code that is working well: http://ideone.com/s2cUaR
Try this linq method
List<BillWorkDetail> myBillWorkDetails = new Lis<BillWorkDetail>();
myBillWorkDetails = myBillSheetDetail.billWorkDetails.Where(b => b.classifiction == "xyz").ToList();
This code retrieve all BillWorkDetail with classification xyz.

LINQ to Entities does not recognize the method ..., and this method cannot be translated into a store expression

My function is as on lambda expression
public IList<ent_Message> messageDetailsArray(decimal from,decimal to)
{
owncibai_ExamEntities db = new owncibai_ExamEntities();
var details = db.Messages.OrderBy(or=>or.mDate).Where(wh => (wh.userNumber==from && wh.messageTo==to) || (wh.messageTo==from && wh.userNumber==to)).Select(a => new ent_Message
{
isRead = a.isRead,
mDate = a.mDate,
Message1 = a.Message1,
messID = a.messID,
userNumber = a.userNumber,
messageTo=a.messageTo,
Name=a.User.First_Name+" "+a.User.Last_Name,
photo = (db.MessagePhotoes.Where(ph => ph.messID == a.messID).Select(b => new ent_MessagePhoto
{
msgPhoto=b.msgPhoto,
srl=b.srl
})).ToList()
}).ToList();
var update = db.Messages.Where(wh => wh.messageTo == from).ToList();
update.ForEach(a => a.isRead = true);
db.SaveChanges();
return details;
}
It works fine when I remove Photo parameter from list. While I add photo it is giving following error.
LINQ to Entities does not recognize the method 'System.Collections.Generic.List1[Entities.ent_MessagePhoto] ToList[ent_MessagePhoto](System.Collections.Generic.IEnumerable1[Entities.ent_MessagePhoto])' method, and this method cannot be translated into a store expression.
Entity class is as follows
public class ent_Message{
public decimal messID { get; set; }
public Nullable<decimal> userNumber { get; set; }
public Nullable<decimal> messageTo { get; set; }
public Nullable<System.DateTime> mDate { get; set; }
public string ip { get; set; }
public string Message1 { get; set; }
public Nullable<bool> isRead { get; set; }
public Nullable<decimal> parentID { get; set; }
public string Name { get; set; }
public IList<ent_MessagePhoto> photo { get; set; }
}
I am totally confused where I am wrong in photo...
Thanks in advance
This bit:
photo = (db.MessagePhotoes.Where(ph => ph.messID == a.messID).Select(b => new ent_MessagePhoto
{
msgPhoto=b.msgPhoto,
srl=b.srl
})).ToList() //<-right here
appears inside your outer Select clause. When the IQueryProvider tries to convert your outer Select statement to valid SQL, it will see an inner Select, which of course can be converted to SQL, but then it will hit the ToList() call and fail, because there is no equivalent in SQL.
If you want to perform some operations in your Select projection that can't be done in SQL, they need to be done against the query result set in-memory on the .NET application side. One common way to do this is to put a ToList() before your select statement - this will be interpreted as "send the Where and OrderBy parts to SQL, bring the full result set back into a List, then perform the Select projection".
ent_MessagePhoto must be in the class definition
public class ent_Message<ent_MessagePhoto>
{
public decimal messID { get; set; }
public Nullable<decimal> userNumber { get; set; }
public Nullable<decimal> messageTo { get; set; }
public Nullable<System.DateTime> mDate { get; set; }
public string ip { get; set; }
public string Message1 { get; set; }
public Nullable<bool> isRead { get; set; }
public Nullable<decimal> parentID { get; set; }
public string Name { get; set; }
public IList<ent_MessagePhoto> photo { get; set; }
}​
Thanks for your suggestion I resolved this issue. Issue was version only. I was using 5.x and updated to 6.x and working fine.

Find object with in class using LINQ

I want to return the item that has the profile ID I send. So in order to do this I will need to loop through all of the Items -> WebProproperties -> profile. The Class structure is at the end of the question.
I would rather use LINQ than create a nested foreach. I have been trying to get this to work for more than an hour now. I am stuck.
My first idea was to simply use where. But that doesn't work because you need to have something on the other side that needs to equal.
this.Accounts.items.Where(a => a.webProperties.Where(b => b.profiles.Where(c => c.id == pSearchString)) ).FirstOrDefault();
My second idea was to try using Exists which I don't have much experience with:
Item test = from item in this.Accounts.items.Exists(a => a.webProperties.Exists(b => b.profiles.Exists(c => c.id == pSearchString))) select item;
This doesn't work either:
Could not find an implementation of query pattern for source type 'Bool'
public RootObject Accounts {get; set;}
public class RootObject
{
public string kind { get; set; }
public string username { get; set; }
public int totalResults { get; set; }
public int startIndex { get; set; }
public int itemsPerPage { get; set; }
public List<Item> items { get; set; }
}
public class Profile
{
public string kind { get; set; }
public string id { get; set; }
public string name { get; set; }
public string type { get; set; }
}
public class WebProperty
{
public string kind { get; set; }
public string id { get; set; }
public string name { get; set; }
public string internalWebPropertyId { get; set; }
public string level { get; set; }
public string websiteUrl { get; set; }
public List<Profile> profiles { get; set; }
}
public class Item
{
public string id { get; set; }
public string kind { get; set; }
public string name { get; set; }
public List<WebProperty> webProperties { get; set; }
}
You can use Any() to determine existence. Also, note that many of the extension methods have overloads which take a predicate, including FirstOrDefault():
this.Accounts.items.FirstOrDefault(a => a.webProperties
.Any(b => b.profiles
.Any(c => c.id == pSearchString)));
You are looking for the .Any() operation I think. This will return true/false for whether there are any items matching your query.
For example:
if (this.Accounts.Items.Any(i=>i.webProperties.Any(wp=>wp.profiles.Any(p=>p.id == MySearchId)));
EDIT: You have full answer (was posted while I was composing mine) and as pointed out in comments my answer isn't actually returning your found item, just letting you know whether there is one. You can rework the first .Any to be a .FirstOrDefault to get that match.
E.g.
var result = this.Accounts.Items.FirstOrDefault(i=>i.webProperties.Any(wp=>wp.profiles.Any(p=>p.id == MySearchId)))
You can use the below mentioned code.
var abc = rr.items.Where(p => p.webProperties.Any(c => c.profiles.Any(d => d.id == "1"))).FirstOrDefault();
Just for your reference, your class should look like:
public class RootObject
{
public string kind { get; set; }
public string username { get; set; }
public int totalResults { get; set; }
public int startIndex { get; set; }
public int itemsPerPage { get; set; }
private List<Item> _items=new List<Item>();
public List<Item> items
{
get { return _items; }
set { _items = value; }
}
}

Categories

Resources