I have asp.net mvc 4 application with EF 4, .net 4
This code
public List<ListItem> GetViolatedArticlesByLaw(int lawId, string culture)
{
culture = culture.ToLower();
var ans =
(from art in context.TITLENORMALAWs.Where(l => l.PARENTID == lawId)
select new ListItem
{
ID = art.ID,
ParentID = lawId,
Value = (art.NUM_STATSTR ?? ""),
});
Debug.WriteLine( ((System.Data.Objects.ObjectQuery)ans).ToTraceString() );
return ans.ToList();
}
throws ora-12704: character set mismatch.
It runs perfectly fine if I select from List, like this: from art in context.TITLENORMALAWs.Where(l => l.PARENTID == lawId).ToList()
This is the SQL generated:
SELECT
"Extent1"."ID" AS "ID",
:p__linq__1 AS "C1",
CASE WHEN ("Extent1"."NUM_STATSTR" IS NULL) THEN '' ELSE "Extent1"."NUM_STATSTR" END AS "C2"
FROM "AISSMK"."TITLENORMALAW" "Extent1"
WHERE ("Extent1"."PARENTID" = :p__linq__0)
It produces the same error in sqldeveloper and if I change this piece THEN '' ELSE to this THEN n'' ELSE it runs ok.
NUM_STATSTR in table definition is NVARCHAR2(30)
How can I make linq generate proper sql? Or do I have to call ToList() before selecting and there is no other way?
#Orif I think you should try to build the query manually instead of using the LINQ-to-SQL generators.
Try using the ExecuteQuerymethod on the DataContext class and try to add a cast to NVARCHAR
For more help read here, https://social.msdn.microsoft.com/Forums/en-US/20d456f0-9174-4745-bbc5-571f68879e27/net-strings-sql-paramater-type-always-nvarchar?forum=linqtosql
In my case, the issue was that empty strings are treated as null by Oracle, so your code Value = (art.NUM_STATSTR ?? "") actually ends up looking like Value = (art.NUM_STATSTR ?? null). Our workaround looks like this:
var ans =
(from art in context.TITLENORMALAWs
where art.PARENTID == lawId
select new
{
ID = art.ID,
ParentID = lawId,
Value = (art.NUM_STATSTR ?? ""),
})
.ToList()
.Select(a => new ListItem{
ID = a.ID,
ParentID = a.ParentID,
Value = a.Value ?? "",
});
Related
I am using Dapper with ExpressionToSQL nuget package. I have a query as below:
Set = new Table{Schema = "Sch",Name = "tbl1"};
Columns = x => new { x.Id};
Conditions = x => x.Name== request.Name && x.Date == request.Date;
Where<TQueryIn, object> query = Sql.Select(Columns, Set).Where(Conditions);
...
connection.QueryAsync(query);
Where the value for request.Name is "T1" and request.Date is "20121020".
When I run the above-mentioned query, I get the following query:
SELECT a.[Id] FROM [Sch].[tbl1] AS a WHERE a.[Name] = #Name AND a.[Date] = #Date
As you see the request.Name and request.Date's values are replaced with #Name and #Date!
What I need to see is:
SELECT a.[Id] FROM [Sch].[tbl1] AS a WHERE a.[Name] = 'T1' AND a.[Date] = '20121020'
Definitely this is not a problem with Dapper and it is a problem with ExpressionToSQL package.
Is there any way to overcome this issue, and convert Expression<Func<T,bool>> to a string value with above mentioned output?
I'm not familiar with Dapper, but after looking at the tests in ExpressionToSQL it seems that you can provide the parameters on the second argument of QueryAsync, therefore, I think this should work:
Set = new Table{Schema = "Sch",Name = "tbl1"};
Columns = x => new { x.Id};
Conditions = x => x.Name== request.Name && x.Date == request.Date;
Where<TQueryIn, object> query = Sql.Select(Columns, Set).Where(Conditions);
...
connection.QueryAsync(query, request);
Also found this, may be useful:
https://dapper-tutorial.net/parameter-anonymous
i need to select data to populate a DataGrid in MVC Asp.net with entity framework. When i select all values i need to have values from three tables connected: e, category and product. The connection is always 1 to 0 or 1. I have selected all walue with this code but when there isn't a category.name associated i naturally have an exception. What is the best way to do this?Do i need use if statment in New constructor?Or other?
var products = from e in dbResult
select new
{
e.Id,
e.Title,
e.Price,
e.Quantity,
e.category.nome,
e.Product.Sottotitolo,
e.Procuct.Provenienza
};
Thanks to all
Prior to C# 6 one way would be:
var products = from e in dbResult
select new
{
e.Id,
e.Title,
e.Price,
e.Quantity,
Noma = e.category == null ? "" : e.category.nome,
Sottotitolo = e.Product == null ? "" : e.Product.Sottotitolo,
Provenienza = e.Procuct == null ? "" : e.Procuct.Provenienza
};
With C# 6 you can use the ?. null-conditional member access operator:
var products = from e in dbResult
select new
{
e.Id,
e.Title,
e.Price,
e.Quantity,
Noma = e.category?.nome,
Sottotitolo = e.Product?.Sottotitolo,
Provenienza = e.Procuct?.Provenienza
};
Note that the field values in the latter method will be null instead of empty strings.
I'd migrated my entity 6.0 project from SQL Server to PostGreSQL. With SQL Server, these kind of convertion on my queries used to work properlly
Module.cs
return (
from m in objDB.Modules
orderby m.ID
select new
{
ID = m.ID,
Name = m.Name,
Status = DB_Function.Convert.ToInt32( m.Status )
}
);
PS: Status is a boolean type
DB_Function.cs
[System.Data.Entity.DbFunctionAttribute( "Business.Database", "ToInt32" )]
public static Int32 ToInt32( Boolean Val )
{
return System.Convert.ToInt32( Val );
}
However, when I migrated to PostgreSQL (and therefore changed my EDMX), these kind of conversion don't execute anymore:
The specified method 'Int32 ToInt32(Boolean)' on the type
'DB_Function+Convert' cannot be translated into a LINQ to Entities
store expression.
This error is related with PostGre (like int4 and not int32) or I'm missing something?
Thanks in advance.
For understanding what type of functions we can use inside LINQ to Enitities : go through below linK :
linq to entities doesn't recognize a method
Now In this particular case we were having a function in side LINQ to Entites, which was unable to be translated to SQL Query and hence the Exception was thrown. SO by removing the function it work perfectly.
return (
from m in objDB.Modules
orderby m.ID
select new
{
ID = m.ID,
Name = m.Name,
Status = m.Status == true ? 1 : 0
}
);
Just remove your function and it will work if your values is not nullable
return (
from m in objDB.Modules
orderby m.ID
select new
{
ID = m.ID,
Name = m.Name,
Status = Convert.ToInt32( m.Status )
}
);
If it is nullable you will need to check if it has value:
return (
from m in objDB.Modules
orderby m.ID
select new
{
ID = m.ID,
Name = m.Name,
Status =m.Status.HasValue? Convert.ToInt32( m.Status ):0
}
);
I am just trying to concatenate a string on to a column returned from the database like so:
var aaData =
(from pr in ctx.PaymentRates
where pr.ServiceRateCodeId == new Guid("BBCE42CB-56E3-4848-B396-4656CCE3CE96")
select new
{
Id = pr.Id,
Rate = pr.YearOneRate + "helloWorld"
})
.ToList();
It gives me this error:
Unable to cast the type 'System.Nullable`1' to type 'System.Object'.
LINQ to Entities only supports casting EDM primitive or enumeration
types.
So, then I tried this:
var aaData =
(from pr in ctx.PaymentRates
where pr.ServiceRateCodeId == new Guid("BBCE42CB-56E3-4848-B396-4656CCE3CE96")
select new
{
pr = pr
})
.AsEnumerable()
.Select(x => new
{
Id = x.pr.Id,
Rate = x.pr.YearOneRate + "helloWorld"
})
.ToList();
But, now it gives me this error:
Object reference not set to an instance of an object.
On this line:
.Select(x => new
How can I concatenate these strings in LINQ?
The quick solution
Regarding your second code chunk I need to point out to you that you're actually doing two left outer joins on the Countries table/set, one for homeC and one for hostC.
That means that you are willing to accept null values for those two variables.
In other words, since they can be null you are somehow allowing this right here to crash with NullReferenceException, should those variables turn out to be null:
.Select(x => new
{
Id = x.pr.Id,
HomeCountry = x.homeC.Name,
HostCountry = x.hostC.Name,
Rate = x.pr.YearOneRate + "helloWorld"
})
The error (NullReferenceException or as you saw it's message: "Object reference not set to an instance of an object.") is not here
.Select(x =>
but rather here
x.homeC.Name and x.hostC.Name
where you will most certainly dereference a null reference.
That's just Visual Studio's way of pointing out the best statement that fits around the error.
So, the quickest solution would be to do this:
.Select(x => new
{
Id = x.pr.Id,
HomeCountry = (x.homeC != null) ? x.homeC.Name : "HomeCountry not found",
HostCountry = (x.hostC.Name != null) ? x.hostC.Name : "HostCountry not found",
Rate = x.pr.YearOneRate + "helloWorld"
})
Notice the modification which ensures that you will still be able to extract some information from result set records for which homeC and hostC are null.
EDIT
Regarding the first query you posted:
var aaData =
(from pr in ctx.PaymentRates
where pr.ServiceRateCodeId == new Guid("BBCE42CB-56E3-4848-B396-4656CCE3CE96")
select new
{
Id = pr.Id,
Rate = pr.YearOneRate + "helloWorld"
})
.ToList();
my guess is that your 'YearOnRate' property is of type 'Nullable< of something >" (maybe decimal -- so for instance it is maybe a decimal? YearOnRate { get; set; }) and the corresponding column in the database is a nullable one.
If that is the case, then I think (in this first version of your endeavour) you could try to do this:
Rate = (pr.YearOnRate != null) ? pr.YearOneRate.Value + "helloWorld" : "[null]helloWorld"
and get away with it.
My guess is that either x.homeC, x.hostC, or x.pr are null. If you're fine using AsEnumerable to convert to Linq-to-Objects then you could just change your projection to
.Select(x => new
{
Id = (x.pr.HasValue ? x.pr.Id : 0),
HomeCountry = (x.homeC.HasValue ? x.homeC.Name : null),
HostCountry = (x.hostC.HasValue ? x.hostC.Name : null),
Rate = (x.pr.HasValue ? x.pr.YearOneRate : null) + "helloWorld"
})
My problem was, I wasn't using .AsEnumerable() properly. The code below works:
var aaData =
(from pr in ctx.PaymentRates
from homeC in ctx.Countries.Where(x => x.Id == pr.HomeCountryId).DefaultIfEmpty()
from hostC in ctx.Countries.Where(x => x.Id == pr.HostCountryId).DefaultIfEmpty()
from curr in ctx.Currencies.Where(x => x.Id == pr.YearOneCurrencyId).DefaultIfEmpty()
where pr.ServiceRateCodeId.Value.Equals(new Guid("BBCE42CB-56E3-4848-B396-4656CCE3CE96"))
select new { pr, homeC, hostC, curr })
.AsEnumerable()
.Select(x => new
{
Id = (string)(x.pr.Id.ToString() + "test"),
HomeCountry = (x.homeC != null ? x.homeC.Name : ""),
HostCountry = (x.hostC != null ? x.hostC.Name : ""),
Rate = (x.pr.YearOneRate ?? 0) + " (" + x.curr.Code + ")"
})
.ToList();
You have used DefaultIfEmpty on both homeC and hostC so you can get a null reference when you call homeC.Name or hostC.Name
Try using HomeCountry = homeC == null ? null : homeC.Name instead
If pr.YearOneRate is not a string and you want the concatenation done by the database engine you need to tell Linq-to-Entities to generate sql to convert it. If you are using Sql Server you can use this:
SqlFunctions.StringConvert(pr.YearOneRate) + "helloWorld"
If you don't need the concatenation done in the database then you can use AsEnumerable() before the Select so that you are running Linq-To-Objects
This is what I am trying to do.
data = (from t in db.Table
where ...
select new
{
Property = t.Table2.Any() ? new Nullable<DateTime>(t.Table2.OrderByDescending(x => x.DateField).FirstOrDefault().DateField) : null
});
if there is anything in table2 i want to get the most recent date if not then return null but it's not letting me use new Nullable<>(). Also AS DateTime? does not work. This used to work in linq2sql but using EF which I have switched to it throws errors.
data = (from t in db.Table
where ...
select new
{
Property = t.Table2.OrderByDescending(x => x.DateField).select(x=> x.DateField).FirstOrDefault()
});