Create c# lambda expression in a loop - c#

How can I convert the following lambda expression for running a SharePoint query in CSOM to accept an array of parameters:
Current working version:
var listItems = list.GetItems(query);
clientContext.Load(listItems,
items => items.Include(
item => item["Title"],
item => item.RoleAssignments
)
);
clientContext.Load(list, l => l.Id, l => l.DefaultDisplayFormUrl);
clientContext.ExecuteQuery();
How I would like it to work:
var fields = new List<string>()
{
"Title",
"ID",
"DocumentOrder",
"FileRef"
};
var listItems = list.GetItems(query);
clientContext.Load(listItems,
items => items.Include(
item => fields,
item => item.RoleAssignments
)
);
clientContext.Load(list, l => l.Id, l => l.DefaultDisplayFormUrl);
clientContext.ExecuteQuery();
This throws an error, is it possible to pass in a dynamic list?

Though not ideal, I have been able to achieve what I am attempting to do by calling Load several times in a loop:
var fieldNames = new List<string>()
{
"Title",
"ID",
"DocumentOrder",
"FileRef"
};
var listItems = list.GetItems(query);
foreach (var fieldName in fieldNames)
{
clientContext.Load(listItems,
items => items.Include(
item => item[fieldName]
)
);
}
clientContext.ExecuteQuery();

Related

Access items in list pertaining to GroupBy() item

I am instantiating a List, derived from an ObservableCollection:
var paidTrips = PaidTrips
.GroupBy(p => new {p.LicenseHolderID})
.ToList();
Which, through a foreach loop, gives me access to the various distinct values in LicenseHolderID.
foreach (var licenseHolder in paidTrips) {
// accessing the string value of LicenseHolderID
// but no access to the other items
}
What I need help with:
How can I obtain access to the other items in paidTrips, which pertain to LicenseHolderID? (Why: I am creating invoices, one per LicenseHolderID, and I am building the invoice with the data from all the other collection properties).
To give some context, here's the full collection I am working with:
PaidTrips.Add(new PaidTrip {
LicenseHolderID = dr[0].ToString(),
VehicleID = dr[1].ToString(),
Year = dr[2].ToString(),
Month = dr[3].ToString(),
Payment = (decimal)dr[4],
PaymentNet = (decimal)dr[5],
OrderFee = (decimal)dr[6],
PaymentFee = (decimal)dr[7],
TripVATcode = (decimal)dr[8],
LicenseHolderInvoiceID = dr[9].ToString(),
TripFeeNet = (decimal)dr[10],
TripFeeVATcode = (decimal)dr[11],
RidelRegionInvoiceID = dr[12].ToString(),
});
It does depend what your looking to do with the data for each invoice? are you looking to summarise the data within each LicenseHolderID group?
var PaidTrips = new List<PaidTrip>();
var paidTrips = PaidTrips
.GroupBy(p => new { p.LicenseHolderID })
.ToList();
foreach (var group in paidTrips)
{
var licenseHolderID = group.Key.LicenseHolderID;
//ie here total payment (This sums all payments for this LicenseHolderID)
var totalPayment = group.Sum(x => x.Payment)
// count of payments made (This Counts all Payments greater than 0)
var totalPayments = group.Count(x => x.Payment > 0)
//Use variables in your invoice generation
}
or as above iterate through each group item and access it in singular form.
If I understand you correctly, you want to access each group member's property. To achieve this, you should use nested foreach to traverse each group and access its members.
var PaidTrips = new List<PaidTrip>();
var paidTrips = PaidTrips
.GroupBy(p => new { p.LicenseHolderID })
.ToList();
foreach (var group in paidTrips)
{
var licenseHolderID = group.Key.LicenseHolderID;
foreach (var paidTrip in group.ToList())
{
Console.WriteLine(paidTrip.TripFeeNet);
}
}
foreach (var licenseHolder in paidTrips) {
// accessing the string value of LicenseHolderID
if (licenseHolder.Key == desiredLicenseHolderID){
foreach (var paidItem in licenseHolder){
paidItem.VehicleID = .......
}
}
}
The .GrouBy() Returns a IGrouping object which contains the Key and the elements grouped by the key. To access the elements of the Key grouping you are after once you iterated through the items and found the one, you can simply iterate through the item as an array.

Remove duplicate emails from to , cc and bcc to send grid

