Rules / Performance

Check if bi-directional and many-to-many relationships are valid

info CHECK_IF_BI-DIRECTIONAL_AND_MANY-TO-MANY_RELATIONSHIPS_ARE_VALID · ported · model layer · scope: Relationship

What it checks

Every relationship that is bi-directional, many-to-many, or both. This is a review list at info severity, not a defect.

Each finding names the relationship by its two columns and its shape, as 'Sales'[Customer ID] ∞↔1 'Customer'[Customer ID]. The arrow is ↔ when the relationship filters both ways and ← when it does not, and ∞ on a side means that side is many.

Example

Fires the rule
table Sales
	column 'Customer ID'
		dataType: int64
		isHidden
		sourceColumn: CustomerID

	column Amount
		dataType: decimal
		sourceColumn: Amount

table Customer
	column 'Customer ID'
		dataType: int64
		isKey
		sourceColumn: CustomerID

	column Region
		dataType: string
		sourceColumn: Region

relationship Sales_Customer
	crossFilteringBehavior: bothDirections
	fromColumn: Sales.'Customer ID'
	toColumn: Customer.'Customer ID'
After the fix
table Sales
	column 'Customer ID'
		dataType: int64
		isHidden
		sourceColumn: CustomerID

	column Amount
		dataType: decimal
		sourceColumn: Amount

table Customer
	column 'Customer ID'
		dataType: int64
		isKey
		sourceColumn: CustomerID

	column Region
		dataType: string
		sourceColumn: Region

relationship Sales_Customer
	fromColumn: Sales.'Customer ID'
	toColumn: Customer.'Customer ID'

Why it matters

Both kinds have real uses, and both are easy to create by accident: Desktop offers bi-directional filtering as a dropdown, and it falls back to many-to-many when it finds duplicates on both sides of a key. An accidental one costs query time on every visual that touches the tables and can open a second filter path, which is where totals stop adding up without any error.

How to fix it

Look at each one and decide whether it was meant. In Power BI Desktop, open the model view, double-click the relationship, and read the Cardinality and Cross filter direction dropdowns in the Edit relationship dialog; in the TMDL file the same three facts are fromCardinality, toCardinality, and crossFilteringBehavior under the relationship. Where the direction is not wanted, set Cross filter direction to Single, which is the crossFilteringBehavior: bothDirections line deleted, and move the reverse filter into the measures that need it with CROSSFILTER. Where the cardinality is many-to-many because the key column has duplicates, that is a data problem: remove the duplicates in Power Query with Remove Duplicates, or in the source view the query reads, then set Cardinality back to Many to one. Both dropdowns behave the same on an import model and a DirectQuery one.

When to ignore it

Ignoring is the ordinary outcome for a relationship you meant to create, and this rule exists to make you say so once. A bridge table between two dimensions, a security table that has to filter upward, a slicer that has to narrow to the values a fact table actually holds: each is a deliberate design and each stays. The check worth making before you ignore one is for a second filter path between the same two tables, which the model view shows as two routes; one route is a design, two is where the totals start disagreeing. Review the list again whenever relationships are added, because a path that was unique when you approved it may not be now.

To ignore this rule on one object, add annotation pbiplint.ignore = CHECK_IF_BI-DIRECTIONAL_AND_MANY-TO-MANY_RELATIONSHIPS_ARE_VALID under the object in its TMDL file. Power BI Desktop keeps the annotation. To turn the rule off for a whole project, set "CHECK_IF_BI-DIRECTIONAL_AND_MANY-TO-MANY_RELATIONSHIPS_ARE_VALID": "off" under rules in pbiplint.config.json.

Quirks

Ported from Microsoft's Best Practice Analyzer ruleset (opens in a new tab).

Check a model for this Improve this page (opens in a new tab)