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();
Related
this is my query in sql server and everything works fine
select * from DetalleNotas
order by len(ColProduct), ColProduct
PROCT1
PROCT2
PROCT3
PROCT4
PROCT5
PROCT6
PROCT7
PROCT8
PROCT9
PROCT10
but i want my query in linq c#
I tried this and it does not work
var product = (from d in db.Product
orderby len(d.ColProduct), d.ColProduct
select new
{
product= d.product
});
the name "len" does not exist in the real context
only this query works
var product = (from d in db.DetalleNotas
orderby d.ColProduct
select new
{
product= d.product
});
This is the result of my functional query
PROCT1
PROCT10
PROCT2
PROCT3
PROCT4
PROCT5
PROCT6
PROCT7
PROCT8
PROCT9
Remember that in C# Linq code, everything is still C#. As you're working with strings you need to order by string.Length. For example:
var results = from d in db.DetalleNotas
orderby d.ColProduct.Length
select d;
You could order it by the number on the end of your strings:
var result = db.DetalleNotas.OrderBy(d => Convert.ToInt32(d.ColProduct.Substring(5)))
.ToArray();
When querying my entity framework DB, I am trying to match a condition based on the values from 2 rows.
My current query looks like this:
var query = context.table.where(x => x.row > 2);
This all works fine.
What I now want to achieve is to query the table based on the value in current and next row eg:
var query = context.table.where(x => x.row > 2 && x.row[next row up in DB] < 2);
Can this be done.
I know I can achieve this in code, but can it be done in a single query using LINQ and entity?
Here is an example of how I would do this with SQL:
SELECT *
FROM t_Table p
INNER JOIN t_Table f
ON (p.id + 1) = f.id
WHERE p.column = whatever
AND f.column = whatever2
Translating your sample SQL into LINQ to SQL:
var ans = from p in t_table
from f in t_table
where (p.id+1) == f.id && p.column == whatever && f.column == whatever2
select new { p, f };
This does not appear to generate an inner join in SQL but rather a cross-join, but I assume the SQL engine will handle it appropriately. Note that LINQ can only do equi-joins.
I didn't realize you can do (some) expressions in LINQ joins as long as equal is the primary operator, and this generates a sub-select and an inner join, which seems quite a bit faster:
var ans = from p in t_table
where p.column == whatever
let pidplus1 = p.id+1
join f in t_table on pidplus1 equals f.id
where f.column == whatever2
select new { p, f };
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
I have a following LINQ-to-entities query
IQueryable<History<T>> GetFirstOperationsForEveryId<T>
(IQueryable<History<T>> ItemHistory)
{
var q = (from h in ItemHistory
where h.OperationId ==
(from h1 in ItemHistory
where h1.GenericId == h.GenericId
select h1.OperationId).Min()
select h);
return q;
}
ItemHistory is a generic query. It can be obtained in the following way
var history1 = MyEntitiySet1.Select(obj =>
new History<long>{ obj.OperationId, GenericId = obj.LongId });
var history2 = AnotherEntitiySet.Select(obj =>
new History<string>{ obj.OperationId, GenericId = obj.StringId });
In the end of all I want a generic query being able to work with any entity collection convertible to History<T>.
The problem is the code does not compile because of GenericId comparison in the inner query (Operator '==' cannot be applied to operands of type 'T' and 'T').
If I change == to h1.GenericId.Equals(h.GenericId) I get the following NotSupportedException:
Unable to cast the type 'System.Int64' to type 'System.Object'. LINQ to Entities only supports casting Entity Data Model primitive types.
I've tried to do grouping instead of subquery and join the results.
IQueryable<History<T>> GetFirstOperationsForEveryId<T>
(IQueryable<History<T>> ItemHistory)
{
var grouped = (from h1 in ItemHistory
group h1 by h1.GenericId into tt
select new
{
GenericId = tt.Key,
OperationId = tt.Min(ttt => ttt.OperationId)
});
var q = (from h in ItemHistory
join g in grouped
on new { h.OperationId, h.GenericId }
equals new { g.OperationId, g.GenericId }
select h);
return q;
}
It compiles because GenericId's are compared with equals keyword and it works but the query with real data is too slow (it has been running for 11 hours on dedicated postgresql server).
There is an option to build a whole expression for the outer where statement. But the code would be too long and unclear.
Are there any simple workarounds for equality comparison with generics in LINQ-to-entities?
Try this, I think it should accomplish what you want without the extra query/join
IQueryable<History<T>> GetFirstOperationsForEveryId<T>
(IQueryable<History<T>> ItemHistory)
{
var q = from h in ItemHistory
group h by h.GenericId into tt
let first = (from t in tt
orderby t.GenericId
select t).FirstOrDefault()
select first;
return q;
}
IQueryable<History<T>> GetFirstOperationsForEveryId<T>
(IQueryable<History<T>> ItemHistory)
{
var grouped = (from h1 in ItemHistory
group t by h1.GenericId into tt
select new
{
GenericId = tt.Key,
OperationId = tt.Min(ttt => ttt.OperationId)
});
var q = (from h in ItemHistory
join g in grouped
on new { h.OperationId, h.GenericId }
equals new { g.OperationId, g.GenericId }
select h);
return q;
}
You could also set a generic constraint on T for an IItemHistory inteface that implements the GenericId and OperationId property.
My question already contains a solution. The second method with group + join works well if the table is properly indexed. It takes 3.28 seconds to retrieve 370k rows from the database table. In fact in non-generic variant the first query is slower on postgresql than the second one. 26.68 seconds vs 4.75.
Basically I'm trying to do this in LINQ to SQL;
SELECT DISTINCT a,b,c FROM table WHERE z=35
I have tried this, (c# code)
(from record in db.table
select new table {
a = record.a,
b = record.b,
c = record.c
}).Where(record => record.z.Equals(35)).Distinct();
But when I remove column z from the table object in that fashion I get the following exception;
Binding error: Member 'table.z' not found in projection.
I can't return field z because it will render my distinct useless. Any help is appreciated, thanks.
Edit:
This is a more comprehensive example that includes the use of PredicateBuilder,
var clause = PredicateBuilder.False<User>();
clause = clause.Or(user => user.z.Equals(35));
foreach (int i in IntegerList) {
int tmp = i;
clause = clause.Or(user => user.a.Equals(tmp));
}
var results = (from u in db.Users
select new User {
a = user.a,
b = user.b,
c = user.c
}).Where(clause).Distinct();
Edit2:
Many thanks to everyone for the comments and answers, this is the solution I ended up with,
var clause = PredicateBuilder.False<User>();
clause = clause.Or(user => user.z.Equals(35));
foreach (int i in IntegerList) {
int tmp = i;
clause = clause.Or(user => user.a.Equals(tmp));
}
var results = (from u in db.Users
select u)
.Where(clause)
.Select(u => new User {
a = user.a,
b = user.b,
c = user.c
}).Distinct();
The ordering of the Where followed by the Select is vital.
problem is there because you where clause is outside linq query and you are applying the where clause on the new anonymous datatype thats y it causing error
Suggest you to change you query like
(from record in db.table
where record.z == 35
select new table {
a = record.a,
b = record.b,
c = record.c
}).Distinct();
Can't you just put the WHERE clause in the LINQ?
(from record in db.table
where record.z == 35
select new table {
a = record.a,
b = record.b,
c = record.c
}).Distinct();
Alternatively, if you absolutely had to have it the way you wrote it, use .Select
.Select(r => new { a = r.a, b=r.b, c=r.c }).Distinct();
As shown here LINQ Select Distinct with Anonymous Types, this method will work since it compares all public properties of anonymous types.
Hopefully this helps, unfortunately I have not much experience with LINQ so my answer is limited in expertise.