/// <summary> /// Get the list of "desired" propertyrefs for the specified type and operation /// </summary> /// <param name="typeInfo"></param> /// <param name="opKind"></param> /// <returns></returns> private IEnumerable<PropertyRef> GetPropertyRefs(TypeInfo typeInfo, OperationKind opKind) { PlanCompiler.Assert(opKind != OperationKind.All, "unexpected attempt to GetPropertyRefs(...,OperationKind.All)"); if (opKind == OperationKind.GetKeys) { return typeInfo.GetKeyPropertyRefs(); } else if (opKind == OperationKind.GetIdentity) { return typeInfo.GetIdentityPropertyRefs(); } else { return GetPropertyRefsForComparisonAndIsNull(typeInfo, opKind); } }
/// <summary> /// Identify the list of property refs for comparison and isnull semantics /// </summary> /// <param name="typeInfo"></param> /// <param name="opKind"></param> /// <returns></returns> private IEnumerable<PropertyRef> GetPropertyRefsForComparisonAndIsNull(TypeInfo typeInfo, OperationKind opKind) { PlanCompiler.Assert(opKind == OperationKind.IsNull || opKind == OperationKind.Equality, "Unexpected opKind: " + opKind + "; Can only handle IsNull and Equality"); md.TypeUsage currentType = typeInfo.Type; md.RowType recordType = null; if (TypeHelpers.TryGetEdmType<md.RowType>(currentType, out recordType)) { if (opKind == OperationKind.IsNull && typeInfo.HasNullSentinelProperty) { yield return NullSentinelPropertyRef.Instance; } else foreach (md.EdmProperty m in recordType.Properties) { if (!TypeUtils.IsStructuredType(md.Helper.GetModelTypeUsage(m))) { yield return new SimplePropertyRef(m); } else { TypeInfo nestedTypeInfo = m_typeInfo.GetTypeInfo(md.Helper.GetModelTypeUsage(m)); foreach (PropertyRef p in GetPropertyRefs(nestedTypeInfo, opKind)) { PropertyRef nestedPropertyRef = p.CreateNestedPropertyRef(m); yield return nestedPropertyRef; } } } yield break; } md.EntityType entityType = null; if (TypeHelpers.TryGetEdmType<md.EntityType>(currentType, out entityType)) { if (opKind == OperationKind.Equality || (opKind == OperationKind.IsNull && !typeInfo.HasTypeIdProperty)) { foreach (PropertyRef p in typeInfo.GetIdentityPropertyRefs()) { yield return p; } } else { yield return TypeIdPropertyRef.Instance; } yield break; } md.ComplexType complexType = null; if (TypeHelpers.TryGetEdmType<md.ComplexType>(currentType, out complexType)) { PlanCompiler.Assert(opKind == OperationKind.IsNull, "complex types not equality-comparable"); PlanCompiler.Assert(typeInfo.HasNullSentinelProperty, "complex type with no null sentinel property: can't handle isNull"); yield return NullSentinelPropertyRef.Instance; yield break; } md.RefType refType = null; if (TypeHelpers.TryGetEdmType<md.RefType>(currentType, out refType)) { foreach (PropertyRef p in typeInfo.GetAllPropertyRefs()) { yield return p; } yield break; } PlanCompiler.Assert(false, "Unknown type"); }