The type arguments cannot be inferred from the query - linq

my linq query works, I tested in the linqpad, got result back. the error happened at the last step, when I try to use EntityVM ViewModel. I dont really understand what this error message means. can someone please explain that to me, and show me how to fix it. thank you.
Error Message: "the type arguments cannot be inferred from the query"
var entityVersions = EntityVersionRepository.Get().Where(x => x.Entity.ClientId == clientId);
var groups = from ev in entityVersions
group ev by ev.EntityId
into g
select g.OrderByDescending(x => x.TaxYear).FirstOrDefault();
var result = from g in groups
select (en => new EntityVM
{
Name = en.EntityName,
Id = en.EntityId
});

It looks like it could be because you aren't actually evaluating the groups query (by calling .ToList() or something similar). Try evaluating groups first:
var groups = (from ev in entityVersions
group ev by ev.EntityId
into g
select g.OrderByDescending(x => x.TaxYear).FirstOrDefault())
.ToList();
If this is the problem, then it's probably a prime example of why you shouldn't use var when you're returning concrete types from a query. If you'd of changed var groups to List<Group> groups, that code wouldn't of even compiled, so you'd have known straight away that you hadn't actually evaluated the property (it would of returned an IQueryable<Group> instead).

Related

retrieve all areas where id's don't exist in supplied list

I'm sure I must be missing something really simple here..
OK I have a list of AreaIds. I want to compare that list to the MapArea Table and return any IDs that exist in the table but NOT in the supplied list.
This is my list of supplied areas that I want to check:
var currentAreas = (from c in _entities.mapAreaLink
where c.listingId == id
select new
{
c.MapArea.areaId
}
).ToList();
This is the getting the exhaustive list of mapAreas..
var availableAreas = (from m in _entities.MapAreas
select new
{
m.areaId
}
).ToList();
This compares the two lists and gets items that exist in the maparea table but not in the maparealink (constrained by an id of the item I am looking at).
var unusedAreas = availableAreas.Except(currentAreas).ToList();
I seem to get the list back ok, but what I need to do is now return a list of maparea objects based on the results of the Except.tolist above.
I thought I could do this:
var mapareas = (from e in _entities.MapAreas
where unusedAreas.Contains(e.areaId)
select e).ToList();
I am getting an ambiguous invocation on the where & "Cannot resolve method Contains(int)" on the e.areaId.
Ive tried using:
var unusedAreas = availableAreas.Except(currentAreas).ToArray();
No Joy.. Can anyone help me out here - I am guessing I must be missing a fundamental basic here.
many thanks
You create anonymous types with just one int property. That's not necessary and it causes the later problem. If you create lists of int you'll be OK:
var currentAreas = (from c in _entities.mapAreaLink
where c.listingId == id
select c.MapArea.areaId).ToList();
var availableAreas = (from m in _entities.MapAreas
select m.areaId).ToList();

Linq error - "NotSupportedException: Unsupported overload used for query operator 'Select'"

I have the following Linq query:
var tmp =
from container in Container
join containerType in ContainerType on container.ContainerType equals containerType
where containerType.ContainerTypeID == 2
select new { ContainerID = container.ContainerID, TypeID = container.ContainerTypeID};
var results = tmp.Select((row, index) => new { row.ContainerID, row.TypeID, ContainerIndex = index })
As is, this works fine. If I add the following, so I can see the results in LinqPad, I get the error described in the title of this message:
results.Dump();
This error is not a LinqPad error, it's coming from Linq, and I don't understand what it means.
Thank you.
Okay, I hadn't realised Container was a LINQ to SQL data source to start with. Basically it's failing to convert the second projection to SQL.
So, you want to do just that bit in .NET instead - you can force it to use Enumerable.Select with AsEnumerable:
var results = tmp.AsEnumerable()
.Select((row, index) => new { row.ContainerID, row.TypeID,
ContainerIndex = index });

NHIbernate Linq group by count

