I am getting a problem when fetching double value from using linq and converting it into string. My code is:-
public List<ShowDataOnClient> GetCardListToShow()
{
try
{
List<ShowDataOnClient> CardList = new List<ShowDataOnClient>();
using (ProgressCardLINQDataContext c = new ProgressCardLINQDataContext())
{
CardList = (from card in c.GetTable<T_PROGRESSCARD>()
where card.RecordStatus.Equals(RecordStatus.Active)
select new ShowDataOnClient
{
Student=(from student in c.T_STUDENTs
where student.Id.Equals(card.StudentId)
select student.Name).Single().ToString(),
Test=(from test in c.T_TESTs
where test.Id.Equals(card.TestId)
select test.Name).Single().ToString(),
MaxMarks = (from test in c.T_TESTs
where test.Id.Equals(card.TestId)
select test.MaxMarks).Single().ToString(),
MarksObtain=card.MarksObtain.ToString(),
Percentage=card.Percentage.ToString()
}).ToList<ShowDataOnClient>();
}
return CardList;
}
catch
{
return new List<ShowDataOnClient>();
}
}
I have tried this also:-
Percentage=Math.Truncate(card.Percentage).ToString()
and when i pass "N2" in ToString it gives exception "Method 'System.String ToString(System.String)' has no supported translation to SQL."
and the value i got after conversion is like this:- 5.200000000000000e+001
is there anybody to help me..
Your ShowDataOnClient class should store the value of Percentage as a double. You can format the way doubles are presented to the user at a later stage. How you do that depends on the control you're using to show the data.
This has the added benefit that sorting functions would work as expected. If you convert your percentage to string this early, sorting by that column won't look right
% as String % as double
1% 1%
10% 2%
11% 10%
2% 11%
23% 23%
etc. etc.
Try this:
double Percentage = card.Percentage;
string PercentageStr = Percentage.ToString();
This will not invoke linq to sql and give you what you want.
Related
I'm trying to find a way to calculate the average of a column (as a double/float or decimal). I've found the AVG function in MySQL documentation but I can't get it to work. Currently I've got the following code:
public double GetRating(string username)
{
double average;
MySqlConnection databaseConnection = new MySqlConnection(connectionString);
string sumQuery = "select sum('rating') from " + username;
string countQuery = "SELECT COUNT(*) FROM " + username;
using (MySqlCommand sumCommand = new MySqlCommand(sumQuery, databaseConnection))
using (MySqlCommand countCommand = new MySqlCommand(countQuery, databaseConnection))
try
{
databaseConnection.Open();
double sum = (Double)sumCommand.ExecuteScalar();
double columnLength = (Double)countCommand.ExecuteScalar();
average = sum / columnLength;
return average;
}
finally
{
databaseConnection.Close();
}
return average;
}
Now for some reason this does not work. It returns "Unable to cast object of type 'System.Int64' to type 'System.Double'."
The stored data in the database is an int but i'm trying to cast them to double. Any suggestions or solutions? Once again; double/float or decimal are usable for me.
The built-in AVG function (an aggregate function) could be used like so:
select avg(rating) from table_name
Note that, like most aggregate functions, the average will exclude null values (the average of 1, 2, null is 1.5 instead of 1.0). Also, in MySQL the return datatype will be decimal if you're averaging decimal or integer columns so use the appropriate C# datatype.
A couple of things:
What is the data type of the rating column in the table? If it is an integer and not floating-point, please change the data type of sum accordingly to avoid the type-cast error.
As you already know, you may use avg() instead of sum() and then division by count(). Your SQL will look like:
select avg(rating) from table_name
There is a property which is decimal I want to divide that on 1,000,000 to change the size of number to shorten one, I declare a variable which is decimal too. when I divide, it raises "conversion overflow"
my code like bellow :
PrmSales and Amt are both decimal,
var amt = (from p in db.FactTotalAmount
group p by p.FromDate into g
select new outputList
{
Amt= (g.Sum(x => x.PrmSales)/1000000)
}
the error is for type of the field in database that is smaller than the type of property in coding because of that I receive that Error.
thank you nilsk !
I have a for loop that loops a list of transactions, which all contains amount. If the amount is correct, I want that transaction to be included in a new list.
So in code:
decimal searchAmount = 33.03;
foreach (var order in listOforders)
{
if(order.amount == searchAmount)
{
addOrderToList()
}
}
The currency used doesn't use more than two decimals, so that's okay. These three scenarios, should all add the order to the list.
order.Amount = 33.03
search.Amount = 33
order.Amount = 33.03
search.Amount = 33.03
order.Amount = 33.99
search.Amount = 33.9
Note:
This is a search. When the customer comes back, and says "I have a problem with the product I purchased, and it's not purchased on a registered customer", searching for the amount on the customers bank receipt is a great function. This is a retail brick and mortar store scenario, so some customers choose to not register themselves.
If you want to discard the fractional part completely, using a combination of LINQ and Math.Truncate
var orders = listOfOrders.Where(o => Math.Truncate(o.amount) == Math.Truncate(searchAmount))
.ToList();
Math.Truncate returns the integral part of a given decimal, Where selects only appropriate orders (do read up on LINQ's deferred execution if you don't know it) and ToList materializes the query into a list.
EDIT: given your edit, this is probably what you're looking for:
var orders
= listOfOrders.Where(
o => Math.Truncate(o.amount) == Math.Truncate(searchAmount)
&& o.amount.ToString(CultureInfo.InvariantCulture)
.StartsWith(searchAmount.ToString(CultureInfo.InvariantCulture)))
.ToList();
This first verifies if the integral part of the numbers match and then uses string comparison to check if the actual amount starts with what was inputted (by your lazy user).
Use your if condition like this. Round to 2 decimal places and compare.
if((Math.Round(order.amount,2) - Math.Round(searchAmount,2)) <= 0.9M)
{
addOrderToList();
}
What if you use Math.Truncate(number)? Just like:
if(Math.Truncate(order.amount) == Math.Truncate(searchAmount))
If am right you need to do define some maximum difference constant and use it something like that
decimal maxDiff = 0.03;
decimal searchAmount = 33.03;
var result = listOfOrders.Where(o => Math.Abs(o.Amount - searchAmount) <= maxDiff);
You need to use Math.Floor method to match all numbers i.e absolute value
decimal searchAmount = 33.03;
var temp = Math.Floor(searchAmount);
foreach (var order in listOforders)
{
if(Math.Floor(order.amount) == temp)
{
addOrderToList()
}
}
There is no need for any call to Math as a cast to int will do the same. Your code could be changed to;
int searchAmount = 33;
listOforders.Where(o => (int)o.Amount == searchAmount)
.ForEach(o => addOrderToList());
I have a table in my database that has columns 'price', 'percentage' and 'ID'.
Percentage column needs to be calculated using colum 'price' and 'id'. There is an initial price, followed by three increased prices, all of them having the same ID. I need to find a method that calculates the percentage column in my database using C#.
I attach a picture for better understanding how it should be.
I am writing an import system using Linq and I have already imported all the columns, but now I need to calculate percentage for the increasing prices and I am really struggeling with this. Maybe someone have some god suggestions of how I can solve this.
UPDATE:
public static void calculateProcentage(string id, double price, double, double percentage)
{
var percentageQuery = from l in db.Table
where l.ID == id
&& l.Price == price && l.Percentage != percentage
select l;
foreach (Table l in percentageQuery)
{
//double newPercentage = (double) l.Percentage;
//DataTable table = new DataTable();
// int rowCount = table.Rows.Count;
DataGridView dataGridView = new DataGridView();
for (int i = 0; i < dataGridView.Rows.Count; i++)
{
if (l.Building_vigor_ID == building_vigor_id)
{
//var priceRows = db.V_Leases.Select(x => x.Price_sqm).ToList();
// get a list of the rows of the price column
// get a list of the rows of the price column
var priceRows = (from r in db.Table
select r.Price).ToList();
percentage = (double)(priceRows[i] / priceRows[i + 1]);
}
}
}
try
{
db.SubmitChanges();
Console.Write("Percentage updated");
//Console.ReadKey();
}
catch (Exception e)
{
Console.WriteLine(e);
Console.Write("Could not update percentage");
//Console.ReadKey();
}
}
That is what I have tried. I bassicaly wanted to make it like an update method with only updating column percentage. But did not actualy work. I am pretty new with Linq sow it may be some bad code written here.
The disclaimer
I am pretty new with Linq sow it may be some bad code written here.
Your question, and the way you've attempted to solve this, are fraught with inconsistencies and seemingly contradictory expectations.
As it stands, the question you've asked is not answerable due to lack of information. However, I do think I understand what the actual problem is that you're trying to solve, so I'll give you that answer. But first, let me explain how I've interpreted your question.
My assumptions about your actual question
As I understand it, you're trying to calculate the percentage based on the previous value.
A more generalized example:
PRICE % ID
------------------------
100 A 1
103 B 1
100 C 2
150 D 2
A and C should both be 0 as they are the "base" price of their respective ID value.
B should be 3% because its price is 103% of A's price.
D should be 50% because its price is 150% of C's price.
My below answer will assume that this is correct.
There is also a problem with your expected values. In your example, you have listed the percentage of 19.79 (compared to 19.21) as 0.3.
This does not make sense. The difference is 3%. There are two different (acceptable) ways to denote this in the percentage column:
3, because it is expressed as a percentage (3%)
0.03, because it is expressed as a decimal value (3% = 0.03)
Your usage of 0.3 makes no sense, as I would interpret this as either 0.3% (option 1) or 30% (option 2).
In order to maintain consistency, my answer will assume that you want the decimal value (0.03 in the above example)
I assume your data class is constructed as follows:
public class Foo
{
public decimal Price { get; set; }
public decimal Percentage { get; set; }
public int ID { get; set; }
}
I don't quite understand how you're using the method. You supply three parameters (string id, double price, double, double percentage), but then you go on to select your data as follows:
var percentageQuery = from l in db.Table
where l.ID == id
&& l.Price == price && l.Percentage != percentage
select l;
It makes little sense to supply a percentage, and then pick everything that's different from that percentage. You have no idea of knowing what data you're going to get, in what order, and whether or not the found entries are "before" or "after" your mentioned percentage.
Instead, my answer will be a method that recalculates all percentages of a given ID. This seems like a much clearer algorithm.
The assumed answer
Retrieving the data
Your attempt is a weird mix of new and old technologies (LINQ, DataTable), I'm going to use LINQ near exclusively, as I feel the use of DataTable is unwarranted here.
public static void CalculatePercentagesForID(int id)
{
Foo[] rows = db.Table.Where(x => x.ID == id).ToArray();
//... (see the next code block)
}
This is much simpler. Note that I am assuming that you wish to process the entries based on the order that they appear in the database. If you need to order them based on something else (e.g. a date value in your Foo objects), then you will have to use an additional OrderBy, e.g. :
Foo[] rows = db.Table.Where(x => x.ID == id).Orderby(x => x.DateCreated).ToArray();
Processing the data
It's important to notice here that a percentage is calculated off of two (subsequent) rows.
//The first entry is always the "base" price, therefore always 0.
rows[0].Percentage = 0;
for(int i = 1; i < rows.Length; i++)
{
var previous = rows[i-1];
var current = rows[i];
current.Percentage = CalculateDifferenceInPercentage(previous.Price, current.Price);
}
//TODO: save all the objects in "rows" back to the database!
Notice how the for loop starts at 1, not at 0. We skip step 0 because the first element is automatically 0 anyway. The for loop will only process every row after the first.
Calculating the percentage
public static Decimal CalculateDifferenceInPercentage(decimal oldPrice, decimal newPrice)
{
//1.The elaborate calculation
//The comments are example output when oldPrice = 19.21, newPrice = 19.79
var theRatio = newPrice / oldPrice;
// = 1.0301...
var theRatioRounded = Math.Round(theRatio,2);
// = 1.03
var thePercentageDifference = theRatioRounded - 1;
// = 0.03
return thePercentageDifference;
}
Or, if you want a shorter (but harder to read) version:
public static Decimal CalculateDifferenceInPercentage(decimal oldPrice, decimal newPrice)
{
return Math.Round(newPrice / oldPrice , 2) - 1;
}
Some caveats
I've omitted some null-checks for the sake of simplicity, e.g. checking if any rows are returned.
I've omitted how to save the updated entities in the database as it is not pertinent to your actual question about calculating the percentages.
This works both for negative and positive percentages.
Been reading about out/ref and tuple, but for the life of me cannot figure out how to implement a way to return three (3) values (whether within same method that calculates my main value, or with separate methods). I am able to perform a calculation with one value (the main value) which deals with pricing for a service.
Here is a snippet of what I've done to calculate that main value:
public class Calculations
{
public decimal decFinancialAccount(QuoteData quoteData)
{
if (quoteData.StepAssetInformation.FinancialAccountDropDown
== StepAssetInformation.FinancialAccount.None)
return 0;
else if (quoteData.StepAssetInformation.FinancialAccountDropDown
== StepAssetInformation.FinancialAccount.One)
return PriceQuote.priceFinancialAccount;
else if (quoteData.StepAssetInformation.FinancialAccountDropDown
== StepAssetInformation.FinancialAccount.Two)
return (PriceQuote.priceFinancialAccount * 2);
...
else
return 0;
}
public decimal CalculateChapter7(QuoteData quoteData)
{
decimal total = PriceQuote.priceChapter7;
...
total += this.decFinancialAccount(quoteData);
return total;
}
}
The above works out great. It obviously has other decimal's that are added, but you get the idea.
Now, I am wanting to perform additional calculations on the CalculateChapter7 value that is returned.
The first value is a DiscountChapter7 / discount (variable in method?) price: above a certain amount, discounts are applied for every increment of 50. I got no problem listing them all out if I have to (rather than complicating things for myself). There is no set formula for the discounts, I just created an Excel sheet to visualize my discounts (see below).
The second value is a CompareChapter7 / compare (variable in method?) price: for every discounted price I offer, a comparison is made to what other's charge for the same service. Again, there is no formula per se, I just used an Excel sheet to figure those out arbitrarily.
In addition, I'd like to (within the "discount" and "compare") do a simple subtraction to show "savings" (calculated price - discounted price = savings) and "difference" (other attorneys charge - discounted price = difference). I imagine when I get the two values above working that these additional two would be simple.
Here is my Excel sheet (just a small snippet):
A few notes about that:
Between 799 and 999 there are no discounts (the "rounded" column is just to bring those numbers to a 50 increment for my ease of use and are not relevant).
The Excel formulas are pretty straightforward (fee - discounted price = savings; other attorneys charge - discounted price = difference) - which is what I am trying to attain within my code.
Can anyone provide a solid example of how to integrate the "discount" and "comparison" with my calculated price?
Thanks!
I didn't really follow your specific scenario but... if you are trying to return 3 things from a function, you're doing it wrong and your code will be a pain to maintain. Just define a new class that has 3 properties and return an instance of this class.
You need to create a new class that will contain all the return values. If it's not going to be used anywhere else, you could nest the class inside the Calculations class as follows, but that's up to you:
public class Calculations
{
public class Result
{
public decimal Total { get; set; }
public decimal Discount { get; set; }
public decimal Comparison {get; set; }
}
public Result CalculateChapter7(QuoteData quoteData)
{
Result result = new Result();
result.Total = ...;
result.Discount = ...;
result.Comparison = ...;
return result;
}
}
When you do it this way, all three return values are packaged up into a single object which is then returned. Each time you call the method, it creates a new Result object and populates it with all the values for that invocation of the method. So, to read the returned values after calling the method, you would need to read each property out of the returned object. For instance you could do something like this:
Calculations calc = new Calculations();
Calculations.Result result = calc.CalculateChapter7(...);
string output = string.Format("Total = {0}, Discount = {1}, Comparison = {2}", result.Total.ToString(), result.Discount.ToString(), result.Comparison.ToString());