Massive Query with inner join not returning any data - massive

I'm using the Massive Query method to write a simple join query against an Oracle database. This is my code with the query simplified even further by taking out some columns:
dynamic logTable = new DynamicModel("mydatabase", "table1");
var sb = new StringBuilder();
sb.Append("select CONTACT_ID from table1 inner join table2 on table1.ID = table2.ID ");
sb.Append("where table1.ID=:0");
dynamic dbResult = logTable.Query(sb.ToString(), id);
The following code gives me an error: 'object' does not contain a definition for 'CONTACT_ID'
string id = dbResult.CONTACT_ID.ToString();
If I take the exact query and run it through sqldeveloper, I get back the expected results. If I try to Query through Massive without a join, I get back an object I can work with.
Any ideas?

My mistake! I was expecting my query to return only one record, but forgot that Query returns IEnumerable. Solution is to take First() or loop over the results.

Related

Unable to create a constant value of type 'X.Models.Game'. Only primitive types or enumeration types are supported in this context

I've got a complex query written in SQL which works.
SELECT Instruments.Id as [Id], Instruments.ShareCode as [Share Code], Instruments.Name AS [Short Name], Instruments.Description as [Share Name],
InstrumentGames.Instrument_Id,
InstrumentGames.Game_Id, Games.Name AS [Game Name],
Entries.Name AS [Entry Name], AspNetUsers.UserName, AspNetUsers.Id as [User_Id],
Sectors.Name AS Sector_Id, Sectors.ShortName AS Sector
FROM AspNetUsers INNER JOIN
Entries ON AspNetUsers.Id = Entries.User_Id INNER JOIN
Games ON Entries.Game_Id = Games.Id INNER JOIN
InstrumentGames ON Games.Id = InstrumentGames.Game_Id INNER JOIN
Instruments ON InstrumentGames.Instrument_Id = Instruments.Id INNER JOIN
Sectors ON Instruments.Sector_Id = Sectors.Id
WHERE Instruments.Listed = 'true' and InstrumentGames.Game_Id = 2 and Entries.User_Id = 'd28d6552-7d98-476c-82cb-063e7ef45cb6'
I'm using Entity code first models and trying to convert what I have in SQL to a linq query.
I've come up with:
public static Models.Instrument GetShare(string shareSearchCriteria,
Models.Game selectedGame,
string userId)
{
var _db = new JSEChallenge.Models.ApplicationDbContext();
var records = (from instru in _db.Instruments
from e in _db.Entries
where (instru.ShareCode.Contains(shareSearchCriteria) ||
instru.Name.Contains(shareSearchCriteria) ||
instru.Description.Contains(shareSearchCriteria))
where (instru.Listed == true &&
instru.Games.Contains(selectedGame) &&
e.User_Id == userId)
select instru).ToList();
return records.FirstOrDefault();
}
But I keep getting this error:
Unable to create a constant value of type 'X.Models.Game'. Only primitive types or enumeration types are supported in this context.
I think the issue is the m2m table InstrumentGames. In my SQL query I can join it easily but in my C# I cannot. The way I usually find m2m records is syntax like instru.Games.Contains(selectedGame)
Unfortunately I still cannot get this to work.
How do I implement this kind of query in Linq?
Not sure if it will work, but try instru.Games.Any(q => q.Id == selectedGame.Id) instead of instru.Games.Contains(selectedGame).
Hope this helps!

nature of SELECT query in MVC and LINQ TO SQL

