I am working with C# and Linq and what I intend is to show a series of data that I add to a list with the currency format.
Data in SQL Server (RealEjecutado <-- is what i want to convert)
100000.00
I want it to be displayed like this:
$100,000.00
My code
List<Dashboard> list = new List<Dashboard>();
using (Web_INCAEntities dc = new Web_INCAEntities())
{
var v = (from a in dc.TBL_PBI
select new Dashboard
{
id = a.id,
RealEjecutado = a.RealEjecutado,
PlanVigente = a.PlanVigente,
Reprogramacion = a.Reprogramacion
});
list = v.ToList();
}
return View("../Dashboard/PontoHorizonte/Graficas", list);
Markup:
#grid.GetHtml(
tableStyle: "fl-table",
htmlAttributes: new { id = "tablaadmin" },
columns: grid.Columns(
grid.Column(header: "Real Ejecutado", format: #<text><div class="" data-id="#item.id" data-propertyname="RealEjecutado" id="" ><p id="userinput">#item.RealEjecutado</p></div></text>),
grid.Column(header: "Plan Vigente", format:#<text><div class="" data-id="#item.id" data-propertyname="PlanVigente">#item.PlanVigente</div></text>),
grid.Column(header: "Proyección INCA", format:#<text><div class="" data-id="#item.id" data-propertyname="Reprogramacion">#item.Reprogramacion</div></text>)
)
)
I have not found on the web something that works for me, that is why I ask your help to solve this, thanks in advance
Building off of Brandon's answer, you can do
i.ToString("C", CultureInfo.CreateSpecificCulture("en-US"))
to get the dollar format like so
using (Web_INCAEntities dc = new Web_INCAEntities())
{
var v = (from a in dc.TBL_PBI
select new Dashboard
{
id = a.id,
RealEjecutado = a.RealEjecutado,
PlanVigente = a.PlanVigente,
Reprogramacion = a.Reprogramacion
});
list = v.ToList().Select(x => new Dashboard
{
id = x.id,
RealEjecutado = Decimal.TryParse(x.RealEjecutado, out decimal i) ? i.ToString("C", CultureInfo.CreateSpecificCulture("en-US")) : x.RealEjecutado,
PlanVigente = x.PlanVigente,
Reprogramacion = x.Reprogramacion
}).ToList();
}
return View("../Dashboard/PontoHorizonte/Graficas", list);
This is possibly not the most efficient way to accomplish this, but it should work given what you said in the question. The second select is because I believe LinqToEntities will complain about the function usages. This will try to parse the value to Decimal. If successful, it will then use the currency string converter. If it fails, it will just use the bare value of RealEjecutado.
using (Web_INCAEntities dc = new Web_INCAEntities())
{
var v = (from a in dc.TBL_PBI
select new Dashboard
{
id = a.id,
RealEjecutado = a.RealEjecutado,
PlanVigente = a.PlanVigente,
Reprogramacion = a.Reprogramacion
});
list = v.ToList().Select(x => new Dashboard
{
id = x.id,
RealEjecutado = Decimal.TryParse(x.RealEjecutado, out decimal i) ? i.ToString("C") : x.RealEjecutado,
PlanVigente = x.PlanVigente,
Reprogramacion = x.Reprogramacion
}).ToList();
}
return View("../Dashboard/PontoHorizonte/Graficas", list);
public static string DecimalToFormattedStringCurrency(decimal? decimalValue, string decimalFormatter = null)
{
if (String.IsNullOrWhiteSpace(decimalFormatter))
{
decimalFormatter = "{0:C0}";
}
return decimalValue.HasValue ? String.Format(decimalFormatter, decimalValue) : null;
}
Related
I'm working with a third part service of my client that is providing me a list of products and services, which is a little bit of a mess.
The list will return all of the services for the product but the product repeats itself, for example:
The product A has the service A and the product A also has the service B so, when i receive the list i will get two products A with services A and B
What i need to do is to group all of the products to get only one with all of it's services and i have done so but i'm worried about performance because i think my solution isn't the 'best' one:
var productsNormalized = products.Data.AsEnumerable().Select(x => new ProdutoSSO
{
CodigoServico = int.Parse(string.IsNullOrEmpty(x["CodigoServico"].ToString()) ? "0" : x["CodigoServico"].ToString()),
CodigoPeca = int.Parse(string.IsNullOrEmpty(x["CodigoPeca"].ToString()) ? "0" : x["CodigoPeca"].ToString()),
CodigoFamilia = int.Parse(string.IsNullOrEmpty(x["CodigoFamilia"].ToString()) ? "0" : x["CodigoFamilia"].ToString()),
Familia = x["Familia"].ToString(),
Servico = x["Servico"].ToString(),
Peca = x["Peca"].ToString(),
Hash = x["Hash"].ToString(),
Valor = decimal.Parse(string.IsNullOrEmpty(x["Valor"].ToString()) ? "0" : x["Valor"].ToString())
})
.GroupBy(x => new { x.CodigoPeca, x.CodigoFamilia, x.Familia, x.Peca })
.Select(x => new ProdutoGroup
{
Produto = new Produto
{
CodigoPeca = x.Key.CodigoPeca,
CodigoFamilia = x.Key.CodigoFamilia,
Familia = x.Key.Familia,
Peca = x.Key.Peca
},
Servicos = x.Select(y => new ProdutoServico
{
CodigoServico = y.CodigoServico,
Hash = y.Hash,
Servico = y.Servico,
Valor = y.Valor
}).ToList()
});
Is there a better way to achieve this or this is as good as it gets?
Using Aggregate you could do something like this (assuming you are starting with a list of ProdutoSSO, which might not be entirely necessary):
var productsNormalized = productoSSOs
.Aggregate(new Dictionary<Produto,List<ProdutoServico>>(ProductoComparer),
(p,c) => {
var product = new Produto
{
CodigoPeca = c.CodigoPeca,
CodigoFamilia = c.CodigoFamilia,
Familia = c.Familia,
Peca = c.Peca
};
var service = new ProdutoServico
{
CodigoServico = c.CodigoServico,
Hash = c.Hash,
Servico = c.Servico,
Valor = c.Valor
};
if (!p.ContainsKey(product))
{
p[product] = new List<ProductoServico>() { service };
}
else
{
p[product].Add(service);
}
return p;
});
Where ProductoComparer is an IEqualityComparer<Producto> (or alternatively you could implement Equals and GetHashCode in Producto, or you could just generate a key some other way - concatenating fields together, for example).
This is obviously untested since I don't have the original classes or data.
This would give you a Dictionary<Producto, List<ProductoServico>> which might be all you need, or you can easily transform it into an IEnumerable<ProdutoGroup> if you want.
I want to order my list by idEtatD but this attribute isn't my table primarykey or id it's a normal attribute migrated from another table,nut OrderBy or OrderByDescending didn't give me a result my list still not ordered by idEtatD.
public ActionResult ListeDemande( int? page)
{
traçabilitérepository=new TraçabilitéDemandeRepository(db);
var listdemandes = (from d in db.Demande_Gabarit
join t in db.Traçabilité_Demande_Gabarit
on d.id_demande equals t.iddemande into ThisList
from t in ThisList.DefaultIfEmpty()
select new
{
id_demande=d.id_demande,
NumDemande = d.NumDemande,
Emetteur = d.Emetteur,
Date = d.Date,
Ligne = d.Ligne.designation,
Etat = t.Etat_Demande_Gabarit.EtatDemande
}).ToList().Select(x => new DemandeViewModel()
{
NumDemande = x.NumDemande,
Emetteur = x.Emetteur,
Date = x.Date,
designation = x.Ligne,
EtatDemande = x.Etat,
id_demande = x.id_demande
});
int pageSize = 10;
int pageNumber = (page ?? 1);
return View(listdemandes.OrderByDescending(x => x.idEtatD).ToList().ToPagedList(pageNumber, pageSize));
}
Please I need your help and thank you.
You can order the items at the beginning, but you need to include it in the list:
traçabilitérepository = new TraçabilitéDemandeRepository(db);
var listdemandes = (from d in db.Demande_Gabarit
join t in db.Traçabilité_Demande_Gabarit
on d.id_demande equals t.iddemande into ThisList
from t in ThisList.DefaultIfEmpty()
orderby t.idEtatD descending
select new
{
id_demande = d.id_demande,
NumDemande = d.NumDemande,
Emetteur = d.Emetteur,
Date = d.Date,
Ligne = d.Ligne.designation,
Etat = t.Etat_Demande_Gabarit.EtatDemande,
idEtatD = XXXX
}).ToList().Select(x => new DemandeViewModel()
{
NumDemande = x.NumDemande,
Emetteur = x.Emetteur,
Date = x.Date,
designation = x.Ligne,
EtatDemande = x.Etat,
id_demande = x.id_demande
});
i have many objects like this:
var obj4 = new Data { name = "person", date = DateTime.Now.AddDays(1), data = "pr-214-2-20151224-word2-word3" };
i want to write a linq query that result be this:
result=[name=person, date=04/09/2016 12:00:00 AM, data=[2,3]]//2 and 3 are the numbers after word
so far i tried this:
var listak=new List<Data>{obj,obj2,obj3,obj4};
var u = listak.OrderByDescending(s => s.date).TakeWhile(s => s.date > DateTime.Now).Select(s=>new
{
name=s.name,
date=s.date,
data=s.data.Split(new []{"-"},StringSplitOptions.None).Select(m=>new
{
word = m.Where(c=>m.StartsWith("word")).Select(c=>m.Remove(0,4))//this line is incorrect, i dont know how to correct this part
})
});
but i cant get what i want, how can i achieve that?
You can try this :
var obj4 = new { name = "person", date = DateTime.Now.AddDays(1), data = "pr-214-2-20151224-word2-word3" };
var listak = new[] { obj4 }.ToList();
var u = listak.OrderByDescending(s => s.date).TakeWhile(s => s.date > DateTime.Now).Select(s => new
{
name = s.name,
date = s.date,
data = s.data.Split(new[] { "-" }, StringSplitOptions.None).Where(c => c.StartsWith("word")).Select(m => m.Remove(0, 4))
});
Console.Write(u);
I am trying to select a few rows from a datatable. I am selecting two of the columns and how can I use a where clause in the below statement?
cars = new Head
{
heading = (string)dr["head"],
subHeads = dt.Select(r => new SubHead
{ // how to use a where clause here?
subHeading = (string)r["subhead"],
cars = dt.Select(r2 => new Cars
{ // how to use a where clause here?
name = (string)r2["name"],
quantity = (string)r2["qty"],
}).ToList()
}).ToList()
};
You could use,
dt.where(e => {check something}).Select({select code here})
Do this on both the places. Hope this helps.
You need to call the Where before you select. Example:
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var contacts = ds.Tables["Contact"].AsEnumerable();
var orders = ds.Tables["SalesOrderHeader"].AsEnumerable();
var query =
contacts.SelectMany(
contact => orders.Where(order =>
(contact.Field<Int32>("ContactID") == order.Field<Int32>("ContactID"))
&& order.Field<decimal>("TotalDue") < 500.00M)
.Select(order => new
{
ContactID = contact.Field<int>("ContactID"),
LastName = contact.Field<string>("LastName"),
FirstName = contact.Field<string>("FirstName"),
OrderID = order.Field<int>("SalesOrderID"),
Total = order.Field<decimal>("TotalDue")
}));
foreach (var smallOrder in query)
{
Console.WriteLine("Contact ID: {0} Name: {1}, {2} Order ID: {3} Total Due: ${4} ",
smallOrder.ContactID, smallOrder.LastName, smallOrder.FirstName,
smallOrder.OrderID, smallOrder.Total);
}
taken from here.
I have some working code that retrieves data from data base. It is interesting for me to get some better code for my solution. Are there some ways to combine two queries into one or something like this?
Dim customerTitlesAndIDs = contex.CustomerTable.Select(Function(row) New
With {.ID = row.ID, .CustomerTitle = row.Title}).ToList()
Dim cutomerIdPayment = contex.CustomerPayments.Select(Function(table) New
With
{
.ID = table.CustomerID,
.Range = table.PaymentsRange,
.Values = table.Values
}).ToList()
Dim customerInfos As New List(Of SCustomerInfo)
For Each customer In customerTitlesAndIDs
Dim cID As Integer = customer.ID
customerInfo.Add(New SCustomerInfo(CreateCustomerTable(), cID, customer.CustomerTitle))
For Each cutomerPayments In cutomerIdPayment
If cutomerPayments.ID = cID Then
Dim rangeValue(1) As Object
rangeValue(0) = cutomerPayments.Range
rangeValue(1) = cutomerPayments.Values
Dim dtRow As DataRow = customerInfos.Last().PaymentTable.NewRow()
dtRow.ItemArray = rangeValue
customerInfos.Last().PaymentTable.Rows.Add(dtRow)
End If
Next
Next
Return customerInfos
Same code with C# (hope no syntax errors occurred):
var customerTitlesAndIDs = contex.CustomerTable.Select(row => new
{ .ID = row.ID, .CustomerTitle = row.Title }).ToList();
var cutomerIdPayment = contex.CustomerPayments.Select(table => new
{
.ID = table.CustomerID,
.Range = table.PaymentsRange,
.Values = table.Values
}).ToList();
List<SCustomerInfo> customerInfos = new List<SCustomerInfo>;
foreach (var customer in customerTitlesAndIDs)
{
int cID = customer.ID;
customerInfos.Add(new SCustomerInfo(CreateCustomerTable(), cID, customer.CustomerTitle));
foreach (var cutomerPayments in cutomerIdPayment)
{
if (cutomerPayments.ID = cID)
{
object[] rangeValue = new object[1] {cutomerPayments.Range, cutomerPayments.Values};
DataRow dtRow = customerInfos.Last().PaymentTable.NewRow();
dtRow.ItemArray = rangeValue;
customerInfos.Last().PaymentTable.Rows.Add(dtRow);
}
}
}
SCustomerInfo represented by folowing Structure (code is simplified):
Public Structure SWindAltitude
Public PaymentTableAs DataTable
Public Title As String
Public ID As Integer
End Structure
Both C# and VB.NET solutions will be helpful.
Try something like this, utilizing navigation properties (you'll probably have to massage it as I don't know the exact makeup of your data structures):
var customerQuery = context.CustomerTable.Select( ct =>
new {
ct.ID,
ct.CustomerTitle,
// use nav property to get customer payments
CustomerPayments = ct.CustomerPayments.Select( cp =>
new {
Range = cp.Range,
Values = cp.Values } ) } );
return customerQuery.ToArray()
.Select( cq =>
{
var retVal = new SCustomerInfo( CreateCustomerTable(), cq.ID, cq.CustomerTitle );
foreach( var customerPayment in cq.CustomerPayments )
{
var dtRow = cq.PaymentTable.NewRow();
dtRow.ItemArray = new object[] { customerPayment.Range, customerPayment.Values };
retVal.PaymentTable.Rows.Add( dtRow );
}
return retVal;
} );
if i understand right in c# with linq it will be something like this
var customerInfos = customerTitlesAndIDs.Select((c)=>{
var ci = new SCustomerInfo(CreateCustomerTable(), c.ID, customer.CustomerTitle);
ci.PaymentTable = ci.PaymentTable.AsEnumerable().Union(
cutomerIdPayment.Where(j=>j.ID == c.ID)
.Select(j=>{
var dtRow = ci.PaymentTable.NewRow();
dtRow.ItemArray = new object[] {
customerPayment.Range,
customerPayment.Values
};
return dtRow;
})).CopyToDataTable();
return ci;
}).ToList();
I think you can use the Linq provided function Sequence.concat() as described here: http://msdn.microsoft.com/en-us/library/vstudio/bb386979(v=vs.100).aspx