Automapper project from joined tables in linq - linq

I am joining two tables in LINQ and using AutoMapper 9 to project the result into a DTO object.
var result = (from s in _db.TableA
join d in _db.TableB on s.Id equals d.ForeignKeyId
select s).ProjectTo<MyDTO>(mapper).ToList();
This works fine except I need one property from the joined table d to be mapped into the MyDTO object as well.
Is there a way to tell AutoMapper to project properties from both tables?

Related

Hibernate, Order by count of subquery on ManyToMany using Predicates

I have a query written using Predicates in Hibernate and I need to add a subquery on a join table to count the number of joins and order by the number of joins where they exist in an array of ids.
The join table is a ManyToMany relation.
I am using flyway to setup the table schema, so while the join table exists in the database, a join model is not needed in Hibernate to join the 2 related models therefore no join model exists.
I don't care about retrieving these related models, I just want the number of joins so that I can order by them.
The following is PostGreSQL, which works. I need to convert the following PSQL into a Predicate based query:
SELECT u.*, COUNT(jui.interest_id) AS juiCount
FROM "user" u
LEFT JOIN (
SELECT ui.user_id, ui.interest_id
FROM user_interest ui
WHERE ui.interest_id IN (?)
) AS jui ON u.id = jui.user_id
GROUP BY u.id
ORDER BY juiCount DESC
Where the ids provided for the IN condition are passed into the subquery. The above query is in PostGreSQL.
Working with what I have so far:
CriteriaBuilder b = em.getCriteriaBuilder();
CriteriaQuery<User> q = b.createQuery(User.class);
Root<User> u = q.from(User.class);
// This doesn't make sense because this is not a join table
// Subquery<Interest> sq = q.subquery(Interest.class)
// Root<Interest> squi = sq.from(Interest.class);
// sq.select(squi);
// sq.where(b.in("interest_id", new LiteralExpression<Long[]>((CriteriaBuilderImpl) b, interestIds)));
q.orderBy(
// b.desc(b.tuple(u, b.count(squi))),
b.asc(u.get(User_.id))
);
q.where(p);
return em
.createQuery(q)
.getResultList();
Everything I have managed to find doesn't quite seem to fit right given that they are not using ManyToMany in the use of q.subquery() in their example.
Anyone can help fill in the blanks on this please?

How can I convert sql to linq

This is my SQL query
SELECT
sys.sysobjects.name Name,
sys.foreign_keys.*
FROM
sys.foreign_keys
inner join sys.sysobjects on
sys.foreign_keys.parent_object_id = sys.sysobjects.id
WHERE
referenced_object_id = OBJECT_ID(N'[dbo].[Country]')
I have installed Linqer to convert SQL to linq.
But I got an error:
SQL cannot be converted to LINQ: Table [foreign_keys] not found in the current Data Context.
I am a beginner in Linq. Can Anyone help me to convert SQL to Linq
The problem is that system views will not be picked up by Linqer. If you want to read these tables in your application, first create your own views on them, as was done here and write a query on these views.
CREATE VIEW SysObjectsView AS SELECT * FROM sys.sysobjects;
GO
CREATE VIEW SysForeignKeysView AS SELECT * FROM sys.foreign_keys;
GO
SELECT obj.name Name, fk.*
FROM SysForeignKeysView fk
INNER JOIN SysObjectsView obj ON fk.parent_object_id = obj.id
INNER JOIN SysObjectsView objfk ON fk.referenced_object_id = objfk.id
WHERE objfk.name = N'Country'
Linqer should be able to pick up these views.

Entity Framework 4 generated queries are joining full tables

