Entity Framework group by left join query - entity-framework

The Result should look like this
I've started to use Entity Framework for one month so I am not familiar with linq queries. The query I wrote in SQL is:
SELECT
om0001.CUSTOMER, om0001.ITEM_CODE,
SUM(om0001.AMOUNT) AS AMOUNT,
SUM(ep0001.EXPORT_AMOUNT) AS EXPORT_AMOUNT
FROM
om0001
LEFT OUTER JOIN
ep0001 ON om0001.ID = ep0001.om0001_ID
GROUP BY
om0001.CUSTOMER, om0001.ITEM_CODE;
When I run this query in SQL, it runs well so I tried to convert it to linq queries.
What I made so far is
var testjoin = from om0001 in EF.om0001
join ep0001 in EF.ep0001 on om0001.ID equals ep0001.om0001_ID
into jointable
from z in jointable.DefaultIfEmpty()
group z by new {om0001.CUSTOMER, om0001.ITEM_CODE } into g
select new
{
CUSTOMER = g.Key.CUSTOMER,
ITEM_CODE = g.Key.ITEM_CODE,
om0001SUMamount = g.Sum(x => x.AMOUNT),
ep0001EXPORTsumAmount = g.Sum(y => y.EXPORT_AMOUNT)
};
The problem over this linq query is I can not get om0001SUMamount. I get only ep0001 column data. Please help

Obviously, I cant peek into your EF database, so I created some sample data (the 'item' class structures are implied):
var EF = new efClass {
om0001 = new List<om0001item> {
new om0001item { ID = 0, CUSTOMER = 0, ITEM_CODE = 0, AMOUNT = 10 },
new om0001item { ID = 1, CUSTOMER = 0, ITEM_CODE = 0, AMOUNT = 20 },
new om0001item { ID = 2, CUSTOMER = 1, ITEM_CODE = 1, AMOUNT = 30 },
new om0001item { ID = 3, CUSTOMER = 1, ITEM_CODE = 1, AMOUNT = 40 }
},
ep0001 = new List<ep0001item> {
new ep0001item { om0001_ID = 0, EXPORT_AMOUNT = -20 },
new ep0001item { om0001_ID = 1, EXPORT_AMOUNT = -20 }
}
};
With this data, I created a query that frankly feels inelegant and left me disappointed, but that's the nature of left joins in LINQ:
var testjoin = from om0001 in EF.om0001
join ep0001 in EF.ep0001 on om0001.ID equals ep0001.om0001_ID into jointable
select new { om0001, ep0001 = jointable.DefaultIfEmpty() } into combined
group combined by new {
combined.om0001.CUSTOMER,
combined.om0001.ITEM_CODE
} into g
select new {
CUSTOMER = g.Key.CUSTOMER,
ITEM_CODE = g.Key.ITEM_CODE,
om0001SUMamount = g.Sum(x => x.om0001.AMOUNT),
ep0001EXPORTsumAmount = g.Sum(x => x?.ep0001.Sum(y => y?.EXPORT_AMOUNT ?? 0))
};
Bottom line is that when you group by 'jointable', you've lost ep0001 references. So select both ep0001 and om0001 into a new 'combined' object, and then group based off of it.
When I created a javascript library (fluent-data) that had some LINQ-like functionality, I developed a lot of respect and compassion for the LINQ developers. Nevertheless, I don't know why they don't just create a left join operator to add so much more value to all the C# developers who use LINQ.

