Criando uma seleção LINQ de várias tabelas
Pergunta
Esta consulta funciona muito bem:
var pageObject = (from op in db.ObjectPermissions
join pg in db.Pages on op.ObjectPermissionName equals page.PageName
where pg.PageID == page.PageID
select op)
.SingleOrDefault();
Recebo um novo tipo com meus campos 'op'.Agora quero recuperar meus campos 'pg' também, mas
select op, pg).SingleOrDefault();
não funciona.
Como posso selecionar tudo de ambas as tabelas para que apareçam no meu novo tipo pageObject?
Solução
Você pode usar tipos anônimos para isso, ou seja:
var pageObject = (from op in db.ObjectPermissions
join pg in db.Pages on op.ObjectPermissionName equals page.PageName
where pg.PageID == page.PageID
select new { pg, op }).SingleOrDefault();
Isso transformará pageObject em um IEnumerable de tipo anônimo, então AFAIK você não poderá passá-lo para outros métodos, no entanto, se você estiver simplesmente obtendo dados para brincar no método em que está atualmente, está perfeitamente bem.Você também pode nomear propriedades em seu tipo anônimo, ou seja: –
var pageObject = (from op in db.ObjectPermissions
join pg in db.Pages on op.ObjectPermissionName equals page.PageName
where pg.PageID == page.PageID
select new
{
PermissionName = pg,
ObjectPermission = op
}).SingleOrDefault();
Isso permitirá que você diga: -
if (pageObject.PermissionName.FooBar == "golden goose") Application.Exit();
Por exemplo :-)
Outras dicas
Se você não quiser usar tipos anônimos porque digamos que você está passando o objeto para outro método, você pode usar a opção de carregamento LoadWith para carregar os dados associados.Requer que suas tabelas sejam associadas por meio de chaves estrangeiras ou em seu modelo dbml Linq-to-SQL.
db.DeferredLoadingEnabled = false;
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<ObjectPermissions>(op => op.Pages)
db.LoadOptions = dlo;
var pageObject = from op in db.ObjectPermissions
select op;
// no join needed
Então você pode ligar
pageObject.Pages.PageID
Dependendo da aparência dos seus dados, você provavelmente desejaria fazer o contrário,
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Pages>(p => p.ObjectPermissions)
db.LoadOptions = dlo;
var pageObject = from p in db.Pages
select p;
// no join needed
var objectPermissionName = pageObject.ObjectPermissions.ObjectPermissionName;
Se o tipo anônimo causar problemas para você, você poderá criar uma classe de dados simples:
public class PermissionsAndPages
{
public ObjectPermissions Permissions {get;set}
public Pages Pages {get;set}
}
e então na sua consulta:
select new PermissionsAndPages { Permissions = op, Page = pg };
Então você pode passar isso:
return queryResult.SingleOrDefault(); // as PermissionsAndPages
mudar
select op)
para
select new { op, pg })