I have the following Linq statement:
var total = (from a in mobileChunk.Data select a.callCost).Sum();
callCost is a string. I need to convert it to a decimal. How is this done?
i would do something like this....
public static class Extenders
{
public static decimal ToDecimal(this string str)
{
// you can throw an exception or return a default value here
if ( string.IsNullOrEmpty(str) )
return someDefaultValue;
decimal d ;
// you could throw an exception or return a default value on failure
if ( !decimal.TryParse(str, out d ) )
return someDefaultValue;
return d;
}
}
now, in your linq.....
var total = = (from a in mobileChunk.Data select a.callCost.ToDecimal()).Sum();
Perhaps you can try this:
var total = (from a in mobileChunk.Data select decimal.Parse(a.callCost)).Sum();
Related
I want to retrieve all determined columns from the model table as queryable
I write code blow it shows me
Severity Code Description Project File Line Suppression State
Error CS1503 Argument 1: cannot convert from 'System.Collections.Generic.List' to 'System.Collections.Generic.List'
any help to solve this error with the best practice:**
public IQueryable<DAL.model> GetAllmodels()
{
var models = (from d in db.models
where (d.Model_Deleted == false)
select (
new
{
d.Model_ID,
d.Model_Name,
d.Model_Image
})).AsQueryable();
return models;
}
Instead of selecting anonymous object with new { .. } Try as below with new DAL.model() { ... }.
public IQueryable<DAL.model> GetAllmodels()
{
var models = (from d in db.models
where (d.Model_Deleted == false)
select (
new DAL.model()
{
Model_ID = d.Model_ID,
Model_Name = d.Model_Name,
Model_Image = d.Model_Image
})).AsQueryable();
return models;
}
My site has a bunch of widgets and i'm trying to filter them based on the url which is passed in. Say a Widget has the following structure:
public class Widget {
public int Id { get; set; }
public string Name { get; set; }
public string Urls { get; set; }
}
Where Urls is a comma separated list for the urls where the widget should be displayed, e.g.:
/, /Blog/, /Blog/123, /News/*
The asterisk after News indicates the Widget will be selected whenever the passed in url starts with /News/.
How could i modify the following method to filter the widgets based on my conditions above?
public IList<Widget> GetWidgets(string url) {
return _session
.Where(w => w.Urls.Contains(url))
.ToList();
}
Ideally i'd like to use a linq query and it must only hit the database once. I'd appreciate the help. Thanks
I managed to solve this by adding my own wild card match generator. See http://sentinel101.wordpress.com/2010/12/30/extend-nhibernate-linq-for-regex-matching/ for example of how to register the generator. Here's the generator incase anyone is interested:
public class WildCardMatchGenerator : BaseHqlGeneratorForMethod {
public WildCardMatchGenerator() {
var methodDefinition = ReflectionHelper.GetMethodDefinition(() => WildCardMatchExtensions.WildCardMatch(null, null, ','));
SupportedMethods = new[] { methodDefinition };
}
public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) {
return treeBuilder.Equality(treeBuilder.MethodCall("[dbo].[WildCardMatch]", new[] {
visitor.Visit(arguments[0]).AsExpression(),
visitor.Visit(arguments[1]).AsExpression(),
visitor.Visit(arguments[2]).AsExpression()
}), treeBuilder.Constant(1));
}
}
And here is the WildCardMatch UDF:
CREATE FUNCTION [dbo].[WildCardMatch] (
#Pattern NVARCHAR(MAX),
#Input NVARCHAR(MAX),
#Separator NVARCHAR(5)
)
RETURNS BIT
AS
BEGIN
SET #Pattern = REPLACE(#Pattern, '*', '%')
DECLARE #RtnValue BIT
SELECT #RtnValue = CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END FROM [dbo].[Split](#Pattern, #Separator) WHERE #Input LIKE [Data]
RETURN #RtnValue
END
And the Split function it calls (from http://blogs.microsoft.co.il/blogs/itai/archive/2009/02/01/t-sql-split-function.aspx):
CREATE FUNCTION [dbo].[Split]
(
#RowData NVARCHAR(MAX),
#Separator NVARCHAR(MAX)
)
RETURNS #RtnValue TABLE
(
[Id] INT IDENTITY(1,1),
[Data] NVARCHAR(MAX)
)
AS
BEGIN
DECLARE #Iterator INT
SET #Iterator = 1
DECLARE #FoundIndex INT
SET #FoundIndex = CHARINDEX(#Separator, #RowData)
WHILE (#FoundIndex > 0)
BEGIN
INSERT INTO #RtnValue ([Data])
SELECT Data = LTRIM(RTRIM(SUBSTRING(#RowData, 1, #FoundIndex - 1)))
SET #RowData = SUBSTRING(#RowData, #FoundIndex + DATALENGTH(#Separator) / 2, LEN(#RowData))
SET #Iterator = #Iterator + 1
SET #FoundIndex = CHARINDEX(#Separator, #RowData)
END
INSERT INTO #RtnValue ([Data])
SELECT Data = LTRIM(RTRIM(#RowData))
RETURN
END
Lastly you'll need the C# implementation of the above UDF:
public static class WildCardMatchExtensions {
public static bool WildCardMatch(this string pattern, string input, char separator = ',') {
foreach (var str in pattern.Split(new char[] { separator }, StringSplitOptions.RemoveEmptyEntries)) {
if (Regex.IsMatch(input, Regex.Escape(str.Trim()).Replace("\\*", ".*")))
return true;
}
return false;
}
}
Hope this helps.
I don't think SQL server allows you to use IN for comma delimited field values. You need LIKE (SQL example below):
Urls LIKE '%_your_url_%'
Linq, Expressions, NHibernate and Like comparison may help you with translation LIKE to Linq to NHibernate
I have a array of string say:
String[] Fields=new String[]{RowField,RowField1}
In which I can use the below query to get the values by specifying the values is query i.e RowField and RowField1:
var Result = (
from x in _dataTable.AsEnumerable()
select new
{
Name = x.Field<object>(RowField),
Name1 = x.Field<object>(RowField1)
})
.Distinct();
But if suppose I have many values in the Array like:
String[] Fields= new String[]
{
RowField,
RowField1,
RowField2,
.......
RowField1000
};
How can I use the query here without specifying each of the rowfield in the query?
How can i iterate through the array items inside the LINQ?
According to some suggestions in LINQ query and Array of string I am trying to get the result using the code below.
var result = (from row in _dataTable.AsEnumerable()
let projection = from fieldName in fields
select new {Name = fieldName, Value = row[fieldName]}
select projection.ToDictionary(p=>p.Name,p=>p.Value))
.Distinct();
But the problem is it does not return the distinct values.Any ideas?
Start with distinct DataRows by using this overload of Distinct():
_dataTable.AsEnumerable().Distinct(new DataRowEqualityComparer())
Where DataRowEqualityComparer is:
public class DataRowEqualityComparer : IEqualityComparer<DataRow>
{
public bool Equals(DataRow x, DataRow y)
{
return x.ItemArray.SequenceEqual(y.ItemArray);
}
public int GetHashCode(DataRow obj)
{
return string.Join("", obj.ItemArray).GetHashCode();
}
}
I want to search records which two column combination equals to the parameter, why it does not work?
public RDCheck SearchByUserPlusId(string uid)
{
RDCheckDataContext dc = new RDCheckDataContext(_connString);
var query = (from r in dc.RDChecks
where (r.login + r.id).Equals(uid)
select r).FirstOrDefault();
return query;
}
for example, one record in table is
id:4/login:test
So I pass parameter uid=test4 but it returns null, why?
Use ToString() before the concatenation
public RDCheck SearchByUserPlusId(string uid)
{
RDCheckDataContext dc = new RDCheckDataContext(_connString);
var query = (from r in dc.RDChecks
where (r.login.ToString() + r.id.ToString()).Equals(uid)
select r).FirstOrDefault();
return query;
}
The scenario is like this:
name | val
'aa' | 10
'bb' | 20
'cc' | 30
*********
sum | 60
For now I just select all the records in simple LINQ query and invoke the enumerator (ToList())
Then I loop over the list and summarize the val column.
Is there a better way? LINQ selects all to a new typed object so I dont know how to add the additional data.
thanks.
Anonymous type cant allow value to be added or edited once its created. so instead of returning anonymous type, you can use your custom output class. Something like this
public class ResClass
{
public string name;
public int value;
}
public class OutClass
{
public int sum;
public List<ResClass> lstData;
}
int sum=0;
var outtt = objTT.Where(x => x.id == 1).Select(x =>
{
sum += x.value;
return new ResClass { name = x.name, value= x.value };
}).ToList();
OutClass outCls = new OutClass { sum = sum, lstData = outtt };