public MasterDetailCollectionMaterializer(DbCommandBuilder <TCommand, TParameter> commandBuilder, string masterKeyColumn, Func <TMaster, ICollection <TDetail> > map, CollectionOptions masterOptions, CollectionOptions detailOptions) : base(commandBuilder) { m_MasterKeyColumn = masterKeyColumn; m_Map = map; if (masterOptions.HasFlag(CollectionOptions.InferConstructor)) { m_MasterConstructor = MaterializerUtilities.InferConstructor(s_MasterMetadata); } if (detailOptions.HasFlag(CollectionOptions.InferConstructor)) { m_DetailConstructor = MaterializerUtilities.InferConstructor(s_DetailMetadata); } }
/// <summary> /// Materializers use this to pick a constructor. /// </summary> /// <returns></returns> /// <exception cref="MappingException"></exception> protected ConstructorMetadata InferConstructor() { return(MaterializerUtilities.InferConstructor(ObjectMetadata)); }
public override IReadOnlyList <string> DesiredColumns() { //We need to pick the constructor now so that we have the right columns in the SQL. //If we wait until materialization, we could have missing or extra columns. if (m_MasterConstructor == null && !s_MasterMetadata.Constructors.HasDefaultConstructor) { m_MasterConstructor = MaterializerUtilities.InferConstructor(s_MasterMetadata); } if (m_DetailConstructor == null && !s_DetailMetadata.Constructors.HasDefaultConstructor) { m_DetailConstructor = MaterializerUtilities.InferConstructor(s_DetailMetadata); } var masterColumns = (m_MasterConstructor == null) ? s_MasterMetadata.ColumnsFor : m_MasterConstructor.ParameterNames; var detailColumns = (m_DetailConstructor == null) ? s_DetailMetadata.ColumnsFor : m_DetailConstructor.ParameterNames; //Sanity checks if (m_IncludedColumns != null && m_ExcludedColumns != null) { throw new InvalidOperationException("Cannot specify both included and excluded columns/properties."); } if (m_ExcludedColumns != null && (m_MasterConstructor != null || m_DetailConstructor != null)) { throw new InvalidOperationException("Cannot specify excluded columns/properties with non-default constructors."); } if (masterColumns.Length == 0) { throw new MappingException($"Type {typeof(TMaster).Name} has no writable properties. Please use the InferConstructor option or the WithMasterConstructor method."); } if (detailColumns.Length == 0) { throw new MappingException($"Type {typeof(TDetail).Name} has no writable properties. Please use the InferConstructor option or the WithMasterConstructor method."); } //Assembly the list var columnNames = new HashSet <string>(); //using this to filter out duplicates if (m_IncludedColumns != null) { columnNames.AddRange(m_IncludedColumns); } else //Use the previously found values { columnNames.AddRange(masterColumns); columnNames.AddRange(detailColumns); if (m_ExcludedColumns != null) { foreach (var column in m_ExcludedColumns) { columnNames.Remove(column); } } } columnNames.Add(m_MasterKeyColumn); //Force this to always be included. return(columnNames.ToImmutableArray()); }