Unirse / Dónde con LINQ y Lambda
Estoy teniendo problemas con una consulta escrita en LINQ y Lambda. Hasta ahora, estoy recibiendo un montón de errores aquí está mi código:
int id = 1;
var query = database.Posts.Join(database.Post_Metas,
post => database.Posts.Where(x => x.ID == id),
meta => database.Post_Metas.Where(x => x.Post_ID == id),
(post, meta) => new { Post = post, Meta = meta });
Soy nuevo en el uso de LINQ, por lo que no estoy seguro de si esta consulta es correcta.
9 answers
Encuentro que si está familiarizado con la sintaxis SQL, usar la sintaxis de consulta LINQ es mucho más claro, más natural y hace que sea más fácil detectar errores:
var id = 1;
var query =
from post in database.Posts
join meta in database.Post_Metas on post.ID equals meta.Post_ID
where post.ID == id
select new { Post = post, Meta = meta };
Si realmente estás atascado en el uso de lambdas, sin embargo, su sintaxis es un poco fuera. Aquí está la misma consulta, usando los métodos de extensión LINQ:
var id = 1;
var query = database.Posts // your starting point - table in the "from" statement
.Join(database.Post_Metas, // the source table of the inner join
post => post.ID, // Select the primary key (the first part of the "on" clause in an sql "join" statement)
meta => meta.Post_ID, // Select the foreign key (the second part of the "on" clause)
(post, meta) => new { Post = post, Meta = meta }) // selection
.Where(postAndMeta => postAndMeta.Post.ID == id); // where statement
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-27 15:41:51
Usted podría ir de dos maneras con esto. Usando LINQPad (invaluable si eres nuevo en LINQ) y una base de datos ficticia, construí las siguientes consultas:
Posts.Join(
Post_metas,
post => post.Post_id,
meta => meta.Post_id,
(post, meta) => new { Post = post, Meta = meta }
)
O
from p in Posts
join pm in Post_metas on p.Post_id equals pm.Post_id
select new { Post = p, Meta = pm }
En este caso particular, creo que la sintaxis de LINQ es más limpia (cambio entre las dos dependiendo de cuál es más fácil de leer).
Lo que me gustaría señalar sin embargo es que si usted tiene claves foráneas apropiadas en su base de datos, (entre post y post_meta) entonces probablemente no necesita una unirse explícitamente a menos que esté tratando de cargar un gran número de registros. Tu ejemplo parece indicar que estás tratando de cargar un solo post y son metadatos. Suponiendo que hay muchos registros post_meta para cada post, entonces usted podría hacer lo siguiente:
var post = Posts.Single(p => p.ID == 1);
var metas = post.Post_metas.ToList();
Si desea evitar el problema n+1, entonces puede decirle explícitamente a LINQ to SQL que cargue todos los elementos relacionados de una sola vez (aunque este puede ser un tema avanzado para cuando esté más familiarizado con L2S). El siguiente ejemplo dice"cuando cargue un Post, también cargue todos sus registros asociados a él a través de la clave foránea representada por la propiedad 'Post_metas'":
var dataLoadOptions = new DataLoadOptions();
dataLoadOptions.LoadWith<Post>(p => p.Post_metas);
var dataContext = new MyDataContext();
dataContext.LoadOptions = dataLoadOptions;
var post = Posts.Single(p => p.ID == 1); // Post_metas loaded automagically
Es posible hacer muchas llamadas LoadWith
en un solo conjunto de DataLoadOptions
para el mismo tipo, o muchos tipos diferentes. Sin embargo, si haces esto mucho, es posible que solo quieras considerar el almacenamiento en caché.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-04 18:27:28
Sus selectores de teclas son incorrectos. Deben tomar un objeto del tipo de la tabla en cuestión y devolver la clave a usar en la combinación. Creo que te refieres a esto:
var query = database.Posts.Join(database.Post_Metas,
post => post.ID,
meta => meta.Post_ID,
(post, meta) => new { Post = post, Meta = meta });
Puede aplicar la cláusula where después, no como parte del selector de teclas.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-04 18:23:16
Daniel tiene una buena explicación de las relaciones de sintaxis, pero armé este documento para mi equipo con el fin de que sea un poco más fácil de entender para ellos. Espero que esto ayude a alguien
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-18 12:30:16
Publicando porque cuando empecé LINQ + EntityFramework, observé estos ejemplos durante un día.
Si está utilizando EntityFramework, y tiene una propiedad de navegación llamada Meta
en su objeto de modelo Post
configurado, esto es muy fácil. Si estás usando entity y no tienes esa propiedad de navegación, ¿qué estás esperando?
database
.Posts
.Where(post => post.ID == id)
.Select(post => new { post, post.Meta });
Si estás haciendo el código primero, configurarías la propiedad de esta manera:
class Post {
[Key]
public int ID {get; set}
public int MetaID { get; set; }
public virtual Meta Meta {get; set;}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-09 03:15:23
He hecho algo como esto;
var certificationClass = _db.INDIVIDUALLICENSEs
.Join(_db.INDLICENSECLAsses,
IL => IL.LICENSE_CLASS,
ILC => ILC.NAME,
(IL, ILC) => new { INDIVIDUALLICENSE = IL, INDLICENSECLAsse = ILC })
.Where(o =>
o.INDIVIDUALLICENSE.GLOBALENTITYID == "ABC" &&
o.INDIVIDUALLICENSE.LICENSE_TYPE == "ABC")
.Select(t => new
{
value = t.PSP_INDLICENSECLAsse.ID,
name = t.PSP_INDIVIDUALLICENSE.LICENSE_CLASS,
})
.OrderBy(x => x.name);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-09 01:13:43
Podría ser algo como
var myvar = from a in context.MyEntity
join b in context.MyEntity2 on a.key equals b.key
select new { prop1 = a.prop1, prop2= b.prop1};
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-22 13:25:42
Esta consulta linq debería funcionar para usted. Obtendrá todo el post que tiene meta post.
var query = database.Posts.Join(database.Post_Metas,
post => post.postId, // Primary Key
meta => meat.postId), // Foreign Key
(post, meta) => new { Post = post, Meta = meta });
Consulta SQL equivalente
Select * FROM Posts P
INNER JOIN Post_Metas pm ON pm.postId=p.postId
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-22 18:27:07
1 es igual a 1 dos tablas diferentes unirse
var query = from post in database.Posts
join meta in database.Post_Metas on 1 equals 1
where post.ID == id
select new { Post = post, Meta = meta };
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-16 20:41:29