i am bit confused by the nature and working of query , I tried to access database which contains each name more than once having same EMPid so when i accessed it in my DROP DOWN LIST then same repetition was in there too so i tried to remove repetition by putting DISTINCT in query but that didn't work but later i modified it another way and that worked but WHY THAT WORKED, I DON'T UNDERSTAND ?
QUERY THAT DIDN'T WORK
var names = (from n in DataContext.EmployeeAtds select n).Distinct();
QUERY THAT WORKED of which i don't know how ?
var names = (from n in DataContext.EmployeeAtds select new {n.EmplID, n.EmplName}).Distinct();
why 2nd worked exactly like i wanted (picking each name 1 time)
i'm using mvc 3 and linq to sql and i am newbie.
Both queries are different. I am explaining you both query in SQL that will help you in understanding both queries.
Your first query is:
var names = (from n in DataContext.EmployeeAtds select n).Distinct();
SQL:-
SELECT DISTINCT [t0].[EmplID], [t0].[EmplName], [t0].[Dept]
FROM [EmployeeAtd] AS [t0]
Your second query is:
(from n in EmployeeAtds select new {n.EmplID, n.EmplName}).Distinct()
SQL:-
SELECT DISTINCT [t0].[EmplID], [t0].[EmplName] FROM [EmployeeAtd] AS
[t0]
Now you can see SQL query for both queries. First query is showing that you are implementing Distinct on all columns of table but in second query you are implementing distinct only on required columns so it is giving you desired result.
As per Scott Allen's Explanation
var names = (from n in DataContext.EmployeeAtds select n).Distinct();
The docs for Distinct are clear – the method uses the default equality comparer to test for equality, and the default comparer sees 4 distinct object references. One way to get around this would be to use the overloaded version of Distinct that accepts a custom IEqualityComparer.
var names = (from n in DataContext.EmployeeAtds select new {n.EmplID, n.EmplName}).Distinct();
Turns out the C# compiler overrides Equals and GetHashCode for anonymous types. The implementation of the two overridden methods uses all the public properties on the type to compute an object's hash code and test for equality. If two objects of the same anonymous type have all the same values for their properties – the objects are equal. This is a safe strategy since anonymously typed objects are essentially immutable (all the properties are read-only).
Try this:
var names = DataContext.EmployeeAtds.Select(x => x.EmplName).Distinct().ToList();
Update:
var names = DataContext.EmployeeAtds
.GroupBy(x => x.EmplID)
.Select(g => new { EmplID = g.Key, EmplName = g.FirstOrDefault().EmplName })
.ToList();

Getting LINQ query result into a list?

I'm converting old code to use LINQ. The old code looked like this:
// Get Courses
sqlQuery = #"SELECT Comment.Comment, Status.StatusId, Comment.DiscussionBoardId, DiscussionBoard.CourseId, Comment.CommentID
FROM Status INNER JOIN Comment ON Status.StatusId = Comment.StatusId INNER JOIN
DiscussionBoard ON Comment.DiscussionBoardId = DiscussionBoard.DiscussionBoardId
WHERE (DiscussionBoard.CourseID = 'CourseID')";
var comments = new List<Comment>(dataContext.ExecuteQuery<Comment>(sqlQuery));
I've converted the above SQL to LINQ:
var db = new CMSDataContext();
var query = from c in db.Comments
join s in db.Status on c.StatusId equals s.StatusId
join d in db.DiscussionBoards on c.DiscussionBoardId equals d.DiscussionBoardId
where d.CourseId == "CourseID"
select new
{
d.ItemType,
c.Comment1,
s.Status1,
c.DiscussionBoardId,
d.CourseId,
c.CommentID
};
The problem I've having, though, is with trying to get the results of the query into the List. Can someone offer me some pointers?
Thanks!
Try adding the ToList() method at the end of the query.
Enclose the whole query in parentheses and add .ToList() at the end.
Or add another line:
var list = query.ToList();
How about the ToList method: query.ToList() ?
You'll need to do two things.
First, change your select to create a new instance of Comment instead of an anonymous type.
Second, either wrap the whole query in a call to ToList() or store the results in a temporary variable and call ToList() on that variable to get the List<Comment> as a result.
Either (A) wrap the entire call with Enumerable.ToList(<your query>), (B) surround the entire query with parentheses and call the ToList extension method at the end, or (C) call query.ToList() as a separate statement.

Linq. Anonymous type error when joining to multiple tables