So you have a table with Oms (actually Om00001, but I'm not going to write all those 0001 over and over again), and a table with Eps, and you have a one-to-many relation between Oms and Eps: Every Om has zero or more Eps, and every Ep belongs to exactly one Om, namely the Om that foreign key EpId refers to.
If you have followed Entity Framework code first conventions you will have classes similar to the following:
class Om
{
public int Id {get; set;}
public string Customer {get; set;}
public string ItemCode {get; set;}
...
// Every Om has zero or more Eps (one-to-many)
public virtual ICollection<Ep> Eps {get; set;}
}
class Ep
{
public int Id {get; set;}
public int Amount {get; set;}
public int ExportAmount {get; set;}
...
// every Ep belongs to exactly one Om, using foreign key
public int OmId {get; set;}
public virtual Om Om {get; set;}
}
This is enough for entity framework to detect your one-to-many relationship. Because I followed the conventions, there is no need for Attributes, nor fluent API. If you want different table names, or columns, you need fluent API / attributes.
In entity framework the non-virtual properties represent the columns of your tables, the virtual properties represent the relations between the tables (one-to-many, many-to-many, ...)
Solution using GroupJoin
var result = dbContext.Oms.GroupJoin(dbContext.Eps,
om => om.Id, // from every Om take the primary key
ep => ep.OmId, // from every ep take the foreign key to the Om
(om, epsOfThisOm) => new // from every om and all eps having the correct foreign key
{ // make one new object
// Select only the properties that you plan to use:
Customer = om.Customer,
ItemCode = om.ItemCode,
Amount = epsOfThisOm.Sum(ep => ep.Amount);
ExportAmount = epsOfThisOm.Sum(ep => ep.ExportAmount);
});
Solution using the virtual ICollection
Instead of executing a GroupJoin, you could also use the virtual ICollection.
Requirement: from every Om, give me the Customer and the ItemCode, and the sum of all Amounts of its Eps, and the sum of all ExportAmounts of its Eps.
var result = dbContext.Oms.Select(om => new
{
Customer = om.Customer,
ItemCode = om.ItemCode,
Amount = om.Eps.Sum(ep => ep.Amount);
ExportAmount = om.Eps.Sum(ep => ep.ExportAmount);
});
This looks much neater, and it matches more directly your requirement. Entity framework knows the relations, and will do the correct GroupJoin for you.

Related

Is my Linq Query Optimal and High performance in EF Core 3.1?

can i remove vg.First().Voucher ? and replace the beter code? what is the optimal and best practice?
is convertable this code to another method? like chain method?
var query = from v in _journalLineRepository.TableNoTracking
.Include(j => j.Voucher).AsEnumerable()
group v by v.AccountId into vg
select new // <-- temporary projection with group by fields needed
{
AccountId = vg.Key,
Credit = vg.Sum(v => v.Credit),
Debit = vg.Sum(v => v.Debit),
Voucher = vg.First().Voucher
} into vg
join p in _partyRepository.TableNoTracking.Include(p => p.PartyPhones).AsEnumerable() on vg.AccountId equals p.AccountId // <-- additional join(s)
select new PartyDeptorAndCreditorViewModel
{
PartyId = p.Id,
FullName = p.FullName,
PhoneNo = p.PartyPhones.FirstOrDefault(p => p.IsActive)?.Phone,
ProjectId = vg.Voucher.ProjectId,
AccountId = vg.AccountId.Value,
Creditor = vg.Credit,
Deptor = vg.Debit,
Balance = vg.Credit - vg.Debit,
VoucherDate = vg.Voucher.VoucherDate,
VoucherRegisterDate = vg.Voucher.VoucherDate,
BalanceType =
vg.Debit > vg.Credit ? AccountingComplexEnum.ShowPartyBalanceParamSearch.Deptor.ToDisplay(DisplayProperty.Name) :
vg.Debit < vg.Credit ? AccountingComplexEnum.ShowPartyBalanceParamSearch.Creditor.ToDisplay(DisplayProperty.Name) :
AccountingComplexEnum.ShowPartyBalanceParamSearch.ZeroBalance.ToDisplay(DisplayProperty.Name),
};
I'd certainly be looking at the SQL query generated. At face value I see a few warning flags that it may not be composing a query but possibly pre-executing to in-memory processing which would be inefficient. It would firstly depend on what these .TableNoTracking methods/properties return, and the use of .AsEnumerable on the eager load joins.
Firstly, when projecting with Select, eager load joins (.Include) are not necessary. The projections will take care of the joins for you, provided it is projecting down to SQL. If you take out the .Include().AsEnumerable() calls and your query still works then it is likely projecting down to SQL. If it is no longer working then it's processing in memory and not efficiently.
Edit: Nope, the inner projection won't resolve: Regarding the .Voucher, your final projection is using 2 fields from this entity, so it stands you could replace this in the initial projection:
select new // <-- temporary projection with group by fields needed
{
AccountId = vg.Key,
Credit = vg.Sum(v => v.Credit),
Debit = vg.Sum(v => v.Debit),
Voucher = vg.Select(v => new { v.ProjectId, v.VoucherDate }).First()
} into vg
When it comes to transformations like this:
BalanceType = vg.Debit > vg.Credit
? AccountingComplexEnum.ShowPartyBalanceParamSearch.Deptor.ToDisplay(DisplayProperty.Name)
: vg.Debit < vg.Credit
? AccountingComplexEnum.ShowPartyBalanceParamSearch.Creditor.ToDisplay(DisplayProperty.Name)
: AccountingComplexEnum.ShowPartyBalanceParamSearch.ZeroBalance.ToDisplay(DisplayProperty.Name),
... inside a projection, this sends off warning flags as Linq2EF needs to compose projections down to SQL so methods/extensions like ToDisplay won't be understood. Instead, since this is based solely on the Credit/Debit amounts, I'd move this to be computed by the property in the view model:
select new PartyDeptorAndCreditorViewModel
{
PartyId = p.Id,
FullName = p.FullName,
PhoneNo = p.PartyPhones
.Where(p => p.IsActive)
.Select(p => p.Phone)
.FirstOrDefault(),
ProjectId = vg.Voucher.ProjectId,
AccountId = vg.AccountId.Value,
Creditor = vg.Credit,
Deptor = vg.Debit,
Balance = vg.Credit - vg.Debit,
VoucherDate = vg.Voucher.VoucherDate,
VoucherRegisterDate = vg.Voucher.VoucherDate
};
Then in the view model:
[Serializable]
public class PartyDebtorAndCreditorViewModel
{
// ...
public decimal Balance { get; set; }
public string BalanceType
{
get
{
return Balance < 0
? AccountingComplexEnum.ShowPartyBalanceParamSearch.Deptor.ToDisplay(DisplayProperty.Name)
: Balance > 0
? AccountingComplexEnum.ShowPartyBalanceParamSearch.Creditor.ToDisplay(DisplayProperty.Name)
: AccountingComplexEnum.ShowPartyBalanceParamSearch.ZeroBalance.ToDisplay(DisplayProperty.Name);
}
}
}

Linq result return zero vs null

Is there a way I have have this linq statement not return nulls ? I would like it to returns 0 I have tried ?? 0 but that is not working
Customer = (from c in db.Customers
join cx in db.CustomerXrefs on c.CustomerId equals cx.CustomerId
join g in db.Groups on cx.GroupId equals g.GroupId
select new Customer
{
CustomerId = c.CustomerId,
Institution = (from ig in db.Groups
join icx in db.CustomerXrefs on ig.GroupId equals icx.GroupId
where icx.CustomerId == c.CustomerId && ig.GroupTypeId == 308
select new Institution()
{
Name = ig.Name == "In1 " ? "Institution 1" :
ig.Name == "In2" ? "Institution 2" :
ig.Name
}
).FirstOrDefault()
}).FirstOrDefault();
It is a bit difficult to distill from your question what you want to achieve. You give us some code, and tell us that the code doesn't do what you want, and ask us to give you the code that does give the requested result.
I hope I can extract your requirement from your code.
It seems that you have a table of Customers and a table of Groups. There seems to be a many-to-many relation between Customers and Groups: every Customer belongs to zero or more Groups, every Group has zero or more Customers that belong to this Group.
In relational databases, a many-to-many relation is implemented using a junction table. The junction table for the many-to-many between Customers and Groups is table CustomerXRefs
For every Customer in the table of Customers, you want its CustomerId, and a Property Institution.
The value of Institution is filled with a Name. This name is taken from the first Group of this Customer with GroupTypeId equal to 308.
There are two solutions for this:
Use GroupJoins to get the Customers with their Groups and extract the Institution from these groups
Use the capability of entity framework to translate the virtual ICollection<...> into the corrrect GroupJoins. Use the virtual properties, entity framework translates them into the proper GroupJoin.
Usually the latter solution is easier, so we'll start with that one first.
The classes
If you have followed the entity framework conventions, you'll have classes similar to the following:
class Customer
{
public int Id {get; set;}
... // other properties
// every Customer belongs to zero or more Groups (many-to-many)
public virtual ICollection<Group> Groups {get; set;}
}
class Group
{
public int Id {get; set;}
public int GroupTypeId {get; set;}
public string Name {get; set;}
... // other properties
// every Group has to zero or more Customers(many-to-many)
public virtual ICollection<Customer> Customers {get; set;}
}
This is enough for entity framework to detect your many-to-many relation. Without even mentioning it, entity framework will create a junction table for you. Only if you want different names of tables or properties, you'll need fluent API or attributes.
In entity framework the columns of the table are represented by non-virtual properties; the virtual properties represent the relations between the tables: one-to-many, many-to-many, ...
Query using the virtual ICollection
var customersWithTheirGroups = dbContext.Customers.Select(customer => new
{
CustomerId = customer.Id,
Institution = customer.Groups.Where(group => group.GroupTypeId == 308)
.Select(group => new Institution
{
name = (ig.Name == "In1") ? "Institution 1" :
(ig.Name == "In2") ? "Institution 2 :
ig.Name,
})
.FirstOrDefault(),
});
BTW: note the parentheses around (ig.Name == "In1"). I think that if Name equals "In1" that you want a name "Institution 1", etc.
Is it correct that you have a class Institution with only one property?
class Institution
{
public string Name {get; set;}
}
Although it is allowed, it is a bit awkward, why not just select the InstitutionName?
.Select(group => (ig.Name == "In1") ? "Institution 1" :
(ig.Name == "In2") ? "Institution 2 :
ig.Name)
.FirstOrDefault(),
Anyway, entity framework knows the relations between the tables and will create the correct groupjoins with the junction tables.
This solution seems very natural.
Solution using GroupJoins
If you want to do the GroupJoin yourself, you'll need to define the junction table:
class CustomerXrefs
{
// every Xref in the junction table belongs to exactly one Customer:
public int CustomerId {get; set;}
// every Xref in the junction table belongs to exactly one Group:
public int GroupId {get; set;}
}
To get each Customer with its Groups, do a GroupJoin of the XRefs with the Customers, followed by another GroupJoin of Groups and XRefs.
var customersWithTheirGroups = dbContext.Customers.GroupJoin(dbContext.CustomerXRefs,
customer => customer.Id, // from every Customer take the Id
xref => xref.CustomerId, // from every xref take the foreign key to Customer
// Parameter resultSelector:
// for every Customer and all its xrefs make one new object:
(customer, xrefsOfThisCustomer) => new
{
Customer = customer,
// To get the Groups of this customer, GroupJoin the Groups with the xrefs:
Groups = dbContext.Groups
// GroupJoin the Group with the xrefs of this Customer
.GroupJoin(xrefsOfThisCustomer,
group => group.Id, // for every Group take the Id,
xRef => xref.GroupId, // for every xref of this customer take the foreign key
// parameter resultSelector:
// for every Group, and all xrefs of this Group that are xrefs of the Customer
// make one new:
(group, xrefs) => group).ToList(),
});
Result: all Customers, each with their Groups.
Select the institution:
var result = customersWithTheirGroups.Select(joinResult => new
{
CustomerId = joinResult.Customer.Id,
Institution = joinResult.Groups
// Keep only the Groups with the desired GroupTypeId
.Where(group => group.GroupTypeId == 308)
// The Select is similar as the Select in the virtual ICollection method:
.Select(group => new Institution
{
name = (ig.Name == "In1") ? "Institution 1" :
(ig.Name == "In2") ? "Institution 2 :
ig.Name,
})
.FirstOrDefault(),
});
Customer is a class (reference type). Default value for a reference type is null. If you want to return some non null value (if there exists correct "default" for your use case) you will need to provide one, for example:
Customer = (...).FirstOrDefault() ?? new Customer();

Entity Framework: Left Join with List Result

I'm trying to optimize my EF queries. I have an entity called Employee. Each employee has a list of tools. Ultimately, I'm trying to get a list of employees with their tools that are NOT broken. When running my query, I can see that TWO calls are made to the server: one for the employee entities and one for the tool list. Again, I'm trying to optimize the query, so the server is hit for a query only once. How can I do this?
I've been exploring with LINQ's join and how to create a LEFT JOIN, but the query is still not optimized.
In my first code block here, the result is what I want, but -- again -- there are two hits to the server.
public class Employee
{
public int EmployeeId { get; set; }
public List<Tool> Tools { get; set; } = new List<Tool>();
...
}
public class Tool
{
public int ToolId { get; set; }
public bool IsBroken { get; set; } = false;
public Employee Employee { get; set; }
public int EmployeeId { get; set; }
...
}
var x = (from e in db.Employees.Include(e => e.Tools)
select new Employee()
{
EmployeeId = e.EmployeeId,
Tools = e.Tools.Where(t => !t.IsBroken).ToList()
}).ToList();
This second code block pseudoly mimics what I'm trying to accomplish. However, the GroupBy(...) is being evaluated locally on the client machine.
(from e in db.Employees
join t in db.Tools.GroupBy(tool => tool.EmployeeId) on e.EmployeeId equals t.Key into empTool
from et in empTool.DefaultIfEmpty()
select new Employee()
{
EmployeeId = e.EmployeeId,
Tools = et != null ? et.Where(t => !t.IsBroken).ToList() : null
}).ToList();
Is there anyway that I can make ONE call to the server as well as not having my GroupBy() evaluate locally and have it return a list of employees with a filtered tool list with tools that are not broken? Thank you.
Shortly, it's not possible (and I don't think it ever will be).
If you really want to control the exact server calls, EF Core is simply not for you. While EF Core still has issues with some LINQ query translation which leads to N+1 query or client evaluation, one thing is by design: unlike EF6 which uses single huge union SQL query for producing the result, EF Core uses one SQL query for the main result set plus one SQL query per each correlated result set.
This is sort of explained in the How Queries Work EF Core documentation section:
The LINQ query is processed by Entity Framework Core to build a representation that is ready to be processed by the database provider
The result is cached so that this processing does not need to be done every time the query is executed
The result is passed to the database provider
The database provider identifies which parts of the query can be evaluated in the database
These parts of the query are translated to database specific query language (for example, SQL for a relational database)
One or more queries are sent to the database and the result set returned (results are values from the database, not entity instances)
Note the word more in the last bullet.
In your case, you have 1 main result set (Employee) + 1 correlated result set (Tool), hence the expected server queries are TWO (except if the first query returns empty set).
You can use this:
var x = from e in _context.Employees
select new
{
e,
Tools = from tool in e.Tools where !tool.IsBroken select tool
};
var result = x.AsEnumerable().Select(y => y.e);
Which will be finally translated to a SQL query like below depending on your provider:
SELECT
`Project1`.`EmployeeId`,
`Project1`.`Name`,
`Project1`.`C1`,
`Project1`.`ToolId`,
`Project1`.`IsBroken`,
`Project1`.`EmployeeId1`
FROM (SELECT
`Extent1`.`EmployeeId`,
`Extent1`.`Name`,
`Extent2`.`ToolId`,
`Extent2`.`IsBroken`,
`Extent2`.`EmployeeId` AS `EmployeeId1`,
CASE WHEN (`Extent2`.`ToolId` IS NOT NULL) THEN (1) ELSE (NULL) END AS `C1`
FROM `Employees` AS `Extent1` LEFT OUTER JOIN `Tools` AS `Extent2` ON (`Extent1`.`EmployeeId` = `Extent2`.`EmployeeId`) AND (`Extent2`.`IsBroken` != 1)) AS `Project1`
ORDER BY
`Project1`.`EmployeeId` ASC,
`Project1`.`C1` ASC
I change my previous answer which was wrong, thanks to comments.

