Hello I'm trying to use IN condition in LINQ.
I have the following query:
select * from unitphotos Where MarketingFileTypeID = 2
AND UnitTypeID in (Select UnitTypeID from unitTypes Where PropertyID = 1)
I think I can't make it in only one LINQ query, so I did this:
var listUnitTypes = (from ut in db.unittypes
where ut.PropertyID == propertyID
select new { ut.UnitTypeID }).ToList();
var getPropertyPhotos = (from up in db.unitphotos
where listUnitTypes.Contains(up.UnitTypeID)
select up).ToList();
However, it gives me a syntax error inside Contains(up.UnitTypeID): "Argument 1: cannot convert from 'int' to 'anonymous type int UnitTypeID'
Does anyone know what I am doing wrong?
Thanks
var getPropertyPhotos = (from up in db.unitphotos
where unittypes.Any(ut => ut.PropertyID == propertyID && ut.UnitTypeId == up.UnitTypeID)
select up).ToList();
I think this should work. Haven't tried it since I don't have the db though so ymmv.
Also, yours should work if instead of select new { ut.UnitTypeID } you just put select ut.UnitTypeID
You have anonymous type here
var listUnitTypes = (from ut in db.unittypes where ut.PropertyID == propertyID select new { ut.UnitTypeID }).ToList();
And then try to use it in Linq To Entity:
var getPropertyPhotos = (from up in db.unitphotos
where listUnitTypes.Contains(up.UnitTypeID)
select up).ToList();
Seems like Linq to Entity won`t know what that type is.
So you can replace
select new { ut.UnitTypeID })
with
select { ut.UnitTypeID })
as #anakic sad before
And then create 1 query by Linq
var listUnitTypes = (from ut in db.unittypes where ut.PropertyID == propertyID select ut.UnitTypeID);
var getPropertyPhotos = (from up in db.unitphotos where listUnitTypes.Contains(up.UnitTypeID) select up).ToList();
By that you force Linq to Sql create complicated query that should be able to handle your problem.
I think that the way that you are approaching the problem forcing a sub-select is going to end up having you going back to the database more than you have to. I don't have an IDE available right now to bang out the correct LINQ syntax, but why not change your approach from thinking in terms of a SQL sub-select to that of a JOIN? Here is the SQL that I would start with and then translate that to LINQ:
SELECT p.*
FROM unitphotos p
INNER JOIN unitTypes u
ON u.UnitTypeID = p.UnitTypeID
AND u.PropertyID = 1
WHERE p.MarketingFileTypeID = 2
Related
How can I rewrite the following Linq query into normal T-SQL?
var list = (from t in context.ParentTable
where t.ChildRecords.Count == t.ChildRecord.Count( c => c.BooleanColumn )
select t).ToList();
Thanks in advance...
Something like this, but you'll need to determine the relationship between the ParentTable and ChildRecord tables to make it work, I'm just guessing at the cr.ParentTableId = pt.ParentTableId part.
select pt.*
from ParentTable pt
where not exists
(select 1
from ChildRecord cr
where cr.ParentTableId = pt.ParentTableId
and cr.BooleanColumn = 0)
On a side note the Linq could be changed to the following instead.
var list = (from t in context.ParentTable
where t.ChildRecords.All(c => c.BooleanColumn)
select t).ToList();
Could somebody assist me in converting a sql query into LINQ ? I well understand SQL queries, but I am a novice in Linq. Thank you so much for help me.
SELECT
subConsulta."NitIps",
subConsulta."NumFactura",
COUNT(*)
FROM
(SELECT
DISTINCT acf."NitIps",
acf."NumFactura",
acf."TipoSoporte"
FROM
"t_ArchivoCentralFacturacion" AS acf
inner join "t_TRCompartaTiposDocumentalesAC" AS ctd
on
acf."TipoSoporte"= ctd."Id"
GROUP BY
acf."NitIps",
acf."NumFactura",
acf."TipoSoporte")as subConsulta
GROUP BY
subConsulta."NitIps",
subConsulta."NumFactura"
ORDER BY
subConsulta."NitIps",
subConsulta."NumFactura"
If you map your tables to entities it looks like follow:
var first = from archivoCentralFacturacion in ArchivoCentralFacturacions
group archivoCentralFacturacion by new {
c.NitIps,
c.NumFactura,
c.TipoSoporte
} into subConsulta
select subConsulta;
var result = (from f in first
group f by new {
f.NitIps,
f.NumFactura
} into r
select new {
NitIps = r.NitIps,
NumFactura = r.NumFactura,
ResultCount = r.Count()
}).OrderBy(x => x.NitIps).ThenBy(x => x.NumFactura);
I am having following query in sql :
SELECT [definition],[pos]
FROM [WordNet].[dbo].[synsets]
where synsetid in(SELECT [synsetid] FROM [WordNet].[dbo].[senses]
where wordid = (select [wordid]FROM [WordNet].[dbo].[words]
where lemma = 'searchString'))
I had tried this for sql to linq :
long x = 0;
if (!String.IsNullOrEmpty(searchString))
{
var word = from w in db.words
where w.lemma == searchString
select w.wordId;
x = word.First();
var sence = from s in db.senses
where (s.senseId == x)
select s;
var synset = from syn in db.synsets
where sence.Contains(syn.synsetId)
select syn;
But I am getting following error at sence.Contains()
Error1:Instance argument: cannot convert from
'System.Linq.IQueryable<WordNetFinal.Models.sense>' to
'System.Linq.ParallelQuery<int>'
Below code:
var sence = from s in db.senses
where (s.senseId == x)
select s;
Returns object of type: WordNetFinal.Models.sense, but in where sence.Contains(syn.synsetId) you are trying to search in it syn.synsetId which is an integer.
So you should change above code to:
var sence = from s in db.senses
where (s.senseId == x)
select s.senseId;
x seems to be of Word type, which is not the type of Id (probably int or long).
You're comparing an entire sense row with a synsetId, which is not correct. You're also splitting the original query into two separate queries by using First() which triggers an evaluation of the expression so far. If you can live with not returning an SQL error if there are duplicates in words, you can write the query as something like this;
if (!String.IsNullOrEmpty(searchString))
{
var wordIds = from word in db.words
where word.lemma == searchString
select word.wordId;
var synsetIds = from sense in db.senses
where wordIds.Contains(sense.wordId)
select sense.synsetId;
var result = (from synset in db.synsets
where synsetIds.Contains(synset.synsetId)
select new {synset.definition, synset.pos}).ToList();
}
The ToList() triggering the evaluation once for the entire query.
You could also just do it using a simpler join;
var result = (from synset in db.synsets
join sense in db.senses on synset.synsetId equals sense.synsetId
join word in db.words on sense.wordId equals word.wordId
select new {synset.definition, synset.pos}).ToList();
I want to filter my LINQ query based on an included table but am having some trouble.
Here is the original statement, which works:
return
this.ObjectContext.People.
Include("Careers").
Include("Careers.Titles").
Include("Careers.Titles.Salaries");
Now I'm trying to filter on Careers using projected filtering but am having trouble. It compiles but it leaves out the Titles and Salaries tables, which causes runtime errors, and I can't seem to add those tables back in:
var query1 = (
from c in
this.ObjectContext.People.
Include("Careers").
Include("Careers.Titles").
Include("Careers.Titles.Salaries")
select new
{
c,
Careers = from Careers in c.Careers
where Careers.IsActive == true
select Careers
});
var query = query1.AsEnumerable().Select(m => m.c);
return query.AsQueryable();
How can I include the titles and salaries tables in the filtered query?
You can simplify your query considerably, which should resolve your issue. I'm assuming that you want all people with at least 1 active career:
var query =
from c in
this.ObjectContext.People.
Include("Careers").
Include("Careers.Titles").
Include("Careers.Titles.Salaries")
where c.Careers.Any(c => c.IsActive);
return query;
I would try something like,
var query = from p in ObjectContext.People
join c in ObjectContext.Careers on p equals c.Person
where c.IsActive
select p;
I have this original SQL that I need to rewrite in LINQ :
SELECT
luProfiles.luProfileID,
luProfiles.ProfileName,
NoOfRights = (SELECT Count(pkProfileRightsID) FROM tblProfileRights WHERE fkProfileID = luProfileID)
FROM luProfiles
WHERE luProfiles.ProfileName LIKE ...
I have done most of it in LINQ, but I am not sure how to add the NoOfRights part to my LINQ. This is what I have done so far :
return from p in _database.LuProfiles
where p.ProfileName.ToLower().StartsWith(strProfile.ToLower())
select p;
Can anybody tell me the right syntax to include the NoOfRights part in my LINQ?
from p in _database.LuProfiles
let NoOfRights = (from r in database.tblProfileRights
where r.fkProfileID == p.luProfileID
select r).Count()
where p.ProfileName.ToLower().StartsWith(strProfile.ToLower())
select new
{
p.luProfileID,
p.ProfileName,
NoOfRights
};
If you are using LINQ-to-SQL or EF, and you have an FK set up, you should have a navigational property ProfileRights. Tn that case, you can query this way:
from p in _database.LuProfiles
where p.ProfileName.ToLower().StartsWith(strProfile.ToLower())
select new
{
p.ProfileId,
p.ProfileName,
NoOfRights = p.ProfileRights.Count()
};
I think this would help you out:
from l in luProfiles
where l.ProfileName.Contains(something)
select new
{
l.luProfileID,
l.ProfileName,
noOfRights = tblProfileRights.Count(t => t.fkProfileID == l.luProfileID)
}
I would recommend you to change SQL first to something like this:
SELECT
luProfiles.luProfileID,
luProfiles.ProfileName,
NoOfRights = COUNT(pkProfileRightsID)
FROM luProfiles
LEFT JOIN tblProfileRights ON fkProfileID = luProfileID
WHERE luProfiles.ProfileName like ...
GROUP BY luProfiles.luProfileID, luProfiles.ProfileName
So this can easily be transformed to LINQ:
return from p in _database.LuProfiles
join o in p.Profiles on p.luProfileID equals o.fkProfileID
group p by new { p.luProfileID, p.ProfileName } into g
select new { g.Key.luProfileID, g.Key.ProfileName , g.Count() }
(not tested, so do it yourself)