Im trying to return an IQueryable based on my model.
But I need to join to the same lookup table twice. Then return the query variable to the gridview.
public IQueryable<Benchmark> GetBenchMarks([QueryString("hydrant")] string hydrant,
[QueryString("revdate")] string revdate, [QueryString("street")] string street,
[QueryString("quadrant")] string quadrant, [QueryString("desc")] string desc) {
IQueryable<Benchmark> query = from p in _db.Benchmarks
join s in _db.Streets on p.Street1Number equals s.Id
join s2 in _db.Streets on p.Street2Number equals s2.Id
select new {
Street1Name = s.StreetName,
p.OrderNumber,
p.HydrantNumber,
Street2Name = s2.StreetName,
p.RevisionDate,
p.Quadrant,
p.Description,
p.Street1Number
};
}
So there is a red squiggle line on the 2nd join to s2. And the following error.
Error 5 Cannot implicitly convert type
'System.Linq.IQueryable<AnonymousType#1>' to
'System.Linq.IQueryable<Benchmarks.Model.Benchmark>'. An explicit
conversion exists (are you missing a
cast?) C:\Projects\Benchmarks\Benchmarks\Benchmarks_Home.aspx.cs 63 25 Benchmarks
Since you end your query with select new {...}, you are creating an anonymous object for each result. Instead, use select p, and each result will be a Benchmark.
However, it looks like returning a Benchmark is not what you want. In this case, you would want to change query to be of type IQueryable or IQueryable<dynamic> (and probably change the return type of the GetBenchMarks function as well, unless it does return IQueryable<Benchmark>!).
A second (potentially better) alternative would be to create a class to represent this anonymous type, and use that.
The result of your query is IEnumerable of anonymous objects, thus it cannot be converted to Benchmark.
If you want to set some additional properties (Street1Name - that are evidently not mapped on DB) from joined relations you can do:
IQueryable<Benchmark> query = from p in _db.Benchmarks
join s in _db.Streets on p.Street1Number equals s.Id
join s2 in _db.Streets on p.Street2Number equals s2.Id
select new {
....
};
var ex = query.ToList();
var result = new List<Benchmark>();
foreach(bn in ex){
result.Add(new Benchmark{ OrderNumber = bn.OrderNumber .... });
}
// return result.AsQueryable();
// but now it losts the point to return it as queryable, because the query was already executed so I would simply reurn that list
return result;
Another option is to make new class representing the object from the query and return it from the method like:
... select new LoadedBenchmark { Street1Name = s.StreetName ....}

linq to entity join on string equals int

I saw this post Linq int to string, and tried it
var personalInfoQuery = from t in crnnsupContext.Tombstones
join i in crnnsupContext.InitialEducations on t.InitialEducation equals SqlFunctions.StringConvert((double)i.InitalEducationID)
where t.RegNumber == 25952
select new CPersonalInfo
{
Tombstone = t,
InitialEducation = i
};
in the database t.InitialEducation is char, i.InitalEducationID is int, but the retrieved result is null. I am pretty sure the value is not empty in the SQL server. So I think the problem is SqlFunctions.StringConvert((double)i.InitalEducationID)
when i remove the join statement, it got this person's information.
Does anyone know why. thanks
Finally find the reason!!
t.InitialEducation is nvarchar(1) in the database, i.InitalEducationID is int, after I modified to SqlFunctions.StringConvert((double)i.InitialEducationID, 1) it works!
"1" is the length of the returned string, the default length is 10, I guess there are some extra space.
Since you're using the SqlFunctions.StringConvert method, I'm assuming you're using EF as the underlying LINQ provider, no?
From the information given, it would appear that you're looking to do a 1 to many join on those properties. The code you've written could coalesce (not enough info on the context to be certain) as an INNER JOIN in SQL, so to force the LEFT JOIN behavior, you can add a .DefaultIfEmpty() call:
crnnsupContext.InitialEducations.DefaultIfEmpty()

Resources