I have the version 3.0.0.1001 nhibernate.
My objects are basically modeiling a lineup at an event. So I have a StageSet object which represents one slot in the schedule for a stage.
Each StageSet object has a Stage and an Act property.
It also has many Users - people who have favorited the set.
I'm trying to ascertain the most popular sets that have been favorited using the following linq:
var topStars = from s in Db.StageSets
group s by s.Act.Id into g
select new { SetKey = g.Key, Count = g.Count() };
However this just fails with a Could not execute query[SQL: SQL not available] error
Should I be able to do this?
w://
in case someone comes here. The following should work with NH 3.1
var topStars = from s in Db.StageSets
group s by s.Act.Id into g
select new { SetKey = g.First().Act.Id, Count = g.Count() }
You've specified the query correctly in linq. NHibernate is refusing to translate it.
I just copied your query with a slightly different domain and it worked. But that will count StageSets by Act, NOT favorites.

Reproduce a "DELETE NOT IN" SQL Statement via LINQ/Subsonic

I want to do something like DELETE FROM TABLE WHERE ID NOT IN (1,2,3) AND PAGEID = 9
I have a List of IDS but that could be changed if needs be. I can't work out how to get a boolean result for the LINQ parser.
Here is what Subsonic expects I think.
db.Delete(content => content.PageID == ID).Execute();
I can't work out how to do the NOT IN statement. I've tried the List.Contains method but something not quite right.
UPDATE: One alternative is to do:
var items = TABLE.Find(x => x.PageID == ID)'
foreach(var item in items)
{
item.Delete();
}
This hits the database a lot more though
When you say "something not quite right" what exactly do you mean?
I'd expect to write:
List<int> excluded = new List<int> { 1, 2, 3 };
db.Delete(content => !excluded.Contains(content.PageID)).Execute();
Note that you need to call Contains on the array of excluded values, not on your candidate. In other words, instead of saying "item not in collection" you're saying "collection doesn't contain item."
Try .Contains:
db.Delete(content => content.PageID.Contains(<Array containing ID's>).Execute();
(the above is just an example, might need some polishing for your specific situation)
I have found that this works but its not via LINQ
var table = new WebPageContentTable(_db.DataProvider);
var g = new SubSonic.Query.Delete<WebPageContent(_db.DataProvider)
.From(table)
.Where(table.ID)
.NotIn(usedID)
.Execute();
I have found that this does work and via LINQ - however it hits the database multiple times.
var f = WebPageContent.Find(x => !usedID.Any(e => e == x.ID));
if (f.Count > 0)
{
var repo = WebPageContent.GetRepo();
repo.Delete(f);
}
This I imagine would work in one hit to the database but I get an exception thrown in QueryVisitor::VisitUnary
WebPageContent.Delete(x => !usedID.Any(e => e == x.ID));

DataTable Query

I am new to LINQ. I am trying to find the rows that does not exists in the second data table.
report_list and benchmark both type are : DataTable. Both these datatables are being populated using OleDbCommand,OleDbDataAdapter. I am getting an error "Specified cast is not valid." in foreach ... loop. I would appreciate your help.
var result = from a in report_list.AsEnumerable()
where !(from b in benchmark.AsEnumerable()
select b.Field<int>("bench_id")
)
.Contains(a.Field<int>("BenchmarkID"))
select a;
foreach (var c in result)
{
Console.WriteLine(c.Field<string>("Name"));
}
I don't know if I understood your question. Are you trying to get the items that exists in the first table but not in the second?
var first = new string[] { "b", "c" };
var second = new string[] { "a", "c" };
//find the itens that exist in "first" but not in "second"
var q = from f in first
where !second.Contains(f)
select f;
foreach (var s in q) {
Console.WriteLine(s);
}
//Prints:
//b
I suggest you to make the inner query first, once it does not depend on the outer record.
From a in report_list
Group Join b in benchmark On a.bench_id Equals b.bench_id Into g = Group
Where g.Count = 0
Select a
Note that this is VB syntax.
My suspicion is that one of the fields you are comparing is not an integer in the database. I believe that the invalid cast exception is being thrown by one of the Field<int>() calls since that is one of the three different exceptions that this method can throw. See docs here.
Perhaps use the .Except() extension to get the set difference of the two sets?
(from b in benchmark.AsEnumerable()
select new { id = b.Field<int>("bench_id")}).Except(
from a in report_list.AsEnumerable()
select new {id = a.Field<int>("BenchmarkID")})
Not actually sure of the precise syntax, but that should work by taking the ids in benchmark, and then removing all equivalent ids in report_list, leaving only the ids that don't match. (I hope this is the order you were after...)
Note: This is also assuming that the above issue mentioned by tvanfosson isn't also a problem

Resources