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
});
Related
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
I would like to use this string as a filter to remove some Ids in a linq query
public class ProductKitMakerDto
{
public int Id { get; set; }
public string TitleShort { get; set; }
public string Media { get; set; }
}
[HttpPost]
public ActionResult KitItemSelect(string culture)
{
string productMakerIds = "4174,2196,2201,2460,2508,2204";
//create a list
var productMakerList = new List<ProductKitMakerDto>();
foreach (int i in productMakerIds)
{
productMakerList.Add(new ProductKitMakerDto { Id = i });
}
var itemselects = (from p in _context.Products
where p.Matrix == 2400
select new ProductKitMakerDto()
{
Id = p.Id,
TitleShort = culture == "de" ? p.TitleShortDe :
culture == "fr" ? p.TitleShortFr :
p.TitleShortEn,
Media = "/img/" + p.Photo,
}).ToList();
//From this query I get 40 results.
//Then I want to remove the ones from the list:
//itemselects = itemselects.Where(i => !productMakerList.Any(pml =>pml.Id == i.Id));
//1st (above) I get an Error CS0266 asking for explicit cast. So aplly the modification
itemselects = (List<ProductKitMakerDto>)itemselects.Where(i => !productMakerList.Any(pml =>pml.Id == i.Id));
return Json(itemselects, JsonRequestBehavior.AllowGet);
}
I get 500 (Internal Server Error) - xhr.send( options.hasContent && options.data || null );
I guess the list is empty.
Any idea? Thanks
this does not work
string productMakerIds = "4174,2196,2201,2460,2508,2204";
var productMakerList = new List<ProductKitMakerDto>();
foreach (int i in productMakerIds)
{
productMakerList.Add(new ProductKitMakerDto { Id = i });
}
because you need to split on comma first and parse the string to int:
foreach (string i in productMakerIds.Split(',')) // and parse i to int with int.Parse
but since it's a string literal, initialize it correctly in the first place. Don't use a List<ProductKitMakerDto> because you just need a List<int>, then you can use Contains:
var productMakerList = new List<int>
{
4174, 2196, 2201, 2460, 2508 , 2204
};
you can not cast to a list if it's not a list and Enumerable.Where does not return one:
itemselects = (List<ProductKitMakerDto>)itemselects.Where(i => !productMakerList.Any(pml =>pml.Id == i.Id));
you need to append ToList after the Where
itemselects = itemselects
.Where(i => !productMakerList.Any(pml =>pml.Id == i.Id))
.ToList();
but as mentioned, you could also use this Where before you create that list the first time, so include the condition witha Contains which should be supported:
var itemselects = (from p in _context.Products
where p.Matrix == 2400
&& !productMakerList.Contains(p.Id)
select new ProductKitMakerDto()
{
Id = p.Id,
TitleShort = culture == "de"
? p.TitleShortDe
: culture == "fr" ? p.TitleShortFr : p.TitleShortEn,
Media = "/img/" + p.Photo,
}).ToList();
foreach (string i in productMakerIds.Split(','))
{
productMakerList.Add(new ProductKitMakerDto { Id = int.Parse(i) });
}
I need to return JUST all categories DISTINCTS (without repeat any) from a document using NEST.
In SQL it looks like this:
SELECT DISTINCT Category
FROM Log
ORDER BY Category ASC
Inside ElasticSearch I do this way:
GET log/_search
{
"size":"0",
"aggs" : {
"alias_category" : {
"terms" : { "field" : "category.keyword" }
}
}
}
How can I do that using NEST?
public ICollection<string> SelectAllCategoriesDistinct(ElasticClient client)
{
var searchResponse = client.Search<LogElasticSearch>(s => s
.Query(q => q
.Terms(t => t
.Field(f => f.Category)
)
)
);
return (ICollection<string>)searchResponse;
}
I found a way to do it. Is not a elegant way, but I found in the elastico site (https://discuss.elastic.co/t/c-nest-best-way-of-accessing-properties-of-iaggregate-object/85384/2) and I did this way:
public ICollection<string> SelectAllCategoriesDistinct(ElasticClient client)
{
var searchResponse =
client.Search<LogElasticSearch>(s => s
.Size(0)
.Aggregations(agg => agg
.Terms("categories", t => t
.Field("category.keyword")
)
)
);
var aggregation = searchResponse.Aggregations.Values;
var listOfCategories = new List<string>();
if (searchResponse.Aggregations.Values.FirstOrDefault().GetType() == typeof(BucketAggregate))
{
foreach (IBucket bucket in ((BucketAggregate)aggregation.FirstOrDefault()).Items)
{
if (bucket.GetType() == typeof(KeyedBucket<object>))
{
var valueKey = ((KeyedBucket<object>)bucket).Key;
listOfCategories.Add(valueKey.ToString());
}
}
}
return listOfCategories.OrderBy(c => c).ToList();
}
If someone knows a better way to do it, help me to improve, but that way it reaches the goal.
I would use a composite aggregation to fetch all the terms. In contrast to the terms aggregation, the composite aggregation supports pagination, so multiple requests can be made if there are a lot of terms to fetch
private static void Main()
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool);
var client = new ElasticClient(settings);
var categories = new List<string>();
GetAllCategories(client, categories);
// do something with the categories
foreach(var category in categories)
Console.WriteLine(category);
}
private static void GetAllCategories(IElasticClient client, List<string> categories, CompositeKey after = null)
{
// number of terms to fetch in each request
var size = 10_000;
var response = client.Search<LogElasticSearch>(s => s
.Size(0)
.Aggregations(a => a
.Composite("categories", c => c
.After(after)
.Size(size)
.Sources(so => so
.Terms("category", t => t
.Field("category.keyword")
.Order(SortOrder.Ascending)
)
)
)
)
);
var compositeAgg = response.Aggregations.Composite("categories");
var buckets = compositeAgg.Buckets;
foreach (var bucket in buckets)
{
if (bucket.Key.TryGetValue("category", out string category))
{
categories.Add(category);
}
}
// there may be more
if (buckets.Count == size)
{
GetAllCategories(client, categories, compositeAgg.AfterKey);
}
}
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;
}
}
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
}
);