Querying many-To-many relationship with a list of parameters

I use EF core and i have the classes "User" and "Authority" which are connected with a many-to-many relationship ("Users" has a property "authorities" and "Authority" has a property "users"). The relationship is managed via middle class "UserAuthority".
I need to query all "Users" that have "Authorities" with certain names.
I tried this:
List<string> authorities = A list of authorities;
(from user in this.dbContext.user.Include("authorities.authority")
where authorities.Any(x => user.authorities.Any(y => y.authority.authority == x))
select new UserDto(user.id, user.firstname + " " + user.lastname)).ToList()
But the console says that LINQ cant translate
authorities.Any(x => user.authorities.Any(y => y.authority.authority == x))
and that it will be handled in memory.
What is the correct approach here?
Currently the only translatable in-memory collection method is Contains (for primitive type in-memory collection, translates to SQL IN(...)).
So instead of
authorities.Any(x => user.authorities.Any(y => y.authority.authority == x))
use
user.authorities.Any(ua => authorities.Contains(ua.authority.authority))
You wrote:
i have the classes "User" and "Authority" which are connected with a many-to-many relationship ("Users" has a property "authorities" and "Authority" has a property "users").
Something like this:
class User
{
public int Id {get; set;}
...
// every User has zero or more Authorities (many-to-many)
public virtual ICollection<Authority> Authorities {get; set;}
}
class Authority
{
public int Id {get; set;}
public string Name {get; set;}
...
// every Authority has zero or more Users (many-to-many)
public virtual ICollection<User> Users {get; set;}
}
I need to query all "Users" that have "Authorities" with certain names.
If I read this literally, you want all Users, that have at least one Authority that has a Name that is in the collection of certainNames. You want each User with ALL his Authorities, even those Authorities with names that are not in certainNames
It could also mean that you want all Users, each with only those of their Authorities that have a Name which is in certainNames, but only those Users that have at least one such Authority.
How about this:
IEnumerable<string> certainNames = ...
var UsersWithAuthoritiesThatAreInCertainNames = myDbContext.Users
.Where (user => user.Authorities.Select(authority => authority.Name)
.Intersect(certainNames)
.Any())
.Select(user => new
{
// select only the User properties you actually plan to use:
Id = user.Id,
Name = user.Name,
...
Authorities = user.Authorities.Select(authority => new
{
// again select only the Authority properties you plan to use:
Id = authority.Id,
Name = authority.Name,
...
})
.ToList(),
})
In words:
From the collection of all users, keep only those users, that have at least one authority with a name that is also in certainNames. From the remaining users, select several properties.
If you don't want ALL Authorities of the user, but only the ones that are in certain names:
var UsersWithOnlyTheirAuthoritiesThatAreInCertainNames = myDbContext.Users
.Select(user => new
{
// select only the User properties you actually plan to use:
Id = user.Id,
Name = user.Name,
...
Authorities = user.Authorities
.Where(authority => certainNames.Contains(authority.Name))
.Select(authority => new
{
// again select only the Authority properties you plan to use:
Id = authority.Id,
Name = authority.Name,
...
})
.ToList(),
})
// keep only the Users that have at least one such authority
.Where(selectedUser => selectedUser.Authorities.Any());
In words:
from the collection of Users, select some properties of every user, inclusive some properties of only those Authorities of the user that have a name that is also in certainNames. From the remaining sequence of selected users keep only those users that have at least one authority left

