I am using this query to calculate the sum of amount and display it in a label. Just because I am using in string it doesn't display values? Any suggestions?
string a;
var query = from r in dt.AsEnumerable()
where r.Field<string>("Code") == strCode
select decimal.Parse(
r.Field<string>("Amount")
.Replace("$", "")
.Replace(",", "")
);
if (query.Count() == 0)
{
a = "0";
}
else
{
foreach (var item in query)
{
a = item.ToString();
}
}
return a;
Parsing dollar amounts
The NumberStyles enumeration from System.Globalization can be used to parse dollar amounts into decimals:
decimal.Parse(r.Field<string>("Amount"), NumberStyles.Currency)
See also Problem parsing currency text to decimal type.
Summing dollar amounts
Also, your for-loop isn't actually adding any of the amounts, it's just assigning each amount to the a variable, so that a is only equal to the last amount at the end:
foreach (var item in query)
{
a = item.ToString();
}
return a;
What you really want to do is to add the amounts:
decimal a = 0;
foreach (var item in query)
{
a = a + item;
// Or even shorter:
a += item;
}
return a.ToString();
Summing with LINQ
But LINQ provides the method Sum() which can be used to replace the for-loop altogether. Also, when Sum() is called on an empty-set of decimals, it already returns 0, so you don't need your if block that checks if the count is 0:
// Don't need this IF block
if (query.Count() == 0)
{
a = "0";
}
return query.Sum().ToString();
Altogther now...
So putting it all together, you get the code below:
// Top of file...
using System.Globalization;
// In your method...
var query =
from r in dt.AsEnumerable()
where r.Field<string>("Code") == strCode
select decimal.Parse(r.Field<string>("Amount"), NumberStyles.Currency);
return query.Sum().ToString();
Try this,
You need to use Sum to get the total amount
string TotalSum = "";
var query = from r in dt.AsEnumerable()
where r.Field<string>("Code") == strCode
select decimal.Parse(r.Field<string>("Amount"), System.Globalization.NumberStyles.Any);
if (query.Count() > 0)
{
TotalSum = string.Format("{0:C}", query.Sum());
}
Label1.Text = TotalSum;
Related
I want to count all the characters in my list to see if I surpass the maxvalue of MaxJsonLength.
This is my controller where I have a list with products.
public JsonResult GetAllProducts()
{
List<ProductNew> allProducts = new List<ProductNew>();
var shopIdOfTheDay = 2;
allProducts = _db.Products
.Where(p => p.Category.ShopId == shopIdOfTheDay && p.Availability)
.OrderBy(p => p.Description)
.ToList();
//count the characters in the list here
int total = 0;
foreach (var value in allProducts)
{
string s = value.ToString();
int i;
i = s.Length;
total = total += i;
Console.WriteLine(total);
}
return new JsonResult { Data = allProducts, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
but the foreach loop is not working, because every string value is 109 characters long and that aint right.
If I break ath value.ToString is see that the value is +
{System.Data.Entity.DynamicProxies.ProductNew_7F6B12BDD7841029155EF84C6372688579A97D5AA4EA2378712AC64A67B25290} SeashellBrawlCorvee.Models.ProductNew {System.Data.Entity.DynamicProxies.ProductNew_7F6B12BDD7841029155EF84C6372688579A97D5AA4EA2378712AC64A67B25290}
So that aint right. There are multiple values in value, so that proberly why I cant cast it to String?
I tried doing an extra foreach. Like:
foreach (var value2 in value) {
string s1 = value2.ToString();
int i1;
i1 = s2.Length;
total = total += i1;
Console.WriteLine(total);
}
Something like this, but thats not working to because I get an error: foreach statement cannot operate on vairables of type 'PRoductNew'because 'ProductNew' does not contain a public definition for 'GetEnumerator'
So what to do?
Check string s = value.ToString();, the content of s may not be the result you want.
Because value is a class which is from ProductNew class, you can't get content through .ToString() method. If you want to count all characters, you should count every content of property in class, like this:
foreach (var value in allProducts)
{
string ID = value.ID.ToString();
string Category = value.Category.ToString();
string Description = value.Description.ToString();
total += (ID.Length + Category.Length + Description.Length);
Console.WriteLine(total);
}
Is there any possiblity to extract only the numbers from a GUID? I'm trying to achieve this because I don't want to display the GUID in a form, but the numbers within, which also are unique.
You can use IsDigit to get only the numbers
var guidstring = Guid.NewGuid().ToString("N");
var getNumbers = (from t in guidstring
where char.IsDigit(t)
select t).ToArray();
DEMO
public string GetNumbersFromGuid(Guid Item)
{
var result = string.Empty;
var guidArray = Item.ToString().ToCharArray();
int n;
foreach (var item in guidArray)
{
if (int.TryParse(item.ToString(), out n) == true)
{
result += item.ToString();
}
}
return result;
}
Call it like:
var MyValue = GetNumbersFromGuid(Guid.NewGuid());
I have a list which contains the name of suppliers. Say
SuppId Supplier Name
----------------------------------
1 Aardema & Whitelaw
2 Aafedt Forde Gray
3 Whitelaw & Sears-Ewald
using following LINQ query
supplierListQuery = supplierListQuery.Where(x => x.SupplierName.Contains(SearchKey));
I can return records correctly in the following conditions,
1) If i am using search string as "Whitelaw & Sears-Ewald" it will return 3rd record.
2) If i am using "Whitelaw" or "Sears-Ewald" it will return 3rd record.
But how can i return 3rd record if i am giving search string as "Whitelaw Sears-Ewald". It always returns 0 records.
Can i use ALL to get this result, but i dont know how to use it for this particular need.
What I usually do in this situation is split the words into a collection, then perform the following:
var searchopts = SearchKey.Split(' ').ToList();
supplierListQuery = supplierListQuery
.Where(x => searchopts.Any(y=> x.SupplierName.Contains(y)));
This works for me:
IEnumerable<string> keyWords = SearchKey.Split('');
supplierListQuery = supplierListQuery
.AsParallel()
.Where
(
x => keyWords.All
(
keyword => x.SupplierName.ContainsIgnoreCase(keyword)
)
);
Thank you all for your quick responses. But the one which worked or a easy fix to handle this was timothyclifford's note on this. Like he said i alterd my answer to this
string[] filters = SearchKey.ToLower().Split(new[] { ' ' });
objSuppliersList = (from x in objSuppliersList
where filters.All(f => x.SupplierName.ToLower().Contains(f))
select x).ToList();
Now it returns the result for all my serach conditions.
Because "Whitelaw" appears in both you will get both records. Otherwise there is no dynamic way to determine you only want the last one. If you know you only have these 3 then append .Last() to get the final record.
supplierListQuery = supplierListQuery.Where(x => x.SupplierName.Contains(SearchKey.Split(' ')[0]));
You need to use some sort of string comparer to create your own simple Search Engine and then you can find strings that are most likely to be included in your result :
public static class SearchEngine
{
public static double CompareStrings(string val1, string val2)
{
if ((val1.Length == 0) || (val2.Length == 0)) return 0;
if (val1 == val2) return 100;
double maxLength = Math.Max(val1.Length, val2.Length);
double minLength = Math.Min(val1.Length, val2.Length);
int charIndex = 0;
for (int i = 0; i < minLength; i++) { if (val1.Contains(val2[i])) charIndex++; }
return Math.Round(charIndex / maxLength * 100);
}
public static List<string> Search(this string[] values, string searchKey, double threshold)
{
List<string> result = new List<string>();
for (int i = 0; i < values.Length; i++) if (CompareStrings(values[i], searchKey) > threshold) result.Add(values[i]);
return result;
}
}
Example of usage :
string[] array = { "Aardema & Whitelaw", "Aafedt Forde Gray", "Whitelaw & Sears-Ewald" };
var result = array.Search("WhitelawSears-Ewald", 80);
// Results that matches this string with 80% or more
foreach (var item in result)
{
Console.WriteLine(item);
}
Output: Whitelaw & Sears-Ewald
If you want an easy (not very handy) solution,
var result = supplierListQuery
.Select(x => normalize(x.SupplierName))
.Where(x => x.Contains(normalize(SearchKey)));
string normalize(string inputStr)
{
string retVal = inputStr.Replace("&", "");
while (retVal.IndexOf(" ") >= 0)
{
retVal = retVal.Replace(" ", " ");
}
return retVal;
}
I am attempting to move slightly away from LINQ which has proven very useful overall, but also quite difficult to read at times.
I used to use LINQ to perform joins (full outer join) but would prefer to do so using for/foreach loops for their simplicity. I just converted one LINQ statement (not PLINQ) into a nested foreach loop and the performance took a severe hit. What used to take seconds is now taking around a minute, see code below.
foreach (var p in PortfolioELT)
{
double meanloss;
double expvalue;
double stddevc;
double stddevi;
bool matched = false;
foreach (var a in AccountELT)
{
if (a.eventid == p.eventid)
{ DO SOME MATH HERE <-----
Any ideas on either
Why this is slower than LINQ Join and
How can I speed it up?
The program fairly obviously does what it needs to, but is too slow.
EDIT:
OLD CODE FULL
public static ConcurrentList<Event> CreateNewELTSUB(IList<Event> AccountELT, IList<Event> PortfolioELT)
{
if (AccountELT == null)
{
return (ConcurrentList<Event>)PortfolioELT;
}
else
{
//Subtract the Account ELT from the Portfolio ELT
var newELT = from p in PortfolioELT
join a in AccountELT
on p.eventid equals a.eventid into g
from e in g.DefaultIfEmpty()
select new
{
EventID = p.eventid,
Rate = p.rate,
meanloss = p.meanloss - (e == null ? 0d : e.meanloss),
expValue = p.expValue - (e == null ? 0d : e.expValue),
stddevc = Math.Sqrt(Math.Pow(p.stddevc, 2) - (e == null ? 0d : Math.Pow(e.stddevc, 2))),
stddevi = Math.Sqrt(Math.Pow(p.stddevi, 2) - (e == null ? 0d : Math.Pow(e.stddevi, 2)))
};
ConcurrentList<Event> list = new ConcurrentList<Event>();
foreach (var x in newELT)
{
list.Add(new Event(x.meanloss, x.EventID, x.expValue, x.Rate, x.stddevc, x.stddevi));
}
return list;
}
}
NEW CODE FULL:
public static ConcurrentList<Event> CreateNewELTSUB(IList<Event> AccountELT, IList<Event> PortfolioELT)
{
if (AccountELT == null)
{
return (ConcurrentList<Event>)PortfolioELT;
}
else
{
//Subtract the Account ELT from the Portfolio ELT
ConcurrentList<Event> newlist = new ConcurrentList<Event>();
//Outer Join on Portfolio ELT
foreach (var p in PortfolioELT)
{
double meanloss;
double expvalue;
double stddevc;
double stddevi;
bool matched = false;
foreach (var a in AccountELT)
{
if (a.eventid == p.eventid)
{
matched = true;
meanloss = p.meanloss - a.meanloss;
expvalue = p.expValue - a.expValue;
stddevc = Math.Sqrt((Math.Pow(p.stddevc, 2)) - (Math.Pow(a.stddevc, 2)));
stddevi = Math.Sqrt((Math.Pow(p.stddevi, 2)) - (Math.Pow(a.stddevi, 2)));
newlist.Add(new Event(meanloss, p.eventid, expvalue, p.rate, stddevc, stddevi));
}
else if (a.eventid != p.eventid) //Outer Join on Account
{
newlist.Add(a);
}
}
if (!matched)
{
newlist.Add(p);
}
}
return newlist;
}
Why this is slower than LINQ Join and
Im skipping answering this on purpose
How can I speed it up?
You're looping over the entire AccountELT collection for every PortfolioELT. You should loop one, and have the other converted to a Dictionary to make finding a specifiec record easier. Something like:
var accountELTIdx = AccountELT.ToDictionary(k => k.eventid);
then
foreach (var p in PortfolioELT)
{
double meanloss;
double expvalue;
double stddevc;
double stddevi;
bool matched = false;
if(accountELTIdx.ContainsKey(p.eventid)
{
var acct = accountELTIdx[p.eventid];
// some maths
}
....
You're creating local variables every iteration, that may or may not ever be used.
double meanloss;
double expvalue;
double stddevc;
double stddevi;
bool matched = false;
You are doing a linear search for matching event id's, if just 1 of the Lists is ordered by "eventid" you could use binary search instead of the wasted effort of a full linear search.
foreach (var a in AccountELT)
{
if (a.eventid == p.eventid)
I'm developing a very basic web search engine that has several parts. After retrieving results according to a user query, I want to calculate rate of each result and then sort results by calculated rate. Here is my query:
var tmpQuery = (from urls in _context.Urls
join documents in _context.Documents
on urls.UrlId equals documents.DocumentId
let words = (from words in _context.Words
join hits in _context.Hits
on words.WordId equals hits.WordId
where hits.DocumentId == documents.DocumentId
select words.Text)
select new { urls, documents, words });
var results = (from r in tmpQuery.AsEnumerable()
where r.urls.ResolvedPath.Contains(breakedQuery, KeywordParts.Url, part) ||
r.documents.Title.Contains(breakedQuery, KeywordParts.Title, part) ||
r.documents.Keywords.Contains(breakedQuery, KeywordParts.Keywords, part) ||
r.documents.Description.Contains(breakedQuery, Description, part) ||
r.words.Contains(breakedQuery, KeywordParts.Content, part)
select new SearchResult()
{
UrlId = r.urls.UrlId,
Url = r.urls.ResolvedPath,
IndexedOn = r.documents.IndexedOn,
Title = r.documents.Title,
Description = r.documents.Description,
Host = new Uri(r.urls.ResolvedPath).Host,
Length = r.documents.Length,
Rate = 0CalculateRating(breakedQuery, r.urls.ResolvedPath, r.documents.Title, r.documents.Keywords, r.documents.Description, r.words)
}).AsEnumerable()
.OrderByDescending(result => result.Rate)
.Distinct(new SearchResultEqualityComparer());
and rate is calculated by this method:
private int CalculateRating(IEnumerable<string> breakedQuery, string resolvedPath, string title, string keywords, string description, IEnumerable<string> words)
{
var baseRate = 0;
foreach (var query in breakedQuery)
{
/*first I'm breaking up user raw query (Microsoft -Apple) to list of broken
queries (Microsoft, -Apple) if broken query start with - that means
results shouldn't have*/
var none = (query.StartsWith("-"));
string term = query.Replace("-", "");
var pathCount = Calculate(resolvedPath, term);
var titleCount = Calculate(title, term);
var keywordsCount = Calculate(keywords, term);
var descriptionCount = Calculate(description, term);
var wordsCount = Calculate(words, term);
var result = (pathCount * 100) + (titleCount * 50) + (keywordsCount * 25) + (descriptionCount * 10) + (wordsCount);
if (none)
baseRate -= result;
else
baseRate += result;
}
return baseRate;
}
private int Calculate(string source, string query)
{
if (!string.IsNullOrWhiteSpace(source))
return Calculate(source.Split(' ').AsEnumerable<string>(), query);
return 0;
}
private int Calculate(IEnumerable<string> sources, string query)
{
var count = 0;
if (sources != null && sources.Count() > 0)
{
//to comparing two strings
//first case sensitive
var elements = sources.Where(source => source == query);
count += elements.Count();
//second case insensitive (half point of sensitive)
count += sources.Except(elements).Where(source => source.ToLowerInvariant() == query.ToLowerInvariant()).Count() / 2;
}
return count;
}
Please guide me to improve performance (speed of my search engine is very very low)
I expect this is down to your from urls in _context.Urls - with no Where on this you're getting a lot of data to then throw away when building up your results. How many items are in tmpQuery / results?