Select data from multiple table with Entity Framework - asp.net

I am able to select data from two tables, But I am getting partial result only while retrieving data from three tables.
var items = from orders in nobleappDbContext.JobOrders.Where(m => m.OrderStat == 0)
join users in nobleappDbContext.users on orders.Uid equals users.Uid
join customers in nobleappDbContext.customers on users.Uid equals customers.Uid into customdata
from m in customdata.DefaultIfEmpty()
select new
{
Eid = orders.Eid,
Uid = orders.Uid,
OrderStat = orders.OrderStat,
Name = m.Name,
Contact = (m.Contact == null) ? 0 : m.Contact
};
return Ok(items);
With this code, I am getting only result (common result) from users table and I am looking for something like UNION or OUTER JOIN.
Any help will be highly appreciated

finally I got exactly what I was looking for, here by posting the answer as I might help someone looking for same. LEFT JOIN with Entity Framework is the key
var query = from a in authurs
join b in books on a.Id equals b.AuthorId into auth_books
from left in auth_books.DefaultIfEmpty()
join bs in booksSeries on left.BookSeriesId equals bs.Id into books_bookseries
from left2 in books_bookseries.DefaultIfEmpty()
select new
{
Author = a.Name,
Book = left.Name,
BookSeries = left2.Description
};
var resList2 = query.ToList();
refer this link for further clarification.

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!

Sqlite select default rows if not exists

Sorry to pester with a simple problem but I'm stumped with a simple select on an HTML5 WebSQL Data Base.
Table tPhones has id, hid, location and several other columns. I would like to return a list of rows with where hid = [input value] or, if no rows with that hid exist, return rows where hid = 1.
I have tried LIMIT 1 ACS etc but that too fails.
Function showPhones(){
var phonegroup = $(this).attr("id");
var hid = localStorage.hid;
db.transaction (function(transaction)
{
var sql = "SELECT * FROM tPhones WHERE dept ='"+phonegroup+"' AND ((hid ='"+hid+"') OR IFNULL (hid ='1')) ORDER BY location ASC";
transaction.executeSql (sql, undefined,function(transaction,result)
{…………..rest of function working fine
Any help would be much appreciated.
A normal expression in the WHERE clause can access only columns of the current record.
To check for the existence of any other record, you have to use a subquery:
SELECT *
FROM tPhones
WHERE dept = ?
AND (hid = ? OR (hid = 1 AND
NOT EXISTS (SELECT 1
FROM tPhones
WHERE dept = ?
AND hid = ?)))
ORDER BY location

Search using linq and dropdowns

I got about 5 look-a-like linq querys just like this SortPerson() metod. I'm trying to develop a search using dropdowns where a user can select values from the dropdown and returns the values that are true from one or more dropdowns the user has selected to use.
Is there a simpler way to develop this? help would be much appreciated
public void SortPerson()
{
var personId = ddlPerson.SelectedValue;
var data = new MyModelContext();
var documents = from d in data.tblDocuments
join sp in data.tblPersons on d.DocPerson equals sp.PersonId
select d;
if (!String.IsNullOrEmpty(personId))
{
documents = documents.Where(c => c.DocPerson.Equals(personId));
}
rptResult.DataSource = documents.ToList();
rptResult.DataBind();
}
I don't see the point in joining without Where if you still select only one table.
If you want all document in case when Person is not selected, then you can't create much simpler method. You can write it shorter like:
var documents =
from d in data.tblDocuments
join ...
where String.IsNullOrEmpty(personId) || d.DocPerson equals personId
select d;
so you don't need separate if statement.
If you want to use several values from 5 dropdowns and use them as conditions in single query, just add more conditions:
var personId = ddlPerson.SelectedValue;
var someValue = ddlSomeDDL.SelectedValue;
//3 more values from DDL
var documents = from d in data.tblDocuments
join sp in data.tblPersons on d.DocPerson equals sp.PersonId
where (String.IsNullOrEmpty(personId) || sp.PersonId equals personId)
&& (String.IsNullOrEmpty(someValue) || d.SomeColumn equals someValue)
//3 more conditions
select d;

Is there a way to select a columns from a joined table without explicitly listing all columns?

I'm trying to use JoinSqlBuilder to select a data from one of the joined tables, and can't find a way to do that unless I list all columns from that table. Hopefully I'm missing something and it actually can be done.
This is approximately what I have:
var sql = new JoinSqlBuilder<Product, Product>()
.Join<Product, Customer>(src => src.Id, dst => dst.Id)
.Where<Customer>(x => x.Id == Id);
and I want to select everything from a product table. The query above throws an exception complaining about column name collisions, so its clearly does a select from both tables.
Edit: In the end I want to have this sql (never mind the design, its not a real thing):
select
p.* //<-- This is the piece that I'm struggling with
from product p inner join customer c on p.id on c.productId
where blah;
Looks like OrmLite want me to explicitly list all columns I want to return, which I want to avoid.
Note: I'm using 3.9.71 of servicestack. I've not looked at the 4.0 implementation yet.
I think you have a FK relationship problem with your join. Assuming that a product has a customer FK named (CustID), it'd look like this. Additionally, you'd need a POCO to represent the result set, if you are returning a "combination" of the results. I don't think you'll want to return both "ID" columns, and instead return a FK column.
return _factory.Run<ProductCustomer>(conn=>
{
var jn = new JoinSqlBuilder<Product, Customer>();
jn = jn.Join<Product, Customer>(srcProd => srcProd.CustId,
dstCust => dstCust.Id, // set up join Customer.id -> Product.CustId
p => new { p.Id, p.OtherField}, // product table fields returned
c => new { c.Name, c.AddressId}, // customer fields returned
null, //where clause on the product table
cust=>cust.Id = customerId // where clause on the customer table
);
var sql = jn.ToSQL();
return conn.FirstOrDefault<ProductCustomer>(sql);
}
Hope this helps.
Edit: After your Edit, try this:
// set up join Customer.id -> c.ProductId
jn = jn.Join<Product, Customer>(srcProd => srcProd.Id, dstCust => dstCust.productId)
.Where<Customer>(c=>c.Id == custIdParameter);
var sql = jn.ToSql();
You can add a ".Where" again for the
Where<Product>(p=>p.id == foo);
if you need to add more product with your BLAH. This should get you close.
Have you tried the SelectAll extension method?
var sql = new JoinSqlBuilder<Product, Product>()
.Join<Product, Customer>(src => src.Id, dst => dst.Id)
.SelectAll<Product>()
.Where<Customer>(x => x.Id == Id);

how to group a query in linq to Entity

I am using linq to Entity to retrieve data from to different tables by joining them, but I also want to group them by the field problemDesc in order to get rid of unnecessary duplicate entries for the same problem.
here is the code:
using (AssistantEntities context = new AssistantEntities())
{
var problems = context.tblProblems;
var customers = context.tblCustomers;
var query =
from problem in problems
join customer in customers
on problem.CustID equals customer.custID
where problem.IsActive == true
orderby customer.isMonthlyService == true descending
select new
{
problemID = problem.problemID,
ProblemCreateDate = problem.ProblemCreateDate,
CustID = problem.CustID,
name = customer.name,
isMonthlyService = customer.isMonthlyService,
StationName = problem.StationName,
problemDesc = problem.problemDesc,
LogMeIn = problem.LogMeIn
};
return query.ToList();
}
I am doing query.toList() in order to use that list in a gridview as a dataSource.
and if it possible, also add a field that count the duplicate problems.
You have plenty of examples in the following link.
LINQ - Grouping Operators

Resources