Left Outer Join in Linq-To-Entities

Is there a way to do a left outer join in linq-to-entities WITHOUT having tables mapped with foreign keys?
Also, if our company decides to stick with using linq-to-entities despite all of its current flaws, do you think it's important to get Visual Studio 2010? In other words, what is in Visual Studio 2010 that would help developing with entities that isn't in Visual Studio 2008?
Thanks.
This may not satisfy you because the objects are not properly flattened, but you can perform an outer join and return a collection of anonymous types.
A left outer join is the same as the union of the inner join and the except set (the part of the first set which does not join onto the second set).
Here I simply
calculate the inner join
calculate the except set (creating an empty B entity to ensure the types are consistent)
combine the two sets.
The LINQ is not beautiful, but it is cute.
class A
{
public int Id { get; set; }
public string PropertyA { get; set; }
}
class B
{
public int Id { get; set; }
public string PropertyB { get; set; }
}
var aThings = new List<A>();
var bThings = new List<B>();
var innerJoin = aThings.SelectMany(a =>
bThings.Where(b => a.Id == b.Id).Select(b => new { a, b })).ToList();
var exceptSet = aThings.Where(a =>
!bThings.Select(b => b.Id).Contains(a.Id)).Select( a =>
{
B b = new B();
return new { a, b };
});
var outerJoin = innerJoin;
outerJoin.AddRange(exceptSet);
The result is a List of anonymous types {a, b}
Microsoft has two data teams that both aim toward the same goal: LINQ-to-SQL and ADO.NET entity. There support lies now with ADO.NET for Entities which means that LINQ-to-SQL won't be as high a priority as the ADO.NET offering.
Visual Studio 2010 has support for .NET 4 which in turn supports ADO.NET for entities and LINQ-to-SQL. Aside from the number of productivity features presents in VS2010, I've not seen much in terms of data support that's different from VS2008.
In terms of left outer join:
var dc = new DataContext();
var query = (
from t1 in dc.MyTable
join a in MyJoinedTable on p.Id equals a.Id into tempTable
from t2 in tempTable.DefaultIfEmpty()
select new { p.Column1, p.Column2, t2.Column1}
);