I have two entities: Master and Details.
When I query them, the resulting query to database is:
SELECT [Extent2]."needed columns listed here", [Extent1]."needed columns listed here"
FROM (SELECT * [Details]."all columns listed here"...
FROM [dbo].[Details] AS [Details]) AS [Extent1]
LEFT OUTER JOIN [dbo].[Master] AS [Extent2] ON [Extent1].[key] = [Extent2].[key]
WHERE [Extent1].[filterColumn] = #p__linq__0
My question is: why not the filter is in the inner query? How can I get this query? I've tried a lot of EF and Linq expressions.
What I need is something like:
SELECT <anything needed>
FROM Master LEFT JOIN Details ON Master.key = Details.Key
WHERE filterColumn = #param
I'm having a full sequential scan in both tables, and in my production environment, I have milions of rows in each table.
Thanks a lot !!
Sometimes The entity Framework does not produce the best query. You can do a few of the following to optimize.
Modify the linq statement (test with
LINQPad)
Create a stored proc and map the stored proc to return an entity
Create a view that handles the join and map the view to a new
entity

How to use Entity Framework to work with many-to-many relationships?

I have a SampleDB that contains 3 tables.
Table Employees (EmployeeID, EmployeeName)
Table Projects (ProjectID, ProjectName)
Table ProjectResources (ProjectID, EmployeeID)
The ProjectResources table is cross reference table that creates a many-to-many relationship between Employees and Projects.
I would like to use LINQ to select all the Employees that have not yet been assigned to a particular project. Here are the steps I took:
Created an entity data model from the SampleDB above using the Entity Framework wizard. The wizard create two entities: Employees and Projects, which I renamed to be Employee and Project. The Project entity has an Employees navigation property that references a collection of Employees and the Employee entity has a Projects navigation property that references a collection of Projects. So it looks as if EF has correctly identified my many-to-many relationship between Employees and Projects table.
Now here is the code I used to attempt to select all the Employees that have not yet been assigned to a Project.
SampleDBEntities db = new SampleDBEntities();
var project = db.Projects.Include("Employees")
.FirstOrDefault(p => p.ProjectID == 1);
var currentEmployees = project.Employees;
var employeesNotAssignedToProject =
db.Employees.Except(currentEmployees);
var project loads fine with the Project that has ProjectID of 1
var currentEmployees loads fine with a list of Employees currently assigned to that Project
Then I get the following exception when I attempt to watch the resultsview ofemployeesNotAssignedToProject in the watch window:
{"Unable to create a constant value of type 'System.Collections.Generic.IEnumerable`1'.
Only primitive types ('such as Int32, String, and Guid') are supported in this context."}
So questions are:
Why am I getting this exception?
Is there another way (that works) of trying to accomplish this type of task? Notice that I am trying to use the "Except" method. Perhaps there is a better way.
What about this:
var employeesNotAssignedToProject = db.Employees.Select(e => e).Where(e => (e.Projects.Count(c => c.ProjectID == 1)) == 0)
I haven't tested this, but basically what it does is it selects only those employees where their Projects collection does not include the project in question by checking the count of projects with the given id.

Is an outer join possible with Linq to Entity Framework

There are many examples of outer join using Linq to Sql, all of them hinging on DefaultIfEmpty() which is not supported with Linq to Entity Framework.
Does this mean that outer join is not possible with Linq to Entity using .NET 3.5 (I understand that DefaultIfEmpty is coming with 4.0 --- but that's not an option at this time for me)
Could somebody please provide a concise example using Linq to EntityFramework.
In LINQ to Entities, think in terms of relationships rather than SQL joins. Hence, the literal equivalent of a SQL outer join on an entity Person with a one to zero or one relationship to CustomerInfo would be:
var q = from p in Context.People
select new
{
Name = p.Name,
IsPreferredCustomer = (bool?)p.CustomerInfo.IsPreferredCustomer
};
L2E will coalesce the join, so that if CustomerInfo is null then the whole expression evaluates to null. Hence the cast to a nullable bool, because the inferred type of non-nullable bool couldn't hold that result.
For one-to-many, you generally want a hierarchy, rather than a flat, SQL-style result set:
var q = from o in Context.Orders
select new
{
OrderNo = o.OrderNo,
PartNumbers = from od in o.OrderDetails
select od.PartNumber
}
This is like a left join insofar as you still get orders with no details, but it's a graph like OO rather than a set like SQL.

Resources