I have a lambda expression to remove duplicate emails from to cc and bcc.
lstCCEmailAddress.Remove(lstCCEmailAddress.Where(t => t.Email.Contains(email.Email, StringComparison.OrdinalIgnoreCase)).FirstOrDefault());
but the thing is I want to remove all the duplicate emails just not FirstOrDefault.
which one should I replace FirstOrDefault with
How can I re-write the above query.
Thanks in advance.
To remove duplicates for all those fields (TO,CC,BCC),
first you need to run distinct on "To"
second run distinct on "cc" then remove any emails which does exists from "to".
third run distinct on "bcc" and remove any records which does exists from "to" and "cc" fields
[Fact]
public void TestUniqeEmails()
{
var listToEmail = new List<string> { "a#a.com", "b.com", "b.com" };
var listCCToEmail = new List<string> { "a#a.com", "b.com", "c.com" };
var listBCCToEmail = new List<string> { "a#a.com", "b.com", "c.com", "d.com" };
var uniqueToEmail = listToEmail.Distinct();
var uniqueCCEmail = listCCToEmail
.Where(e => !uniqueToEmail.Any(e.Contains))
.Distinct();
var uniqueBCCEmail = listBCCToEmail
.Where(e => !listToEmail.Any(e.Contains))
.Where(e => !uniqueCCEmail.Any(e.Contains))
.Distinct();
Assert.Equal(2, uniqueToEmail.ToList().Count);
Assert.Single(uniqueCCEmail.ToList());
Assert.Single(uniqueBCCEmail.ToList());
}
You can use the .Distinct() function Of Linq.
static void Main(string[] args)
{
List<string> mail = new List<string>() { "test#gmail", "blub#gmail", "test#gmail" };
var x = mail.Distinct();
foreach (var item in x)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
Result:
test#gmail
blub#gmail
For more information:
https://learn.microsoft.com/de-de/dotnet/api/system.linq.enumerable.distinct?view=net-5.0
You can group by and select group
var DistinctItems = lstCCEmailAddress.GroupBy(x => x. Email).Select(y => y.First());

The collection has not been initialized

I am trying to retrieve all items from a Sharepoint library with CSOM and create a list of it. I am sure it has something to do with the order of the code. The question is how?
ListItemCollection collListItem = oList.GetItems(camlQuery);
var newList = new List<Item>();
var items = oList.GetItems(camlQuery);
context.Load(collListItem);
context.ExecuteQuery();
foreach (var col in items)
{
newList.Add(new Item()
{
ID = Convert.ToInt32(col["ID"]),
});
}
I get the following error:
The collection has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested
You should have loaded the items object not the collListItems thus your code should look following:
ListItemCollection collListItem = oList.GetItems(camlQuery);
var newList = new List<Item>();
var items = oList.GetItems(camlQuery);
context.Load(items);
context.ExecuteQuery();
I have a same problem, then I recalled ExecuteQuery() below foreach loop and that worked for me
ListItemCollection recruitmentItems= Recuitment.GetItems(camlQuery);
cc.Load(recruitmentItems, items => items.Include(
x => x.Id,
x => x["Title"],
x => x["Email"],
x => x["Phone"]
));
cc.ExecuteQuery();
foreach (ListItem item in recruitmentItems)
{
ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
ListItem newItem = Applicant.AddItem(itemCreateInfo);
newItem["Title"] = item["Title"];
newItem["Email"] = item["Email"];
newItem["PhoneNumber"] = item["Phone"];
newItem.Update();
}
cc.ExecuteQuery();

Linq: Return a new list of different type

Given a return of type "AccountItem", I want to filter and sort to a new list of type FDKeyValue<>
I am trying to do this without looping and I thought I could do something like this:
var monthlyList = accountList.Where(x => x.RoleType == "Metric")
.OrderBy(x => x.EntityName)
.Select(new FDKeyValue<long, string>{}
{
"Field", "Field"
}
);
here is what I have working with a loop
var accountList = DBEntity.ReturnAccountListBySearch((int)this.PageLanguageType, "");
var monthlyList = accountList.Where(x => x.RoleType == "Metric").OrderBy(x => x.EntityName).ToList();
this.MonthlyAccountList = new FDKeyValue<long,string>();
foreach (var item in monthlyList)
{
this.MonthlyAccountList.Add(item.EntityID, item.EntityName);
}
This syntax must help
var monthlyList = accountList.Where(x => x.RoleType == "Metric")
.OrderBy(x => x.EntityName)
.Select(x => new FDKeyValue<long, string>
{
x.EntityID, x.EntityName
}
);

Collections list and dictionary

I have a list that contains roleids and a dictionary that has database of roleids and menus accessible to that roleid.
Suppose a user has role 1,2,3 then how do I retrieve the distinct menus he can access from a dictionary?
List<int> roleids = new List<int>();
roleids.Add(1);
roleids.Add(2);
roleids.Add(3);
Dictionary<int, List<String>> Links = new Dictionary<int, List<string>>
{
{ 1, new List<String> { "Home", "About Us", "Logout", "Help" } },
{ 2, new List<String> { "Home", "Products", "Logout", "Help" } },
{ 3, new List<String> { "Home", "Customers", "Users", "Help" } }
};
I want to create a new list that contains menus accessible to user based on values in List roleids
If you do your initial select across the roleids list - you can leverage the fast-lookup nature of the dictionary
var menuItems = roleids
.Select(id => Links[id])
.SelectMany(roles => roles)
.Distinct();
Try this:
var distinct = Links
.Where(i => roleids.Contains(i.Key))
.SelectMany(i => i.Value).Distinct()
.ToList();
Retrieve at first Links where role id in user's roleids, then select from this subset the values and avoid duplicates with distinct:
var menus = Links.Where(l => roleids.Contains(l.key))
.SelectMany(k => k.Value)
.Distinct();
use this algorithm
public static List<string> GetMenuItems(List<int> userRoles)
{
var roleids = new List<int>();
roleids.Add(1);
roleids.Add(2);
roleids.Add(3);
var Links = new Dictionary<int, List<string>>()
{
{1,new List<String> {"Home","About Us","Logout","Help"}},
{2,new List<String>{"Home","Products","Logout","Help"}},
{3,new List<String>{"Home","Customers","Users","Help"}}
};
var roleLinks = Links
.Where(item => userRoles.Contains(item.Key))
.SelectMany(item => item.Value)
.ToList()
.Distinct();
}

Categories

Resources