Extracting only one property in List<Object> to List<String> - c#

public async Task<IEnumerable<String>> GetUsersAsStringBysearch(string userSearch)
{
//This returns List<UserTable>
var item = await riskDBContext.UserTables.Where(e => e.Email.Contains(userSearch)).ToListAsync(); ;
List<string> m_oEnum = new List<string>();
foreach (var user in item)
{
m_oEnum.Add(user.Email);
}
//this is when we fullyindex the table
//var item = await riskDBContext.UserTables.Where(x => EF.Functions.FreeText(x.Email,userSearch)).ToListAsync();
return m_oEnum;
}
var item = await riskDBContext.UserTables.Where(e =>
e.Email.Contains(userSearch)).ToListAsync(); ;
returns List<UserTable>, I want only the email id as an List<string>
Is there a one line statement to achieve, instead of looping the List and adding it to a List<String>

Use .Select(e => e.Email) to create a projection

Related

Combine LINQ and Foreach which in turn creates another list

I have the following piece of code which I am trying to improve:
var ApprovedAllowancesProductIds = from item in ApprovedAllowancesListFiltered select item.ProductId; //(1)
List<Product> productList = new List<Product>();
List<string> partitionProductKeys = new List<string>();
foreach (var item in ApprovedAllowancesProductIds) //(2)
{
string[] partitionKey = new string[] { CountryCD, item.ToString() };
string PartitionKey = partitionKey.ConcatenatedStringWithPipeSeparator();
partitionProductKeys.Add(PartitionKey);
}
var resultProduct = await _tableStorageService.FetchDataByMultiplePartitionKey<Product>(partitionProductKeys, QueryComparisonEnums.Equal);
productList.Add((Product)resultProduct);
For better performance I want to combine the functionality of (2) i.e., the entire foreach loop in (1). I saw some example as: Example1 and Example2 but they don't serve my purpose so please don't mark this as duplicate.
you could combine with Select
var partitionProductKeys = ApprovedAllowancesProductIds
.Select(item =>
{
string[] partitionKey = new string[] { CountryCD, item.ToString() };
return partitionKey.ConcatenatedStringWithPipeSeparator();
})
.ToList();
you could apply the same concept with ApprovedAllowancesListFiltered if you want to merge the fist line as well with this code.
I suggest you remove the outer list completely and loop on the objects instead of the property ProductId of the objects:
List<Product> productList = new List<Product>();
List<string> partitionProductKeys = new List<string>();
foreach (var item in ApprovedAllowancesListFiltered)
{
string[] partitionKey = new string[] { CountryCD, item.ProductId.ToString() };
string PartitionKey = partitionKey.ConcatenatedStringWithPipeSeparator();
partitionProductKeys.Add(PartitionKey);
}
var resultProduct = await _tableStorageService.FetchDataByMultiplePartitionKey<Product>(partitionProductKeys, QueryComparisonEnums.Equal);
productList.Add((Product)resultProduct);
I hope this helps.

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());

How to pass a list of strings through webapi and get the results without those strings?

My code already gets the table without containing a string. How can I get a list without containing a list of strings? I want to get the result of SELECT * FROM table WHERE column NOT IN ('x' ,'y');
public IEnumerable<keyart1> Get(string keyword)
{
List<keyart1> keylist;
using (dbEntities5 entities = new dbEntities5())
{
keylist = entities.keyart1.Where(e => e.keyword != keyword).ToList();
var result = keylist.Distinct(new ItemEqualityComparer());
return result;
}
}
I think i found the answer if anybody interested
public IEnumerable<keyart1> Get([FromUri] string[] keyword1)
{
List<keyart1> keylist;
List<IEnumerable<keyart1>> ll;
using (dbEntities5 entities = new dbEntities5())
{
ll = new List<IEnumerable<keyart1>>();
foreach (var item in keyword1)
{
keylist = entities.keyart1.Where(e => e.keyword != item).ToList();
var result = keylist.Distinct(new ItemEqualityComparer());
ll.Add(result);
}
var intersection = ll.Aggregate((p, n) => p.Intersect(n).ToList());
return intersection;
}
}

EF .Net Core Enumerable.Concat not working

