src/Shared/EntityFramework/Core/Mapping/Update/Internal/UpdateCompiler.cs
// <summary>
// Determines predicate used to identify a row in a table.
// </summary>
// <remarks>
// Columns are included in the list when:
// <list>
//     <item>They are keys for the table</item>
//     <item>They are concurrency values</item>
// </list>
// </remarks>
// <param name="target"> Expression binding representing the table containing the row </param>
// <param name="referenceRow"> Values for the row being located. </param>
// <param name="current"> Values being updated (may be null). </param>
// <param name="processor"> Context for the table containing the row. </param>
// <param name="rowMustBeTouched"> Output parameter indicating whether a row must be touched (whether it's being modified or not) because it contains a concurrency value </param>
// <returns> Column/value pairs. </returns>
Determines predicate used to identify a row in a table.
Determines predicate used to identify a row in a table .
private DbExpression BuildPredicate(
            DbExpressionBinding target, PropagatorResult referenceRow, PropagatorResult current,
            TableChangeProcessor processor, ref bool rowMustBeTouched)
        {
            var whereClauses = new Dictionary<EdmProperty, PropagatorResult>();
            var propertyOrdinal = 0;
            foreach (var member in processor.Table.ElementType.Properties)
            {
                var expectedValue = referenceRow.GetMemberValue(propertyOrdinal);
                var newValue = null == current ? null : current.GetMemberValue(propertyOrdinal);
                if (!rowMustBeTouched
                    &&
                    (HasFlag(expectedValue, PropagatorFlags.ConcurrencyValue) ||
                     HasFlag(newValue, PropagatorFlags.ConcurrencyValue)))
                {
                    rowMustBeTouched = true;
                }
                if (!whereClauses.ContainsKey(member)
                    && 
                    (HasFlag(expectedValue, PropagatorFlags.ConcurrencyValue | PropagatorFlags.Key) ||
                     HasFlag(newValue, PropagatorFlags.ConcurrencyValue | PropagatorFlags.Key))) 
                {
                    whereClauses.Add(member, expectedValue);
                }
                propertyOrdinal++;
            }
            DbExpression predicate = null;
            foreach (var clause in whereClauses)
            {
                var clauseExpression = GenerateEqualityExpression(target, clause.Key, clause.Value);
                if (null == predicate)
                {
                    predicate = clauseExpression;
                }
                else
                {
                    predicate = predicate.And(clauseExpression);
                }
            }
            Debug.Assert(null != predicate, "some predicate term must exist");
            return predicate;
        }
private DbExpression BuildPredicate ( DbExpressionBinding target , PropagatorResult referenceRow , PropagatorResult current , TableChangeProcessor processor , ref bool rowMustBeTouched ) { var whereClauses = new Dictionary < EdmProperty , PropagatorResult > ( ) ; var propertyOrdinal = 0 ; foreach ( var member in processor . Table . ElementType . Properties ) { var expectedValue = referenceRow . GetMemberValue ( propertyOrdinal ) ; var newValue = null == current ? null : current . GetMemberValue ( propertyOrdinal ) ; if ( ! rowMustBeTouched && ( HasFlag ( expectedValue , PropagatorFlags . ConcurrencyValue ) || HasFlag ( newValue , PropagatorFlags . ConcurrencyValue ) ) ) { rowMustBeTouched = true ; } if ( ! whereClauses . ContainsKey ( member ) && ( HasFlag ( expectedValue , PropagatorFlags . ConcurrencyValue | PropagatorFlags . Key ) || HasFlag ( newValue , PropagatorFlags . ConcurrencyValue | PropagatorFlags . Key ) ) ) { whereClauses . Add ( member , expectedValue ) ; } propertyOrdinal ++ ; } DbExpression predicate = null ; foreach ( var clause in whereClauses ) { var clauseExpression = GenerateEqualityExpression ( target , clause . Key , clause . Value ) ; if ( null == predicate ) { predicate = clauseExpression ; } else { predicate = predicate . And ( clauseExpression ) ; } } Debug . Assert ( null != predicate , " " ) ; return predicate ; }
Determines predicate used to identify a row in a table.
Determines predicate used to identify a row in a table .
// add all concurrency tokens (note that keys are always concurrency tokens as well) // members and result values are ordinally aligned // check if the rowMustBeTouched value should be set to true (if it isn't already // true and we've come across a concurrency value) // determine if this is a concurrency value // don't add to the set clause twice // tagged as concurrency value // Build a binary AND expression tree from the clauses
None
target
DbExpressionBinding
Expression binding representing the table containing the row
Expression binding representing the table containing the row
referenceRow
PropagatorResult
Values for the row being located.
Values for the row being located .
current
PropagatorResult
Values being updated (may be null).
Values being updated ( may be null ) .
processor
TableChangeProcessor
Context for the table containing the row.
Context for the table containing the row .
bool
ref
rowMustBeTouched
Output parameter indicating whether a row must be touched (whether it's being modified or not) because it contains a concurrency value
Output parameter indicating whether a row must be touched ( whether it ' s being modified or not ) because it contains a concurrency value
remarks
Columns are included in the list when.

They are keys for the tableThey are concurrency values
Columns are included in the list when . They are keys for the tableThey are concurrency values