internal SqlExpression BuildProjection(SqlExpression item, MetaType rowType, bool allowDeferred, SqlLink link, Expression source) { if (!rowType.HasInheritance) { return(BuildProjectionInternal(item, rowType, (rowType.Table != null) ? rowType.PersistentDataMembers : rowType.DataMembers, allowDeferred, link, source)); } var list = new List <MetaType>(rowType.InheritanceTypes); var list2 = new List <SqlTypeCaseWhen>(); SqlTypeCaseWhen sqlTypeCaseWhen = null; var inheritanceRoot = rowType.InheritanceRoot; var discriminator = inheritanceRoot.Discriminator; var type = discriminator.Type; var sqlMember = sql.Member(item, discriminator.Member); foreach (var item2 in list) { if (item2.HasInheritanceCode) { var typeBinding = BuildProjectionInternal(item, item2, item2.PersistentDataMembers, allowDeferred, link, source); if (item2.IsInheritanceDefault) { sqlTypeCaseWhen = new SqlTypeCaseWhen(null, typeBinding); } object value = InheritanceRules.InheritanceCodeForClientCompare(item2.InheritanceCode, sqlMember.SqlType); var match = sql.Value(type, sql.Default(discriminator), value, true, source); list2.Add(new SqlTypeCaseWhen(match, typeBinding)); } } if (sqlTypeCaseWhen == null) { throw Error.EmptyCaseNotSupported(); } list2.Add(sqlTypeCaseWhen); return(sql.TypeCase(inheritanceRoot.Type, inheritanceRoot, sqlMember, list2.ToArray(), source)); }
internal SqlExpression BuildProjection(SqlExpression item, MetaType rowType, bool allowDeferred, SqlLink link, Expression source) { if (!rowType.HasInheritance) { return(this.BuildProjectionInternal(item, rowType, (rowType.Table != null) ? rowType.PersistentDataMembers : rowType.DataMembers, allowDeferred, link, source)); } else { // Build a type case that represents a switch between the various type. List <MetaType> mappedTypes = new List <MetaType>(rowType.InheritanceTypes); List <SqlTypeCaseWhen> whens = new List <SqlTypeCaseWhen>(); SqlTypeCaseWhen @else = null; MetaType root = rowType.InheritanceRoot; MetaDataMember discriminator = root.Discriminator; Type dt = discriminator.Type; SqlMember dm = sql.Member(item, discriminator.Member); foreach (MetaType type in mappedTypes) { if (type.HasInheritanceCode) { SqlNew defaultProjection = this.BuildProjectionInternal(item, type, type.PersistentDataMembers, allowDeferred, link, source); if (type.IsInheritanceDefault) { @else = new SqlTypeCaseWhen(null, defaultProjection); } // Add an explicit case even for the default. // Redundant results will be optimized out later. object code = InheritanceRules.InheritanceCodeForClientCompare(type.InheritanceCode, dm.SqlType); SqlExpression match = sql.Value(dt, sql.Default(discriminator), code, true, source); whens.Add(new SqlTypeCaseWhen(match, defaultProjection)); } } if (@else == null) { throw Error.EmptyCaseNotSupported(); } whens.Add(@else); // Add the else at the end. return(sql.TypeCase(root.Type, root, dm, whens.ToArray(), source)); } }