Below is my code
var dbClaimLink = this.Context.Set<ClaimLink>();
var claims = await DbSet
.Include(claim => claim.Parent)
.Include(link => link.ParentLinks)
.ToListAsync();
var newClaimLink = await dbClaimLink.ToListAsync();
var processedClaims = claims.Select(x =>
{
var claimLinks = x.ParentLinks;
if (!claimLinks.Any())
{
return x;
}
var hiddenParents = claimLinks.Select(p => claims.Find(t => t.Id == p.ClaimLinkId));
x.HiddenParents = hiddenParents;
return x;
});
foreach (var objClaim in processedClaims)
{
if (objClaim.Children == null)
objClaim.Children = new List<Claim>();
var lst = newClaimLink.Where(k=> k.ClaimLinkId == objClaim.Id).ToList();
if (lst.Any())
{
foreach (var item in lst)
{
IEnumerable<Claim> newChildren = claims.Where(p => p.Id == item.ClaimId);
objClaim.Children.Concat(newChildren);
}
}
}
it always return old children set without concatenate with new children. I want to those old and new children set concatenate in side of foreach loop
the Concat method returns a new collection with both values and does not alter the original.
Concat will return new object - result of concatination, so you need to save it somewhere: var result = objClaim.Children.Concat(newChildren);
Where is lazy operation, it does not execute in place, only after materialization (ToArray, or foreach call): claims.Where(p => p.Id == item.ClaimId).ToArray()

how to retrieve unique value from xml

i have written a query to retrieve distinct xml node value using foreach
i am trying to retrive distinct BankName and TemplateModel from XML
can any one just a better way to write the query with ienumerable or something like that
my Xml is as follows
<Bank>
<BankName BankName="DohaBank" TemplateModel="CT1">
<ChqBasics>
</ChqBasics>
<XandYPosition>
</XandYPosition>
</BankName>
<BankName BankName="DohaBank" TemplateModel="CT2">
<ChqBasics>
</ChqBasics>
<XandYPosition>
</XandYPosition>
</BankName>
<BankName BankName="IBQ" TemplateModel="CT1New">
<ChqBasics>
</ChqBasics>
<XandYPosition>
</XandYPosition>
</BankName>
my c# code
public List<string> bankload()
{
List<string> bankname=new List<string>();
XDocument doc = XDocument.Load("newtest.xml");
var result= (from item in doc.Descendants("BankName")
select (string)item.Attribute("BankName")).Distinct();
foreach (var item in result)
{
bankname.Add(item.ToString());
}
return bankname;
}
public static List<string> templateload(string bankname)
{
List<string> templatename = new List<string>();
XDocument doc = XDocument.Load("newtest.xml");
var result = (from item in doc.Descendants("BankName")
where item.Attribute("BankName").Value == bankname
select (string)item.Attribute("TemplateModel")).Distinct();
foreach (var item in result)
{
templatename.Add(item.ToString());
}
return templatename;
}
i need to bind the result to a combobox
Why not do this?
public List<string> bankload()
{
return
(
from item in XDocument.Load("newtest.xml").Descendants("BankName")
select (string)item.Attribute("BankName")
)
.Distinct()
.ToList();
}
public static List<string> templateload(string bankname)
{
return
(
from item in XDocument.Load("newtest.xml").Descendants("BankName")
where item.Attribute("BankName").Value == bankname
select (string)item.Attribute("TemplateModel")
)
.Distinct()
.ToList();
}
Do you mean lambdas like this?
public List<string> bankload()
{
return
XDocument
.Load("newtest.xml")
.Descendants("BankName")
.Select(item => (string)item.Attribute("BankName"))
.Distinct()
.ToList();
}
public static List<string> templateload(string bankname)
{
return
XDocument
.Load("newtest.xml")
.Descendants("BankName")
.Where(item => item.Attribute("BankName").Value == bankname)
.Select(item => (string)item.Attribute("TemplateModel"))
.Distinct()
.ToList();
}
Return a list of distinct BankName/TemplateModel combinations in your XML:
var result = doc.Descendants("BankName")
.Select(bn => new
{
BankName = bn.Attribute("BankName").Value,
TemplateModel = bn.Attribute("TemplateModel")
.Value
});

Categories

Resources