Unir tablas usando QueryExpression
Utilice la propiedad QueryExpression.LinkEntities para describir los datos de las tablas relacionadas que se devolverán con su consulta. Esta propiedad contiene una colección de instancias de LinkEntity que describen:
- Qué filas de la tabla relacionadas devolver
- En qué valores de columna basar la combinación
- Qué columnas de esos registros devolver
- Cualquier filtro para aplicar con la combinación
Nota
La propiedad LinkEntities
es de solo lectura. Puede configurar instancias de LinkEntity
en esta colección usando la inicialización de objetos o usando el método QueryExpression.AddLink.
También puede usar métodos System.Collections.ObjectModel.Collection<T> las herencias de propiedades de LinkEntities
.
Propiedades de LinkEntity
La siguiente tabla proporciona detalles sobre las propiedades de LinkEntity:
Property | Description |
---|---|
LinkFromEntityName | El nombre lógico de la entidad desde la que se está vinculando. Para LinkEntity que no está anidado, use el mismo valor que la propiedad QueryExpression.EntityName.Para un LinkEntity que está anidado en una colección LinkEntity.LinkEntities, use el valor de LinkEntity.LinkToEntityName de la entidad de vínculo principal. |
LinkToEntityName | El nombre lógico de la entidad a la que se está vinculando. |
LinkFromAttributeName | El nombre lógico del atributo de la entidad desde la que se está vinculando. |
LinkToAttributeName | El nombre lógico del atributo de la entidad a la que se está vinculando. |
JoinOperator | El operador de combinación. Utilice un valor de uno de los miembros de JoinOperator enum. El valor predeterminado es Inner , que restringe los resultados a filas con valores coincidentes en ambas tablas.Otros valores válidos son: - LeftOuter incluye resultados de la fila principal que no tienen un valor coincidente.- Natural Solo se devuelve un valor de las dos columnas unidas si se realiza una operación de combinación igual y los dos valores son idénticos.Estos miembros consideraron JoinOperators avanzados: - Exists - In - MatchFirstRowUsingCrossApply Estos miembros se utilizan para filtrar valores en registros relacionados: - All - Any - NotAll - NotAny |
EntityAlias | El alias de la tabla. |
Columns | Las columnas que se incluirán en la tabla. Agregue estas columnas a la tabla unida usando ColumnSet. Aprenda a seleccionar columnas usando QueryExpression |
LinkCriteria | La condición compleja y las expresiones de filtro lógicas que filtran los resultados de la consulta. Aprender a filtrar filas usando QueryExpression |
LinkEntities | La colección de vínculos entre entidades que pueden incluir vínculos anidados. Se pueden incluir hasta 15 vínculos en total en una consulta. |
Nota
El significado de las propiedades LinkEntity.LinkFromAttributeName y LinkEntity.LinkToAttributeName es el opuesto de sus atributos from
y to
correspondientes en FetchXml. Obtener más información sobre el uso de los atributos from
y to
con FetchXml
Ejemplo de LinkEntity
La siguiente consulta devuelve hasta cinco registros de las tablas cuenta y contacto basadas en la columna de búsqueda PrimaryContactId en el registro de cuenta. Esto representa una relación de varios a uno:
QueryExpression query = new("account")
{
TopCount = 5,
ColumnSet = new ColumnSet("name"),
LinkEntities = {
new LinkEntity()
{
LinkFromEntityName = "account",
LinkToEntityName = "contact",
LinkFromAttributeName = "primarycontactid",
LinkToAttributeName = "contactid",
JoinOperator = JoinOperator.Inner,
EntityAlias = "contact",
Columns = new ColumnSet("fullname")
}
}
};
Los resultados tienen este aspecto:
-----------------------------------------------------------------
| name | contact.fullname |
-----------------------------------------------------------------
| Litware, Inc. (sample) | Susanna Stubberod (sample) |
-----------------------------------------------------------------
| Adventure Works (sample) | Nancy Anderson (sample) |
-----------------------------------------------------------------
| Fabrikam, Inc. (sample) | Maria Campbell (sample) |
-----------------------------------------------------------------
| Blue Yonder Airlines (sample) | Sidney Higa (sample) |
-----------------------------------------------------------------
| City Power & Light (sample) | Scott Konersmann (sample) |
-----------------------------------------------------------------
Métodos de AddLink
Puede redactar la consulta completa utilizando la inicialización de objetos como se muestra, pero recomendamos usar los métodos QueryExpression.AddLink y LinkEntity.AddLink. Estos métodos devuelven una referencia al vínculo creado para que pueda tener acceso y modificar fácilmente la consulta dentro de la colección. Por ejemplo, si redacta la consulta de esta manera utilizando el método QueryExpression.AddLink:
var query = new QueryExpression("account")
{
TopCount = 5,
ColumnSet = new ColumnSet("name"),
};
// Link to primary contact
LinkEntity linkedPrimaryContact = query.AddLink(
linkToEntityName: "contact",
linkFromAttributeName: "primarycontactid",
linkToAttributeName: "contactid",
joinOperator: JoinOperator.Inner);
linkedPrimaryContact.EntityAlias = "primarycontact";
linkedPrimaryContact.Columns = new ColumnSet("fullname");
Puede ampliar la consulta utilizando el método LinkEntity.AddLink para incluir información sobre usuario propietario para el contacto vinculado a través de la instancia linkedPrimaryContact
LinkEntity
:
// Link to contact owning user
LinkEntity linkedContactOwner = linkedPrimaryContact.AddLink(
linkToEntityName: "systemuser",
linkFromAttributeName: "owninguser",
linkToAttributeName: "systemuserid",
joinOperator: JoinOperator.Inner);
linkedContactOwner.EntityAlias = "owner";
linkedContactOwner.Columns = new ColumnSet("fullname");
De esta manera podrá tener acceso más fácilmente a las diferentes partes de la consulta para realizar ajustes.
Limitaciones
Puede agregar hasta 15 instancias LinkEntity a una consulta. Cada LinkEntity
agrega un JOIN a la consulta y aumenta el tiempo para ejecutar la consulta. Este límite es para proteger el rendimiento. Si agrega más de 15 instancias de LinkEntity
a QueryExpression.LinkEntities, obtendrá este error de tiempo de ejecución:
Nombre:
TooManyLinkEntitiesInQuery
Código:0x8004430D
Número:-2147204339
Mensaje:Number of link entities in query exceeded maximum limit.
Relaciones de varios a uno
El ejemplo anterior es una relación de muchos a uno donde muchos registros de cuentas pueden hacer referencia a un registro de contacto. Esta información se define en la relación de muchos a uno Relación de cuenta account_primary_contact, que tiene los siguientes valores:
Propiedad | valor | Comentario |
---|---|---|
SchemaName |
account_primary_contact |
Nombre único de la relación. |
ReferencedEntity |
contact |
La tabla referenciada. El one (uno) en many-to-one (muchos a uno). LinkToEntityName en el ejemplo anterior. |
ReferencedAttribute |
contactid |
La clave principal de la tabla referenciada. LinkToAttributeName en el ejemplo anterior. |
ReferencingEntity |
account |
La tabla con una columna de búsqueda que hace referencia a la otra tabla. El many (muchos) en many-to-one (muchos a uno). LinkFromEntityName en el ejemplo anterior. |
ReferencingAttribute |
primarycontactid |
El nombre de la columna de búsqueda. LinkFromAttributeName en el ejemplo anterior. |
RelationshipType |
OneToManyRelationship |
Una relación de uno a muchos cuando se ve desde la tabla referenciada (uno) contact .Una relación de muchos a uno cuando se be desde la tabla de referencia (muchos) account |
Recuperar información de la relación
Puede utilizar otras herramientas y API para buscar datos de relaciones para los valores LinkToEntityName
, LinkToAttributeName
, LinkFromEntityName
y LinkFromAttributeName
a utilizar. Para obtener más información, consulte:
Ejemplo de relación varios a uno
La siguiente tabla muestra los valores de relación que se utilizarán para una relación de varios a uno:
Property | Valor de la relación | Comment |
---|---|---|
LinkFromEntityName |
ReferencingEntity |
La tabla referenciada. El many (muchos) en many-to-one (muchos a uno). account en el ejemplo de varios a uno. No hay ningún parámetro para esta propiedad en los métodos AddLink porque puede derivarse de las propiedades QueryExpression.EntityName o LinkEntity.LinkToEntityName . |
LinkToEntityName |
ReferencedEntity |
La tabla con una clave principal a la que hace referencia la otra tabla. El one (uno) en many-to-one (muchos a uno). contact en el ejemplo de varios a uno. |
LinkFromAttributeName |
ReferencingAttribute |
El nombre de la columna de búsqueda. primarycontactid en el ejemplo de varios a uno. |
LinkToAttributeName |
ReferencedAttribute |
La clave principal de la tabla referenciada. contactid en el ejemplo de varios a uno. |
Relaciones de uno a varios
Las relaciones de muchos a uno y de uno a muchos son como ver las dos caras de una moneda. La relación existe entre las tablas, por lo que la forma en que la use depende de qué tabla es la tabla base para su consulta.
Nota
Si su tabla base contiene la columna de búsqueda, es una relación de varios a uno. De lo contrario, es una relación de uno a varios.
Puede recuperar los mismos datos que en el ejemplo anterior de la tabla contacto usando la misma relación, excepto en la lado de la tabla contact
. Utilice los datos de la misma relación de cuenta account_primary_contact one-to-many, pero ajuste los valores para la vista diferente de la relación.
var query = new QueryExpression("contact")
{
TopCount = 5,
ColumnSet = new ColumnSet("fullname"),
};
// Link to related account
var linkedPrimaryContact = query.AddLink(
linkToEntityName: "account",
linkFromAttributeName: "contactid",
linkToAttributeName: "primarycontactid",
joinOperator: JoinOperator.Inner);
linkedPrimaryContact.EntityAlias = "account";
linkedPrimaryContact.Columns = new ColumnSet("name");
Para una relación de uno a varios, utilice estos valores de relación:
Property | Valor de la relación | Comment |
---|---|---|
LinkFromEntityName |
ReferencedEntity |
La tabla referenciada. El one (uno) en many-to-one (muchos a uno). contact en el ejemplo de uno a varios. No hay ningún parámetro para esta propiedad en los métodos AddLink porque puede derivarse de las propiedades QueryExpression.EntityName o LinkEntity.LinkToEntityName . |
LinkToEntityName |
ReferencingEntity |
La tabla con una columna de búsqueda que hace referencia a la otra tabla. El many (muchos) en many-to-one (muchos a uno). account en el ejemplo de uno a varios. |
LinkFromAttributeName |
ReferencedAttribute |
La clave principal de la tabla referenciada. contactid en el ejemplo de uno a varios. |
LinkToAttributeName |
ReferencingAttribute |
El nombre de la columna de búsqueda. primarycontactid en el ejemplo de uno a varios. |
Los resultados incluyen los mismos registros y datos que el ejemplo anterior usando la relación de varios a uno, excepto que ahora la 'entidad principal' es contact
en lugar de account
.
-----------------------------------------------------------------
| fullname | account.name |
-----------------------------------------------------------------
| Susanna Stubberod (sample) | Litware, Inc. (sample) |
-----------------------------------------------------------------
| Nancy Anderson (sample) | Adventure Works (sample) |
-----------------------------------------------------------------
| Maria Campbell (sample) | Fabrikam, Inc. (sample) |
-----------------------------------------------------------------
| Sidney Higa (sample) | Blue Yonder Airlines (sample) |
-----------------------------------------------------------------
| Scott Konersmann (sample) | City Power & Light (sample) |
-----------------------------------------------------------------
Relaciones de varios a varios
Las relaciones de muchos a muchos dependen de una tabla de intersección. Una tabla de intersección normalmente tiene solo cuatro columnas, pero solo dos de ellas son importantes. Las dos columnas importantes coinciden con las columnas de clave principal de las tablas participantes.
Por ejemplo, la tabla de intersección TeamMembership
admite la relación de muchos a muchos teammembership_association entre SystemUser y Team . Permite a los usuarios unirse a varios equipos y a los equipos tener varios usuarios. TeamMembership
tiene estas columnas: systemuserid
, teamid
.
Si desea recuperar información sobre los usuarios y los equipos a los que pertenecen utilizando la relación teammembership_association
de varios a varios, puede utilizar esta consulta QueryExpression:
var query = new QueryExpression("systemuser")
{
TopCount = 2,
ColumnSet = new ColumnSet("fullname"),
};
LinkEntity linkedTeamMemberShip = query.AddLink(
linkToEntityName: "teammembership",
linkFromAttributeName: "systemuserid",
linkToAttributeName: "systemuserid");
LinkEntity linkedTeam = linkedTeamMemberShip.AddLink(
linkToEntityName: "team",
linkFromAttributeName: "teamid",
linkToAttributeName: "teamid");
linkedTeam.EntityAlias = "team";
linkedTeam.Columns = new ColumnSet("name");
Hay dos instancias de LinkEntity.
linkedTeamMemberShip
se conectasystemuser
a la tabla de intersección deteammembership
dondesystemuserid
=systemuserid
.linkedTeam
conecta la tabla de intersección deteammembership
al equipo en el queteamid
=teamid
.
El resultado deberá ser ahora similar a:
--------------------------------------
| fullname | team.name |
--------------------------------------
| FirstName LastName | org26ed931d |
--------------------------------------
| # PpdfCDSClient | org26ed931d |
--------------------------------------
No existe relación
Es posible especificar propiedades LinkFromAttributeName
y LinkToAttributeName
usando columnas que no forman parte de una relación definida.
Por ejemplo, esta consulta encuentra pares de registros donde la Columna de nombre de un registro de cuenta coincide con la columna FullName de un registro de contacto independientemente de si se hacen referencia entre sí en cualquiera de las columnas de búsqueda.
var query = new QueryExpression("account")
{
ColumnSet = new ColumnSet("name"),
};
LinkEntity linkedContact = query.AddLink(
linkToEntityName: "contact",
linkFromAttributeName: "name",
linkToAttributeName: "fullname");
linkedContact.EntityAlias = "contact";
linkedContact.Columns = new ColumnSet("fullname");
Nota
Es importante que las columnas especificadas en las propiedades LinkFromAttributeName
y LinkToAttributeName
sean del mismo tipo incluso si no están involucradas en una relación. El uso de columnas de diferentes tipos requerirá una conversión de tipo que podría tener un impacto en el rendimiento y podría fallar en algunos valores de columna.
Los siguientes tipos de columnas no se pueden usar en las propiedades LinkFromAttributeName
y LinkToAttributeName
:
- Archivo
- Image
- Campo MultiSelect
- PartyList
Algunas columnas se pueden utilizar en las propiedades LinkFromAttributeName
y LinkToAttributeName
, pero pueden provocar un rendimiento deficiente:
- Columnas del tipo Varias líneas de texto
- Columnas del tipo Línea única de texto con una longitud máxima superior a 850
- Columnas de Fórmula
- Columnas de Calculado
- Columnas Lógicas
Buscar registros que no estén en un conjunto
Puede usar QueryExpression para crear una consulta para devolver registros que no están en un conjunto usando una combinación externa izquierda. Una combinación externa izquierda devuelve todas las filas que satisfacen la combinación de la primera entrada con la segunda entrada. También devuelve las filas de la primera entrada que no tenían ninguna fila coincidente en la segunda entrada. Las filas no coincidentes de la segunda entrada se devuelven como valores nulos.
Puede realizar una combinación externa izquierda en QueryExpression
usando la propiedad ConditionExpression.EntityName. La propiedad EntityName
es válida en condiciones, filtros y filtros anidados. Obtener más información sobre los filtros en LinkEntity
Por ejemplo, la siguiente consulta devuelve todos los registros de cuentas sin contactos.
var query = new QueryExpression(entityName: "account");
query.ColumnSet.AddColumn("name");
query.AddOrder(
attributeName: "name",
orderType: OrderType.Descending);
query.Criteria.AddCondition(
entityName: "contact",
attributeName: "parentcustomerid",
conditionOperator: ConditionOperator.Null);
LinkEntity linkedContact = query.AddLink(
linkToEntityName: "contact",
linkFromAttributeName: "accountid",
linkToAttributeName: "parentcustomerid",
joinOperator: JoinOperator.LeftOuter);
linkedContact.EntityAlias = "contact";
linkedContact.Columns.AddColumn("fullname");
Usar JoinOperators avanzados
Los siguientes miembros JoinOperator no corresponden directamente a tipos operador JOIN de T-SQL y usan subconsultas en su lugar. Estos tipos proporcionan capacidades más avanzadas que puede utilizar para mejorar el rendimiento de las consultas y definir consultas más complejas.
Name | Description |
---|---|
Exists |
Una variante de Inner que pueden proporcionar beneficios de rendimiento. Utiliza una condición EXISTS en la cláusula where . Use Exists cuando no sean necesarias varias copias de la fila principal en los resultados. Obtener más información sobre Exists y In . |
In |
Una variante de Inner que pueden proporcionar beneficios de rendimiento. Utiliza una condición IN en la cláusula where. Use In cuando no sean necesarias varias copias de la fila principal en los resultados. Obtener más información sobre Exists y In . |
MatchFirstRowUsingCrossApply |
Una variante de Inner que pueden proporcionar beneficios de rendimiento. Utilice este tipo cuando solo sea suficiente un único ejemplo de una fila coincidente de la entidad vinculada y no sean necesarias varias copias de la fila principal en los resultados. Obtener más información sobre el uso de MatchFirstRowUsingCrossApply |
Use JoinOperator.Exists
o JoinOperator.In
Exists
e In
son variantes de Inner
que utilizan diferentes condiciones ( EXISTS e IN respectivamente) en la cláusula where
para que no se devuelvan varias copias de la fila principal en los resultados. Exists
y In
no devuelven los valores de las columnas de las filas de la entidad relacionada.
El uso de JoinOperator.Exists
o JoinOperator.In
puede reducir el tamaño de los resultados de la consulta intermedia o final, especialmente cuando existen muchas filas vinculadas coincidentes para las mismas filas principales, o cuando se utilizan varias entidades de vínculo con el mismo padre. El uso de JoinOperator.Exists
o JoinOperator.In
puede mejorar el rendimiento de la consulta en comparación con JoinOperator.Inner
porque no requiere devolver un producto cartesiano que contenga todas las permutaciones posibles de filas de diferentes entidades vinculadas para cada fila principal.
Estos miembros de JoinOperator
también podrían permitir a Dataverse buscar solo la primera fila de entidad vinculada coincidente para cada fila principal, lo cual es más eficiente que buscar todas las filas coincidentes en la entidad vinculada con JoinOperator.Inner
.
Ejemplo de JoinOperator.Exists
Estos ejemplos de QueryExpression y SQL muestran los patrones aplicados con JoinOperator.Exists
.
QueryExpression query = new("contact");
query.ColumnSet.AddColumn("fullname");
LinkEntity linkedAccount = query.AddLink(
linkToEntityName: "account",
linkFromAttributeName: "contactid",
linkToAttributeName: "primarycontactid",
joinOperator: JoinOperator.Exists);
linkedAccount.EntityAlias = "account";
linkedAccount.LinkCriteria.AddCondition(
entityName:"account",
attributeName: "statecode",
conditionOperator: ConditionOperator.Equal,
values: 1);
Ejemplo de JoinOperator.In
Estos ejemplos de QueryExpression y SQL muestran los patrones aplicados con JoinOperator.In
.
QueryExpression query = new("contact");
query.ColumnSet.AddColumn("fullname");
LinkEntity linkedAccount = query.AddLink(
linkToEntityName: "account",
linkFromAttributeName: "contactid",
linkToAttributeName: "primarycontactid",
joinOperator: JoinOperator.In);
linkedAccount.EntityAlias = "account";
linkedAccount.LinkCriteria.AddCondition(
entityName: "account",
attributeName: "statecode",
conditionOperator: ConditionOperator.Equal,
values: 1);
Usar JoinOperator.MatchFirstRowUsingCrossApply
JoinOperator.MatchFirstRowUsingCrossApply
produce un operador CROSS APPLY con una subconsulta usando top 1
siguiendo este patrón:
QueryExpression query = new("contact");
query.ColumnSet.AddColumn("fullname");
LinkEntity linkedAccount = query.AddLink(
linkToEntityName: "account",
linkFromAttributeName: "contactid",
linkToAttributeName: "primarycontactid",
joinOperator: JoinOperator.MatchFirstRowUsingCrossApply);
linkedAccount.EntityAlias = "account";
linkedAccount.Columns = new ColumnSet("accountid", "name");
Esto es equivalente a JoinOperator.LeftOuter
excepto que solo devuelve la fila principal como máximo una vez. A diferencia de JoinOperator.In
y JoinOperator.Exists
, devuelve valores de columna de una de las filas coincidentes en la tabla relacionada cuando existen filas coincidentes, pero la fila principal se devuelve incluso si no hay filas coincidentes en la tabla relacionada. Utilícelo cuando solo sea suficiente un único ejemplo de una fila coincidente de la tabla relacionada y no sean necesarias varias copias de la fila principal en los resultados.
Pasos siguientes
Aprenda a filtrar las filas de pedidos.
Nota
¿Puede indicarnos sus preferencias de idioma de documentación? Realice una breve encuesta. (tenga en cuenta que esta encuesta está en inglés)
La encuesta durará unos siete minutos. No se recopilan datos personales (declaración de privacidad).