join - left - linq c# listas
Linq a entidad con mĂșltiples combinaciones externas izquierdas (7)
¡Resuelto!
Salida final:
theCompany.id: 1
theProduct.id: 14
theCompany.id: 2
theProduct.id: 14
theCompany.id: 3
Aquí está el escenario
1 - La base de datos
--Company Table
CREATE TABLE [theCompany](
[id] [int] IDENTITY(1,1) NOT NULL,
[value] [nvarchar](50) NULL,
CONSTRAINT [PK_theCompany] PRIMARY KEY CLUSTERED
( [id] ASC ) WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY];
GO
--Products Table
CREATE TABLE [theProduct](
[id] [int] IDENTITY(1,1) NOT NULL,
[value] [nvarchar](50) NULL,
CONSTRAINT [PK_theProduct] PRIMARY KEY CLUSTERED
( [id] ASC
) WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY];
GO
--CompanyProduct Table
CREATE TABLE [dbo].[CompanyProduct](
[fk_company] [int] NOT NULL,
[fk_product] [int] NOT NULL
) ON [PRIMARY];
GO
ALTER TABLE [CompanyProduct] WITH CHECK ADD CONSTRAINT
[FK_CompanyProduct_theCompany] FOREIGN KEY([fk_company])
REFERENCES [theCompany] ([id]);
GO
ALTER TABLE [dbo].[CompanyProduct] CHECK CONSTRAINT
[FK_CompanyProduct_theCompany];
GO
ALTER TABLE [CompanyProduct] WITH CHECK ADD CONSTRAINT
[FK_CompanyProduct_theProduct] FOREIGN KEY([fk_product])
REFERENCES [dbo].[theProduct] ([id]);
GO
ALTER TABLE [dbo].[CompanyProduct] CHECK CONSTRAINT
[FK_CompanyProduct_theProduct];
2 - Los datos
SELECT [id] ,[value] FROM theCompany
id value
----------- --------------------------------------------------
1 company1
2 company2
3 company3
SELECT [id] ,[value] FROM theProduct
id value
----------- --------------------------------------------------
14 Product 1
SELECT [fk_company],[fk_product] FROM CompanyProduct;
fk_company fk_product
----------- -----------
1 14
2 14
3 - La entidad en VS.NET 2008
texto alternativo http://i478.photobucket.com/albums/rr148/KyleLanser/companyproduct.png
El nombre del contenedor de la entidad es ''testEntities'' (como se ve en la ventana Propiedades del modelo)
4 - El código (¡FINALMENTE!)
testEntities entity = new testEntities();
var theResultSet = from c in entity.theCompany
select new { company_id = c.id, product_id = c.theProduct.Select(e=>e) };
foreach(var oneCompany in theResultSet)
{
Debug.WriteLine("theCompany.id: " + oneCompany.company_id);
foreach(var allProducts in oneCompany.product_id)
{
Debug.WriteLine("theProduct.id: " + allProducts.id);
}
}
5 - La salida final
theCompany.id: 1
theProduct.id: 14
theCompany.id: 2
theProduct.id: 14
theCompany.id: 3
Estoy tratando de entender las uniones externas izquierdas en LINQ to Entity. Por ejemplo, tengo las siguientes 3 tablas:
Compañía, Compañía Producto, Producto
The CompanyProduct está vinculado a sus dos tablas principales, Compañía y Producto.
Deseo devolver todos los registros de la Compañía y el Producto de la Compañía asociado, ya sea que el Producto de la Compañía exista o no para un producto determinado. En Transact SQL, iría de la tabla Company utilizando las combinaciones externas izquierdas de la siguiente manera:
SELECT * FROM Company AS C
LEFT OUTER JOIN CompanyProduct AS CP ON C.CompanyID=CP.CompanyID
LEFT OUTER JOIN Product AS P ON CP.ProductID=P.ProductID
WHERE P.ProductID = 14 OR P.ProductID IS NULL
Mi base de datos tiene 3 compañías y 2 registros CompanyProduct asociados con el ProductID de 14. Entonces los resultados de la consulta SQL son las 3 filas esperadas, 2 de las cuales están conectadas a CompanyProduct y Product y 1 que simplemente tiene la tabla Company y nulls en las tablas de productos y productos de la compañía.
Entonces, ¿cómo se escribe el mismo tipo de unión en LINQ to Entity para obtener un resultado similar?
He intentado algunas cosas diferentes pero no puedo obtener la sintaxis correcta.
Gracias.
¿Qué pasa con esta (usted tiene una relación de muchos a muchos entre la Empresa y el Producto en su Entity Designer, ¿no es así?):
from s in db.Employees
where s.Product == null || s.Product.ProductID == 14
select s;
Entity Framework debería ser capaz de determinar el tipo de unión que se usará.
La unión de grupo normal representa una combinación externa izquierda. Prueba esto:
var list = from a in _datasource.table1
join b in _datasource.table2
on a.id equals b.table1.id
into ab
where ab.Count()==0
select new { table1 = a,
table2Count = ab.Count() };
Ese ejemplo le da todos los registros de la table1
que no tienen una referencia a la table2
. Si omite la oración where
, obtiene todos los registros de la table1
.
Las UNIONES EXTREMAS IZQUIERDAS se realizan mediante el uso de GroupJoin en Entity Framework:
Por favor, intente algo como esto:
from s in db.Employees
join e in db.Employees on s.ReportsTo equals e.EmployeeId
join er in EmployeeRoles on s.EmployeeId equals er.EmployeeId
join r in Roles on er.RoleId equals r.RoleId
where e.EmployeeId == employeeId &&
er.Status == (int)DocumentStatus.Draft
select s;
¡Aclamaciones!
Querrá utilizar Entity Framework para configurar un mapeo de muchos a muchos de la empresa al producto. Esto utilizará la tabla CompanyProduct, pero hará que no sea necesario tener una entidad CompanyProduct establecida en su modelo de entidad. Una vez que haya hecho eso, la consulta será muy simple y dependerá de las preferencias personales y de cómo quiera representar los datos. Por ejemplo, si solo desea todas las empresas que tienen un producto determinado, podría decir:
var query = from p in Database.ProductSet
where p.ProductId == 14
from c in p.Companies
select c;
o
var query = Database.CompanySet
.Where(c => c.Products.Any(p => p.ProductId == 14));
Su consulta SQL devuelve la información del producto junto con las compañías. Si eso es lo que estás buscando, puedes intentar:
var query = from p in Database.ProductSet
where p.ProductId == 14
select new
{
Product = p,
Companies = p.Companies
};
Utilice el botón "Agregar comentario" si desea proporcionar más información, en lugar de crear otra respuesta.
TI debería ser algo así ...
var query = from t1 in db.table1
join t2 in db.table2
on t1.Field1 equals t2.field1 into T1andT2
from t2Join in T1andT2.DefaultIfEmpty()
join t3 in db.table3
on t2Join.Field2 equals t3.Field3 into T2andT3
from t3Join in T2andT3.DefaultIfEmpty()
where t1.someField = "Some value"
select
{
t2Join.FieldXXX
t3Join.FieldYYY
};
Así es como lo hice ...