├── .gitattributes ├── .gitignore ├── LICENSE.txt ├── PATENTS.txt ├── README.md ├── src ├── BindingLists │ ├── BindingList.cs │ ├── DataBindingList.cs │ ├── EntitySetDataBindingList.cs │ └── SortableBindingList.cs ├── ChangeManagement │ ├── ChangeConflictCollection.cs │ ├── ChangeConflictSession.cs │ ├── ChangeDirector.cs │ ├── ChangeProcessor.cs │ ├── ChangeSet.cs │ ├── ChangeTracker.cs │ ├── DataManipulation.cs │ ├── MemberChangeConflict.cs │ ├── ModifiedMemberInfo.cs │ ├── ObjectChangeConflict.cs │ ├── ReadOnlyChangeTracker.cs │ ├── RelatedItem.cs │ ├── StandardChangeDirector.cs │ ├── StandardChangeTracker.cs │ └── TrackedObject.cs ├── ConstantsEnums.cs ├── DbEngines │ └── SqlServer │ │ ├── CommandTextProducer.cs │ │ ├── ConstantsEnums.cs │ │ ├── LongTypeConverter.cs │ │ ├── PostBindDotNetConverter.cs │ │ ├── Sql2000Provider.cs │ │ ├── Sql2005Provider.cs │ │ ├── Sql2008Provider.cs │ │ ├── SqlBooleanizer.cs │ │ ├── SqlBuilder.cs │ │ ├── SqlCEProvider.cs │ │ ├── SqlConnectionManager.cs │ │ ├── SqlFactory.cs │ │ ├── SqlFormatter.cs │ │ ├── SqlHelpers.cs │ │ ├── SqlMethods.cs │ │ ├── SqlParameterInfoProducer.cs │ │ ├── SqlParameterizer.cs │ │ ├── SqlProvider.cs │ │ ├── SqlServerProviderBase.cs │ │ ├── SqlTopReducer.cs │ │ ├── SqlType.cs │ │ ├── SqlTypeConverter.cs │ │ └── SqlTypeSystem.cs ├── Error.cs ├── Exceptions │ ├── ChangeConflictException.cs │ ├── DuplicateKeyException.cs │ └── ForeignKeyReferenceAlreadyHasValueException.cs ├── GlobalSuppressions.cs ├── IdentityMangement │ ├── IdentityCache.cs │ ├── IdentityCacheOfTK.cs │ ├── IdentityManager.cs │ ├── KeyManager.cs │ ├── KeyManagerOfTK.cs │ ├── MultiKey.cs │ ├── MultiKeyManager.cs │ ├── SingleKeyManager.cs │ └── StandardIdentityManager.cs ├── Interfaces │ ├── ICompiledQuery.cs │ ├── IDataServices.cs │ ├── IDeferredSourceFactory.cs │ ├── IExecuteResult.cs │ ├── IFunctionResult.cs │ ├── IMultipleResults.cs │ ├── IProvider.cs │ ├── ISingleResult.cs │ ├── ITable.cs │ └── ITableOfT.cs ├── Mapping │ ├── Accesssors │ │ ├── Delegates.cs │ │ ├── EntityRefDefSourceAccessor.cs │ │ ├── EntityRefDefValueAccessor.cs │ │ ├── EntityRefValueAccessor.cs │ │ ├── EntitySetDefSourceAccessor.cs │ │ ├── EntitySetDefValueAccessor.cs │ │ ├── EntitySetValueAccessor.cs │ │ ├── FieldAccessor.cs │ │ ├── LinkDefSourceAccessor.cs │ │ ├── LinkDefValueAccessor.cs │ │ ├── LinkValueAccessor.cs │ │ └── PropertyAccessor.cs │ ├── AttributedMetaModel │ │ ├── AttributedMetaAssociation.cs │ │ ├── AttributedMetaDataMember.cs │ │ ├── AttributedMetaFunction.cs │ │ ├── AttributedMetaModel.cs │ │ ├── AttributedMetaParameter.cs │ │ ├── AttributedMetaTable.cs │ │ ├── AttributedMetaType.cs │ │ ├── AttributedRootType.cs │ │ ├── InheritanceBaseFinder.cs │ │ └── MethodFinder.cs │ ├── Attributes.cs │ ├── ConstantsEnums.cs │ ├── DbmlShared │ │ ├── AssociationMapping.cs │ │ ├── ColumnMapping.cs │ │ ├── DatabaseMapping.cs │ │ ├── FunctionMapping.cs │ │ ├── MappingSystem.cs │ │ ├── MemberMapping.cs │ │ ├── ParameterMapping.cs │ │ ├── ReturnMapping.cs │ │ ├── TableMapping.cs │ │ ├── TypeMapping.cs │ │ └── XmlMappingConstant.cs │ ├── EntityRef.cs │ ├── EntitySet.cs │ ├── ItemList.cs │ ├── Link.cs │ ├── MappedMetaModel │ │ ├── MappedAssociation.cs │ │ ├── MappedDataMember.cs │ │ ├── MappedFunction.cs │ │ ├── MappedMetaModel.cs │ │ ├── MappedParameter.cs │ │ ├── MappedReturnParameter.cs │ │ ├── MappedRootType.cs │ │ ├── MappedTable.cs │ │ ├── MappedType.cs │ │ ├── MetaAssociationImpl.cs │ │ ├── UnmappedDataMember.cs │ │ └── UnmappedType.cs │ ├── MappingSource │ │ ├── AttributeMappingSource.cs │ │ ├── MappingSource.cs │ │ ├── XmlMappingReader.cs │ │ └── XmlMappingSource.cs │ ├── MetaModel │ │ ├── MetaAccessor.cs │ │ ├── MetaAccessor1.cs │ │ ├── MetaAssociation.cs │ │ ├── MetaDataMember.cs │ │ ├── MetaFunction.cs │ │ ├── MetaModel.cs │ │ ├── MetaParameter.cs │ │ ├── MetaTable.cs │ │ └── MetaType.cs │ ├── SourceState.cs │ └── Table.cs ├── Miscellaneous │ ├── DbConvert.cs │ └── SecurityUtils.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Main.Designer.cs │ └── Main.resx ├── Provider │ ├── Common │ │ ├── BigJoinChecker.cs │ │ ├── ColumnNominator.cs │ │ ├── CompatibilityAnnotation.cs │ │ ├── CompatibilityCheck.cs │ │ ├── CompiledQuery.cs │ │ ├── CompiledSubQuery.cs │ │ ├── ConnectionManager.cs │ │ ├── DbFormatter.cs │ │ ├── DynamicTypeGenerator.cs │ │ ├── ExecuteResult.cs │ │ ├── Group.cs │ │ ├── HierarchyChecker.cs │ │ ├── InheritanceRules.cs │ │ ├── LinkOptimizationScope.cs │ │ ├── MetaPosition.cs │ │ ├── MultipleResults.cs │ │ ├── MultisetChecker.cs │ │ ├── NamedColumn.cs │ │ ├── NodeFactory.cs │ │ ├── ObjectMaterializer.cs │ │ ├── ObjectReader.cs │ │ ├── ObjectReaderBase.cs │ │ ├── ObjectReaderCompiler.cs │ │ ├── ObjectReaderFactory.cs │ │ ├── ObjectReaderFactoryCache.cs │ │ ├── ObjectReaderSession.cs │ │ ├── OneTimeEnumerable.cs │ │ ├── OrderedResults.cs │ │ ├── ProviderType.cs │ │ ├── QueryConverter.cs │ │ ├── QueryExtractor.cs │ │ ├── QueryInfo.cs │ │ ├── Rereader.cs │ │ ├── SequenceOfOne.cs │ │ ├── SingleResult.cs │ │ ├── SqlAliasDependencyChecker.cs │ │ ├── SqlAliasesReferenced.cs │ │ ├── SqlBinder.cs │ │ ├── SqlCaseSimplifier.cs │ │ ├── SqlColumnizer.cs │ │ ├── SqlComparer.cs │ │ ├── SqlCrossApplyToCrossJoin.cs │ │ ├── SqlDeflator.cs │ │ ├── SqlDuplicator.cs │ │ ├── SqlExpander.cs │ │ ├── SqlExpressionNullability.cs │ │ ├── SqlFlattener.cs │ │ ├── SqlGatherColumnsProduced.cs │ │ ├── SqlGatherConsumedAliases.cs │ │ ├── SqlGatherProducedAliases.cs │ │ ├── SqlGatherReferencedColumns.cs │ │ ├── SqlIdentifier.cs │ │ ├── SqlLiftIndependentRowExpressions.cs │ │ ├── SqlLiftWhereClauses.cs │ │ ├── SqlMultiplexer.cs │ │ ├── SqlNamer.cs │ │ ├── SqlNodeAnnotation.cs │ │ ├── SqlNodeAnnotations.cs │ │ ├── SqlNodeTypeOperators.cs │ │ ├── SqlOuterApplyReducer.cs │ │ ├── SqlParameterInfo.cs │ │ ├── SqlPredicateLifter.cs │ │ ├── SqlProjectionComparer.cs │ │ ├── SqlRemoveConstantOrderBy.cs │ │ ├── SqlReorderer.cs │ │ ├── SqlResolver.cs │ │ ├── SqlRetyper.cs │ │ ├── SqlRewriteScalarSubqueries.cs │ │ ├── SqlScope.cs │ │ ├── SqlSelectionLifter.cs │ │ ├── SqlUnionizer.cs │ │ ├── Translator.cs │ │ ├── TypeSource.cs │ │ ├── TypeSystem.cs │ │ ├── TypeSystemProvider.cs │ │ └── WhereClauseLifter.cs │ ├── Expressions │ │ ├── InternalExpression.cs │ │ ├── KnownExpression.cs │ │ └── LinkedTableExpression.cs │ ├── Interfaces │ │ ├── ICompiledSubQuery.cs │ │ ├── IConnectionManager.cs │ │ ├── IConnectionUser.cs │ │ ├── IObjectReader.cs │ │ ├── IObjectReaderCompiler.cs │ │ ├── IObjectReaderFactory.cs │ │ ├── IObjectReaderSession.cs │ │ └── IReaderProvider.cs │ ├── NodeTypes │ │ ├── SqlAlias.cs │ │ ├── SqlAliasRef.cs │ │ ├── SqlAssign.cs │ │ ├── SqlBetween.cs │ │ ├── SqlBinary.cs │ │ ├── SqlBlock.cs │ │ ├── SqlClientArray.cs │ │ ├── SqlClientCase.cs │ │ ├── SqlClientParameter.cs │ │ ├── SqlClientQuery.cs │ │ ├── SqlClientWhen.cs │ │ ├── SqlColumn.cs │ │ ├── SqlColumnRef.cs │ │ ├── SqlDelete.cs │ │ ├── SqlDiscriminatedType.cs │ │ ├── SqlDiscriminatorOf.cs │ │ ├── SqlDoNotVisitExpression.cs │ │ ├── SqlExprSet.cs │ │ ├── SqlExpression.cs │ │ ├── SqlFunctionCall.cs │ │ ├── SqlGrouping.cs │ │ ├── SqlIn.cs │ │ ├── SqlIncludeScope.cs │ │ ├── SqlInsert.cs │ │ ├── SqlJoin.cs │ │ ├── SqlJoinedCollection.cs │ │ ├── SqlLift.cs │ │ ├── SqlLike.cs │ │ ├── SqlLink.cs │ │ ├── SqlMember.cs │ │ ├── SqlMemberAssign.cs │ │ ├── SqlMethodCall.cs │ │ ├── SqlNew.cs │ │ ├── SqlNode.cs │ │ ├── SqlNop.cs │ │ ├── SqlOptionalValue.cs │ │ ├── SqlOrderExpression.cs │ │ ├── SqlParameter.cs │ │ ├── SqlRow.cs │ │ ├── SqlRowNumber.cs │ │ ├── SqlSearchedCase.cs │ │ ├── SqlSelect.cs │ │ ├── SqlSharedExpression.cs │ │ ├── SqlSharedExpressionRef.cs │ │ ├── SqlSimpleCase.cs │ │ ├── SqlSimpleExpression.cs │ │ ├── SqlSimpleTypeExpression.cs │ │ ├── SqlSource.cs │ │ ├── SqlStatement.cs │ │ ├── SqlStoredProcedureCall.cs │ │ ├── SqlSubSelect.cs │ │ ├── SqlTable.cs │ │ ├── SqlTableValuedFunctionCall.cs │ │ ├── SqlTypeCase.cs │ │ ├── SqlTypeCaseWhen.cs │ │ ├── SqlUnary.cs │ │ ├── SqlUnion.cs │ │ ├── SqlUpdate.cs │ │ ├── SqlUserColumn.cs │ │ ├── SqlUserQuery.cs │ │ ├── SqlUserRow.cs │ │ ├── SqlValue.cs │ │ ├── SqlVariable.cs │ │ └── SqlWhen.cs │ └── Visitors │ │ ├── AliasDependencyChecker.cs │ │ ├── AliasMapper.cs │ │ ├── Booleanizer.cs │ │ ├── CaseSimplifier.cs │ │ ├── ColumnDeclarer.cs │ │ ├── ColumnLifter.cs │ │ ├── ColumnNameGatherer.cs │ │ ├── ColumnTypeValidator.cs │ │ ├── ConstantInOrderByRemover.cs │ │ ├── ConsumedAliaseGatherer.cs │ │ ├── ContainsRowNumberChecker.cs │ │ ├── DependenceChecker.cs │ │ ├── DuplicatingVisitor.cs │ │ ├── ExpectNoAliasRefs.cs │ │ ├── ExpectNoFloatingColumns.cs │ │ ├── ExpectNoMethodCalls.cs │ │ ├── ExpectNoSharedExpressions.cs │ │ ├── ExpectRationalizedBooleans.cs │ │ ├── ExpressionDuplicator.cs │ │ ├── ExpressionVisitor.cs │ │ ├── Funcletizer.cs │ │ ├── LiteralValidator.cs │ │ ├── LocalMapper.cs │ │ ├── Localizer.cs │ │ ├── MemberAccessBinder.cs │ │ ├── MethodCallConverter.cs │ │ ├── MultiSetDetector.cs │ │ ├── MultiSetMultiPlexer.cs │ │ ├── NameAssigner.cs │ │ ├── ObjectExpressionFlattener.cs │ │ ├── OrderByLifter.cs │ │ ├── PredicateLifter.cs │ │ ├── ProducedAliasGatherer.cs │ │ ├── ProducedColumnsGatherer.cs │ │ ├── QueryHierarchyFinder.cs │ │ ├── QueryUnionizer.cs │ │ ├── RelationComposer.cs │ │ ├── ScalarSubQueryRewriter.cs │ │ ├── SelectionFlattener.cs │ │ ├── SelectionLifter.cs │ │ ├── SideEffectChecker.cs │ │ ├── SimpleExpression.cs │ │ ├── SingleTableQueryVisitor.cs │ │ ├── SourceExpressionRemover.cs │ │ ├── SqlAggregateChecker.cs │ │ ├── SqlAliasDeflator.cs │ │ ├── SqlAliaser.cs │ │ ├── SqlAliasesReferenced.cs │ │ ├── SqlBooleanMismatchVisitor.cs │ │ ├── SqlBubbler.cs │ │ ├── SqlColumnDeflator.cs │ │ ├── SqlColumnEqualizer.cs │ │ ├── SqlDuplicateColumnDeflator.cs │ │ ├── SqlMethodTransformer.cs │ │ ├── SqlScopedVisitor.cs │ │ ├── SqlSelectionSkipper.cs │ │ ├── SqlSupersetValidator.cs │ │ ├── SqlTopSelectDeflator.cs │ │ ├── SqlValueDeflator.cs │ │ ├── SqlVisitor.cs │ │ ├── SubQueryCompiler.cs │ │ ├── SubSelectDuplicator.cs │ │ ├── SubqueryValidator.cs │ │ ├── TypeCorrector.cs │ │ └── ValidateNoInvalidComparison.cs ├── Querying │ ├── CompiledQuery.cs │ ├── DataContext.cs │ ├── DataLoadOptions.cs │ ├── DataQuery.cs │ ├── DataServices.cs │ └── SubqueryRules.cs ├── SD.Tools.LinqToDB.snk ├── SD.Tools.LinqToSQL2.csproj ├── SD.Tools.LinqToSQL2.sln ├── SR.cs ├── Strings.cs └── Types │ └── Binary.cs └── tests ├── AdventureWorks2008Model ├── AdventureWorks2008.csproj ├── AdventureWorks2008DataContext.cs ├── AdventureWorks2008Mappings.xml ├── App.config ├── EntityClasses │ ├── Address.cs │ ├── AddressType.cs │ ├── AwbuildVersion.cs │ ├── BillOfMaterial.cs │ ├── BusinessEntity.cs │ ├── BusinessEntityAddress.cs │ ├── BusinessEntityContact.cs │ ├── ContactType.cs │ ├── CountryRegion.cs │ ├── CountryRegionCurrency.cs │ ├── CreditCard.cs │ ├── Culture.cs │ ├── Currency.cs │ ├── CurrencyRate.cs │ ├── Customer.cs │ ├── DatabaseLog.cs │ ├── Department.cs │ ├── Document.cs │ ├── EmailAddress.cs │ ├── Employee.cs │ ├── EmployeeDepartmentHistory.cs │ ├── EmployeePayHistory.cs │ ├── ErrorLog.cs │ ├── Illustration.cs │ ├── JobCandidate.cs │ ├── Location.cs │ ├── Password.cs │ ├── Person.cs │ ├── PersonCreditCard.cs │ ├── PersonPhone.cs │ ├── PhoneNumberType.cs │ ├── Product.cs │ ├── ProductCategory.cs │ ├── ProductCostHistory.cs │ ├── ProductDescription.cs │ ├── ProductDocument.cs │ ├── ProductInventory.cs │ ├── ProductListPriceHistory.cs │ ├── ProductModel.cs │ ├── ProductModelIllustration.cs │ ├── ProductModelProductDescriptionCulture.cs │ ├── ProductPhoto.cs │ ├── ProductProductPhoto.cs │ ├── ProductReview.cs │ ├── ProductSubcategory.cs │ ├── ProductVendor.cs │ ├── PurchaseOrderDetail.cs │ ├── PurchaseOrderHeader.cs │ ├── SalesOrderDetail.cs │ ├── SalesOrderHeader.cs │ ├── SalesOrderHeaderSalesReason.cs │ ├── SalesPerson.cs │ ├── SalesPersonQuotaHistory.cs │ ├── SalesReason.cs │ ├── SalesTaxRate.cs │ ├── SalesTerritory.cs │ ├── SalesTerritoryHistory.cs │ ├── ScrapReason.cs │ ├── Shift.cs │ ├── ShipMethod.cs │ ├── ShoppingCartItem.cs │ ├── SpecialOffer.cs │ ├── SpecialOfferProduct.cs │ ├── StateProvince.cs │ ├── Store.cs │ ├── TransactionHistory.cs │ ├── TransactionHistoryArchive.cs │ ├── UnitMeasure.cs │ ├── Vendor.cs │ ├── WorkOrder.cs │ └── WorkOrderRouting.cs ├── Properties │ └── AssemblyInfo.cs ├── SqlServerTypes │ ├── Loader.cs │ └── readme.htm ├── TypedViewClasses │ ├── BillOfRightsResultTypedViewRow.cs │ └── UfnGetContactInformationResultTypedViewRow.cs └── packages.config ├── GenerateTestCode.cmd ├── LinqToSql2Tests.sln ├── ReadWriteTests ├── App.config ├── ConstantsEnums.cs ├── EntityCreator.cs ├── Pair.cs ├── Properties │ └── AssemblyInfo.cs ├── ReadTestsAdventureWorks.cs ├── ReadWriteTests.csproj ├── WriteTests.cs └── packages.config ├── SourceProjects ├── AdventureWorks2008.llblgenproj ├── DDLSQL_CreateScript_WriteTestDB.sql ├── ReadTestsNorthwind.llblgenproj ├── WriteTests.llblgenproj ├── WriteTests.llblgenproj.typeimports ├── log_AdventureWorks2008.txt └── log_WriteTests.txt └── WriteTestsModel ├── App.config ├── EntityClasses ├── Address.cs ├── AddressDuplicateFields.cs ├── AddressSimple.cs ├── Ball.cs ├── BallColor.cs ├── Color.cs ├── Company.cs ├── CompanyProperty.cs ├── Customer.cs ├── DerivedType1.cs ├── DerivedType2.cs ├── Employee.cs ├── EnumTester.cs ├── GuidTpehTester.cs ├── Order.cs ├── OrderRow.cs ├── Product.cs ├── SpecialCustomer.cs ├── SpecialProduct.cs ├── SplitOffBlobData.cs └── SplitOffNoBlobData.cs ├── Properties └── AssemblyInfo.cs ├── TypedListClasses ├── AddressCustomerSpecialCustomerTypedListRow.cs ├── OrderCustomerTypedListRow.cs ├── Product_TypedListRow.cs └── SpecialCustomerCustomerAddressTypedListRow.cs ├── WriteTests.csproj ├── WriteTestsDataContext.cs ├── WriteTestsMappings.xml └── WriteTestsModel.csproj /PATENTS.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FransBouma/LinqToSQL2/6928cd728095dc7e03a8ec23f75a83d912acc780/PATENTS.txt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Linq To SQL2 2 | ============= 3 | 4 | Official Linq to SQL fork. A complete ORM which is backwards compatible with Linq to SQL but with new features. Please see the [Wiki](https://github.com/FransBouma/LinqToSQL2/wiki) for further information about the progress and design decisions made in this project. For the roadmap/features which are planned, please see the [issues section](https://github.com/FransBouma/LinqToSQL2/issues) for the work items. 5 | 6 | There's no official release yet, as this project has just been started. After every new feature successfully added to the codebase, a new version will be released on Nuget. 7 | 8 | ## Does the code in 'Trunk' compile? 9 | 10 | (No CI system setup (yet), so we'll have to do with the manually written elements below) 11 | 12 | It compiles, tests succeed, but the code will be changed a lot internally before the initial compiled release (especially for #6). 13 | 14 | ## Linq to SQL and this project 15 | 16 | This project is an official fork from Linq to SQL from the [.NET reference sourcecode](https://github.com/Microsoft/referencesource). As the reference source for .NET doesn't come in compilable form, the resource files for the error strings have been reverse engineered from the official System.Data.Linq assembly. 17 | 18 | This project strives to stay 100% backwards compatible with Linq to SQL's query API, so your original Linq to SQL projects will just work with Linq to SQL 2, unless stated otherwise. 19 | 20 | ### License 21 | 22 | The original Linq to SQL code is (c) Microsoft Corporation (see License.txt). Additional code added is (c) by the contributors and is marked as such in the code files. 23 | 24 | ### Designer support 25 | 26 | This project will offer designer support through [LLBLGen Pro](http://www.llblgen.com) 27 | 28 | -------------------------------------------------------------------------------- /src/BindingLists/BindingList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Data.Linq.Mapping; 6 | using System.Reflection; 7 | using System.Runtime.CompilerServices; 8 | 9 | namespace System.Data.Linq.BindingLists 10 | { 11 | internal static class BindingList 12 | { 13 | [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] 14 | internal static IBindingList Create(DataContext context, IEnumerable sequence) 15 | { 16 | List list = sequence.ToList(); 17 | MetaTable metaTable = context.Services.Model.GetTable(typeof(T)); 18 | if(metaTable != null) 19 | { 20 | ITable table = context.GetTable(metaTable.RowType.Type); 21 | Type bindingType = typeof(DataBindingList<>).MakeGenericType(metaTable.RowType.Type); 22 | return (IBindingList)Activator.CreateInstance(bindingType, 23 | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, 24 | new object[] { list, table }, null 25 | ); 26 | } 27 | else 28 | { 29 | return new SortableBindingList(list); 30 | } 31 | } 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/ChangeManagement/ChangeConflictSession.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | using System.Text; 6 | using System.Reflection; 7 | using System.Linq; 8 | using System.Diagnostics; 9 | 10 | namespace System.Data.Linq 11 | { 12 | using System.Data.Linq.Mapping; 13 | using Linq; 14 | using System.Diagnostics.CodeAnalysis; 15 | 16 | internal sealed class ChangeConflictSession 17 | { 18 | private DataContext context; 19 | private DataContext refreshContext; 20 | 21 | internal ChangeConflictSession(DataContext context) 22 | { 23 | this.context = context; 24 | } 25 | 26 | internal DataContext Context 27 | { 28 | get { return this.context; } 29 | } 30 | 31 | internal DataContext RefreshContext 32 | { 33 | get 34 | { 35 | if(this.refreshContext == null) 36 | { 37 | this.refreshContext = this.context.CreateRefreshContext(); 38 | } 39 | return this.refreshContext; 40 | } 41 | } 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/ChangeManagement/ChangeDirector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq.Expressions; 5 | using System.Text; 6 | using System.Reflection; 7 | using System.Linq; 8 | using System.Security.Permissions; 9 | using System.Security; 10 | 11 | namespace System.Data.Linq { 12 | using System.Data.Linq.Mapping; 13 | using Linq; 14 | using System.Diagnostics.CodeAnalysis; 15 | 16 | 17 | /// 18 | /// Controls how inserts, updates and deletes are performed. 19 | /// 20 | internal abstract class ChangeDirector { 21 | internal abstract int Insert(TrackedObject item); 22 | internal abstract int DynamicInsert(TrackedObject item); 23 | internal abstract void AppendInsertText(TrackedObject item, StringBuilder appendTo); 24 | 25 | internal abstract int Update(TrackedObject item); 26 | internal abstract int DynamicUpdate(TrackedObject item); 27 | internal abstract void AppendUpdateText(TrackedObject item, StringBuilder appendTo); 28 | 29 | internal abstract int Delete(TrackedObject item); 30 | internal abstract int DynamicDelete(TrackedObject item); 31 | internal abstract void AppendDeleteText(TrackedObject item, StringBuilder appendTo); 32 | 33 | internal abstract void RollbackAutoSync(); 34 | internal abstract void ClearAutoSyncRollback(); 35 | 36 | internal static ChangeDirector CreateChangeDirector(DataContext context) { 37 | return new StandardChangeDirector(context); 38 | } 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/ChangeManagement/ChangeTracker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Text; 8 | 9 | namespace System.Data.Linq 10 | { 11 | using System.Data.Linq.Mapping; 12 | using Linq; 13 | 14 | internal abstract class ChangeTracker 15 | { 16 | /// 17 | /// Starts tracking an object as 'unchanged' 18 | /// 19 | /// 20 | /// 21 | internal abstract TrackedObject Track(object obj); 22 | /// 23 | /// Starts tracking an object as 'unchanged', and optionally 24 | /// 'weakly' tracks all other referenced objects recursively. 25 | /// 26 | /// 27 | /// True if all untracked objects in the graph 28 | /// should be tracked recursively. 29 | /// 30 | internal abstract TrackedObject Track(object obj, bool recurse); 31 | /// 32 | /// Fast-tracks an object that is already in identity cache 33 | /// 34 | /// 35 | internal abstract void FastTrack(object obj); 36 | internal abstract bool IsTracked(object obj); 37 | internal abstract TrackedObject GetTrackedObject(object obj); 38 | internal abstract void StopTracking(object obj); 39 | internal abstract void AcceptChanges(); 40 | internal abstract IEnumerable GetInterestingObjects(); 41 | 42 | internal static ChangeTracker CreateChangeTracker(CommonDataServices dataServices, bool asReadOnly) 43 | { 44 | if(asReadOnly) 45 | { 46 | return new ReadOnlyChangeTracker(); 47 | } 48 | else 49 | { 50 | return new StandardChangeTracker(dataServices); 51 | } 52 | } 53 | 54 | } 55 | } -------------------------------------------------------------------------------- /src/ChangeManagement/ModifiedMemberInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | using System.ComponentModel; 6 | using System.Configuration; 7 | using System.Data; 8 | using System.Data.Common; 9 | using System.Globalization; 10 | using System.IO; 11 | using System.Linq; 12 | using System.Linq.Expressions; 13 | using System.Reflection; 14 | using System.Text; 15 | using System.Transactions; 16 | using System.Xml; 17 | using System.Runtime.CompilerServices; 18 | 19 | namespace System.Data.Linq 20 | { 21 | using System.Data.Linq.Mapping; 22 | using Linq; 23 | using System.Diagnostics.CodeAnalysis; 24 | using System.Data.Linq.BindingLists; 25 | 26 | [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes", Justification = "[....]: Types are never compared to each other. When comparisons happen it is against the entities that are represented by these constructs.")] 27 | public struct ModifiedMemberInfo 28 | { 29 | MemberInfo member; 30 | object current; 31 | object original; 32 | 33 | internal ModifiedMemberInfo(MemberInfo member, object current, object original) 34 | { 35 | this.member = member; 36 | this.current = current; 37 | this.original = original; 38 | } 39 | 40 | public MemberInfo Member 41 | { 42 | get { return this.member; } 43 | } 44 | 45 | public object CurrentValue 46 | { 47 | get { return this.current; } 48 | } 49 | 50 | public object OriginalValue 51 | { 52 | get { return this.original; } 53 | } 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /src/ChangeManagement/ReadOnlyChangeTracker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Text; 8 | 9 | namespace System.Data.Linq 10 | { 11 | using System.Data.Linq.Mapping; 12 | using Linq; 13 | 14 | /// 15 | /// This is the implementation used when change tracking is disabled. 16 | /// 17 | internal class ReadOnlyChangeTracker : ChangeTracker 18 | { 19 | internal override TrackedObject Track(object obj) { return null; } 20 | internal override TrackedObject Track(object obj, bool recurse) { return null; } 21 | internal override void FastTrack(object obj) 22 | { 23 | // nop 24 | } 25 | internal override bool IsTracked(object obj) { return false; } 26 | internal override TrackedObject GetTrackedObject(object obj) { return null; } 27 | internal override void StopTracking(object obj) { } 28 | internal override void AcceptChanges() 29 | { 30 | // nop 31 | } 32 | internal override IEnumerable GetInterestingObjects() { return new TrackedObject[0]; } 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/ChangeManagement/RelatedItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | using System.Linq.Expressions; 6 | using System.Reflection; 7 | using System.Text; 8 | using System.Linq; 9 | using System.Runtime.CompilerServices; 10 | 11 | namespace System.Data.Linq 12 | { 13 | using System.Data.Linq.Mapping; 14 | using Linq; 15 | 16 | internal struct RelatedItem 17 | { 18 | internal MetaType Type; 19 | internal object Item; 20 | internal RelatedItem(MetaType type, object item) 21 | { 22 | this.Type = type; 23 | this.Item = item; 24 | } 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/DbEngines/SqlServer/Sql2008Provider.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Diagnostics.CodeAnalysis; 3 | 4 | namespace System.Data.Linq.DbEngines.SqlServer 5 | { 6 | internal class Sql2008Provider : Sql2005Provider 7 | { 8 | [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")] 9 | internal override ProviderType From(Type type, int? size) 10 | { 11 | if(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) 12 | type = type.GetGenericArguments()[0]; 13 | 14 | // Retain mappings for DateTime and TimeSpan; add one for the new DateTimeOffset type. 15 | // 16 | if(System.Type.GetTypeCode(type) == TypeCode.Object && 17 | type == typeof(DateTimeOffset)) 18 | { 19 | return SqlTypeSystem.Create(SqlDbType.DateTimeOffset); 20 | } 21 | 22 | return base.From(type, size); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/DbEngines/SqlServer/SqlBooleanizer.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Mapping; 2 | using System.Data.Linq.Provider.Common; 3 | using System.Data.Linq.Provider.NodeTypes; 4 | using System.Data.Linq.Provider.Visitors; 5 | 6 | namespace System.Data.Linq.DbEngines.SqlServer { 7 | 8 | /// 9 | /// Locate cases in which there is a 'Bit' but a 'Predicate' is expected or vice-versa. 10 | /// Transform these expressions into expressions of the expected type. 11 | /// 12 | internal class SqlBooleanizer { 13 | /// 14 | /// Rationalize boolean expressions for the given node. 15 | /// 16 | internal static SqlNode Rationalize(SqlNode node, TypeSystemProvider typeProvider, MetaModel model) { 17 | return new Booleanizer(new SqlFactory(typeProvider, model)).Visit(node); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/DbEngines/SqlServer/SqlCEProvider.cs: -------------------------------------------------------------------------------- 1 | namespace System.Data.Linq.DbEngines.SqlServer 2 | { 3 | internal class SqlCEProvider : Sql2000Provider 4 | { 5 | #warning [FB] REFACTOR Might be removed, CE has been discontinued by MS. 6 | } 7 | } -------------------------------------------------------------------------------- /src/DbEngines/SqlServer/SqlFormatter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.Common; 3 | using System.Data.Linq.Provider.NodeTypes; 4 | 5 | namespace System.Data.Linq.DbEngines.SqlServer 6 | { 7 | /// 8 | /// Class which produces SQL fragments for SqlNode instances. 9 | /// 10 | internal class SqlFormatter : DbFormatter 11 | { 12 | #warning REFACTOR. Introduce interface for CommandTextProducer to make it not tied to a specific DB. 13 | 14 | #region Member Declarations 15 | private CommandTextProducer _commandTextProducer; 16 | #endregion 17 | 18 | internal SqlFormatter() 19 | { 20 | this._commandTextProducer = new CommandTextProducer(); 21 | } 22 | 23 | internal override string Format(SqlNode node, bool isDebug) 24 | { 25 | return this._commandTextProducer.Format(node, isDebug); 26 | } 27 | 28 | internal string[] FormatBlock(SqlBlock block, bool isDebug) 29 | { 30 | List results = new List(block.Statements.Count); 31 | for(int i = 0, n = block.Statements.Count; i < n; i++) 32 | { 33 | SqlStatement stmt = block.Statements[i]; 34 | SqlSelect select = stmt as SqlSelect; 35 | if(select != null && select.DoNotOutput) 36 | { 37 | continue; 38 | } 39 | results.Add(this.Format(stmt, isDebug)); 40 | } 41 | return results.ToArray(); 42 | } 43 | 44 | internal override string Format(SqlNode node) 45 | { 46 | return this._commandTextProducer.Format(node); 47 | } 48 | 49 | internal bool ParenthesizeTop 50 | { 51 | get { return this._commandTextProducer.ParenthesizeTop; } 52 | set { this._commandTextProducer.ParenthesizeTop = value; } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/DbEngines/SqlServer/SqlTopReducer.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | using System.Data.Linq.Provider.Visitors; 4 | 5 | namespace System.Data.Linq.DbEngines.SqlServer 6 | { 7 | /// 8 | /// REduces TOP to literal value if required. 9 | /// 10 | internal class SqlTopReducer 11 | { 12 | #region Private Classes 13 | private class Visitor : SqlVisitor 14 | { 15 | SqlNodeAnnotations annotations; 16 | NodeFactory sql; 17 | 18 | internal Visitor(SqlNodeAnnotations annotations, NodeFactory sql) 19 | { 20 | this.annotations = annotations; 21 | this.sql = sql; 22 | } 23 | 24 | internal override SqlSelect VisitSelect(SqlSelect select) 25 | { 26 | base.VisitSelect(select); 27 | if(select.Top != null) 28 | { 29 | if(select.Top.NodeType == SqlNodeType.Value) 30 | { 31 | SqlValue val = (SqlValue)select.Top; 32 | // convert to literal value for SQL2K compatibility 33 | if(val.IsClientSpecified) 34 | { 35 | select.Top = sql.Value(val.ClrType, val.SqlType, val.Value, false, val.SourceExpression); 36 | } 37 | } 38 | else 39 | { 40 | // cannot be converted to literal value. note that this select is not SQL2K compatible 41 | this.annotations.Add(select.Top, new CompatibilityAnnotation(Strings.SourceExpressionAnnotation(select.Top.SourceExpression), SqlServerProviderMode.Sql2000)); 42 | } 43 | } 44 | return select; 45 | } 46 | } 47 | #endregion 48 | 49 | internal static SqlNode Reduce(SqlNode node, SqlNodeAnnotations annotations, NodeFactory sql) 50 | { 51 | return new Visitor(annotations, sql).Visit(node); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Exceptions/ChangeConflictException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Linq; 4 | using System.Linq; 5 | using System.Diagnostics.CodeAnalysis; 6 | 7 | namespace System.Data.Linq { 8 | /// 9 | /// DLinq-specific custom exception factory. 10 | /// 11 | [SuppressMessage("Microsoft.Usage", "CA2237:MarkISerializableTypesWithSerializable", Justification = "Unknown reason.")] 12 | [SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors", Justification = "Unknown reason.")] 13 | public class ChangeConflictException : Exception { 14 | public ChangeConflictException() { } 15 | public ChangeConflictException(string message) : base(message) { } 16 | public ChangeConflictException(string message, Exception innerException) : base(message, innerException) { } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Exceptions/DuplicateKeyException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Linq; 4 | using System.Linq; 5 | using System.Diagnostics.CodeAnalysis; 6 | 7 | namespace System.Data.Linq 8 | { 9 | /// 10 | /// An attempt was made to add an object to the identity cache with a key that is already in use 11 | /// 12 | [SuppressMessage("Microsoft.Usage", "CA2237:MarkISerializableTypesWithSerializable", Justification = "Unknown reason.")] 13 | [SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors", Justification = "Unknown reason.")] 14 | public class DuplicateKeyException : InvalidOperationException 15 | { 16 | private object duplicate; 17 | public DuplicateKeyException(object duplicate) 18 | { 19 | this.duplicate = duplicate; 20 | } 21 | public DuplicateKeyException(object duplicate, string message) 22 | : base(message) 23 | { 24 | this.duplicate = duplicate; 25 | } 26 | public DuplicateKeyException(object duplicate, string message, Exception innerException) 27 | : base(message, innerException) 28 | { 29 | this.duplicate = duplicate; 30 | } 31 | 32 | /// 33 | /// The object whose duplicate key caused the exception. 34 | /// 35 | public object Object 36 | { 37 | get 38 | { 39 | return duplicate; 40 | } 41 | } 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/Exceptions/ForeignKeyReferenceAlreadyHasValueException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Linq; 4 | using System.Linq; 5 | using System.Diagnostics.CodeAnalysis; 6 | 7 | namespace System.Data.Linq 8 | { 9 | /// 10 | /// An attempt was made to change an FK but the Entity is Loaded 11 | /// 12 | [SuppressMessage("Microsoft.Usage", "CA2237:MarkISerializableTypesWithSerializable", Justification = "Unknown reason.")] 13 | [SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors", Justification = "Unknown reason.")] 14 | public class ForeignKeyReferenceAlreadyHasValueException : InvalidOperationException 15 | { 16 | public ForeignKeyReferenceAlreadyHasValueException() { } 17 | public ForeignKeyReferenceAlreadyHasValueException(string message) : base(message) { } 18 | public ForeignKeyReferenceAlreadyHasValueException(string message, Exception innerException) : base(message, innerException) { } 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/IdentityMangement/IdentityCache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Security; 7 | using System.Security.Permissions; 8 | using System.Runtime.CompilerServices; 9 | 10 | namespace System.Data.Linq 11 | { 12 | using System.Data.Linq.Mapping; 13 | using Linq; 14 | 15 | internal abstract class IdentityCache 16 | { 17 | internal abstract object Find(object[] keyValues); 18 | internal abstract object FindLike(object instance); 19 | internal abstract object InsertLookup(object instance); 20 | internal abstract bool RemoveLike(object instance); 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/IdentityMangement/IdentityManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Security; 7 | using System.Security.Permissions; 8 | using System.Runtime.CompilerServices; 9 | 10 | namespace System.Data.Linq { 11 | using System.Data.Linq.Mapping; 12 | using Linq; 13 | 14 | internal abstract class IdentityManager { 15 | internal abstract object InsertLookup(MetaType type, object instance); 16 | internal abstract bool RemoveLike(MetaType type, object instance); 17 | internal abstract object Find(MetaType type, object[] keyValues); 18 | internal abstract object FindLike(MetaType type, object instance); 19 | 20 | internal static IdentityManager CreateIdentityManager(bool asReadOnly) { 21 | if (asReadOnly) { 22 | return new ReadOnlyIdentityManager(); 23 | } 24 | else { 25 | return new StandardIdentityManager(); 26 | } 27 | } 28 | } 29 | 30 | /// 31 | /// This is the noop implementation used when object tracking is disabled. 32 | /// 33 | internal class ReadOnlyIdentityManager : IdentityManager 34 | { 35 | internal ReadOnlyIdentityManager() { } 36 | internal override object InsertLookup(MetaType type, object instance) { return instance; } 37 | internal override bool RemoveLike(MetaType type, object instance) { return false; } 38 | internal override object Find(MetaType type, object[] keyValues) { return null; } 39 | internal override object FindLike(MetaType type, object instance) { return null; } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/IdentityMangement/KeyManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Security; 7 | using System.Security.Permissions; 8 | using System.Runtime.CompilerServices; 9 | 10 | namespace System.Data.Linq 11 | { 12 | using System.Data.Linq.Mapping; 13 | using Linq; 14 | 15 | internal abstract class KeyManager 16 | { 17 | internal abstract Type KeyType { get; } 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/IdentityMangement/KeyManagerOfTK.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Security; 7 | using System.Security.Permissions; 8 | using System.Runtime.CompilerServices; 9 | 10 | namespace System.Data.Linq 11 | { 12 | using System.Data.Linq.Mapping; 13 | using Linq; 14 | 15 | internal abstract class KeyManager : KeyManager 16 | { 17 | internal abstract K CreateKeyFromInstance(T instance); 18 | internal abstract bool TryCreateKeyFromValues(object[] values, out K k); 19 | internal abstract IEqualityComparer Comparer { get; } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/IdentityMangement/MultiKey.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Security; 7 | using System.Security.Permissions; 8 | using System.Runtime.CompilerServices; 9 | 10 | namespace System.Data.Linq 11 | { 12 | using System.Data.Linq.Mapping; 13 | using Linq; 14 | 15 | internal struct MultiKey 16 | { 17 | T1 value1; 18 | T2 value2; 19 | 20 | internal MultiKey(T1 value1, T2 value2) 21 | { 22 | this.value1 = value1; 23 | this.value2 = value2; 24 | } 25 | 26 | internal class Comparer : IEqualityComparer>, IEqualityComparer 27 | { 28 | IEqualityComparer comparer1; 29 | IEqualityComparer comparer2; 30 | 31 | internal Comparer(IEqualityComparer comparer1, IEqualityComparer comparer2) 32 | { 33 | this.comparer1 = comparer1; 34 | this.comparer2 = comparer2; 35 | } 36 | 37 | public bool Equals(MultiKey x, MultiKey y) 38 | { 39 | return this.comparer1.Equals(x.value1, y.value1) && 40 | this.comparer2.Equals(x.value2, y.value2); 41 | } 42 | 43 | public int GetHashCode(MultiKey x) 44 | { 45 | return this.comparer1.GetHashCode(x.value1) ^ this.comparer2.GetHashCode(x.value2); 46 | } 47 | 48 | bool IEqualityComparer.Equals(object x, object y) 49 | { 50 | return this.Equals((MultiKey)x, (MultiKey)y); 51 | } 52 | 53 | int IEqualityComparer.GetHashCode(object x) 54 | { 55 | return this.GetHashCode((MultiKey)x); 56 | } 57 | } 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/IdentityMangement/SingleKeyManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Security; 7 | using System.Security.Permissions; 8 | using System.Runtime.CompilerServices; 9 | 10 | namespace System.Data.Linq 11 | { 12 | using System.Data.Linq.Mapping; 13 | using Linq; 14 | using System.Data.Linq.Provider.Common; 15 | 16 | internal class SingleKeyManager : KeyManager 17 | { 18 | bool isKeyNullAssignable; 19 | MetaAccessor accessor; 20 | int offset; 21 | IEqualityComparer comparer; 22 | 23 | internal SingleKeyManager(MetaAccessor accessor, int offset) 24 | { 25 | this.accessor = accessor; 26 | this.offset = offset; 27 | this.isKeyNullAssignable = TypeSystem.IsNullAssignable(typeof(V)); 28 | } 29 | 30 | internal override V CreateKeyFromInstance(T instance) 31 | { 32 | return this.accessor.GetValue(instance); 33 | } 34 | 35 | internal override bool TryCreateKeyFromValues(object[] values, out V v) 36 | { 37 | object o = values[this.offset]; 38 | if(o == null && !this.isKeyNullAssignable) 39 | { 40 | v = default(V); 41 | return false; 42 | } 43 | v = (V)o; 44 | return true; 45 | } 46 | 47 | internal override Type KeyType 48 | { 49 | get { return typeof(V); } 50 | } 51 | 52 | internal override IEqualityComparer Comparer 53 | { 54 | get 55 | { 56 | if(this.comparer == null) 57 | { 58 | this.comparer = EqualityComparer.Default; 59 | } 60 | return this.comparer; 61 | } 62 | } 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /src/Interfaces/ICompiledQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Data; 5 | using System.Data.Linq; 6 | using System.Data.Common; 7 | using System.Linq.Expressions; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Transactions; 12 | using System.Reflection; 13 | using System.Diagnostics.CodeAnalysis; 14 | 15 | namespace System.Data.Linq 16 | { 17 | using Linq; 18 | 19 | /// 20 | /// A compiled query. 21 | /// 22 | internal interface ICompiledQuery 23 | { 24 | /// 25 | /// Executes the compiled query using the specified provider and a set of arguments. 26 | /// 27 | /// The provider that will execute the compiled query. 28 | /// Argument values to supply to the parameters of the compiled query, 29 | /// when the query is specified as a LambdaExpression. 30 | /// 31 | IExecuteResult Execute(IProvider provider, object[] arguments); 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/Interfaces/IDataServices.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq.Expressions; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | namespace System.Data.Linq { 9 | using System.Data.Linq.Mapping; 10 | 11 | internal interface IDataServices { 12 | DataContext Context { get; } 13 | MetaModel Model { get; } 14 | IDeferredSourceFactory GetDeferredSourceFactory(MetaDataMember member); 15 | object GetCachedObject(Expression query); 16 | bool IsCachedObject(MetaType type, object instance); 17 | object InsertLookupCachedObject(MetaType type, object instance); 18 | void OnEntityMaterialized(MetaType type, object instance); 19 | } 20 | } -------------------------------------------------------------------------------- /src/Interfaces/IDeferredSourceFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq.Expressions; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | namespace System.Data.Linq 9 | { 10 | using System.Data.Linq.Mapping; 11 | 12 | internal interface IDeferredSourceFactory 13 | { 14 | IEnumerable CreateDeferredSource(object instance); 15 | IEnumerable CreateDeferredSource(object[] keyValues); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/Interfaces/IExecuteResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.CodeAnalysis; 4 | 5 | namespace System.Data.Linq 6 | { 7 | /// 8 | /// The result of executing a query. 9 | /// 10 | public interface IExecuteResult : IDisposable 11 | { 12 | /// 13 | /// The return value or result of the executed query. This object has the same type as the 14 | /// query expression's Type property. 15 | /// 16 | object ReturnValue { get; } 17 | 18 | /// 19 | /// Retrieves the nth output parameter. This method is normally used when the query is a mapped 20 | /// function with output parameters. 21 | /// 22 | /// 23 | /// 24 | object GetParameterValue(int parameterIndex); 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/Interfaces/IFunctionResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.CodeAnalysis; 4 | 5 | namespace System.Data.Linq 6 | { 7 | /// 8 | /// Interface providing access to a function return value. 9 | /// 10 | public interface IFunctionResult 11 | { 12 | /// 13 | /// The value. 14 | /// 15 | object ReturnValue { get; } 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/Interfaces/IMultipleResults.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.CodeAnalysis; 4 | 5 | namespace System.Data.Linq { 6 | 7 | /// 8 | /// An interface for representing results of mapped functions or queries with variable return sequences. 9 | /// 10 | public interface IMultipleResults : IFunctionResult, IDisposable { 11 | /// 12 | /// Retrieves the next result as a sequence of Type 'TElement'. 13 | /// 14 | /// 15 | /// 16 | [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "[....]: Generic parameters are required for strong-typing of the return type.")] 17 | IEnumerable GetResult(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Interfaces/ISingleResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.CodeAnalysis; 4 | 5 | namespace System.Data.Linq 6 | { 7 | /// 8 | /// An interface for representing the result of a mapped function with a single return sequence. 9 | /// 10 | [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification = "[....]: Meant to represent a database table which is delayed loaded and doesn't provide collection semantics.")] 11 | public interface ISingleResult : IEnumerable, IFunctionResult, IDisposable { } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /src/Mapping/Accesssors/Delegates.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq.Expressions; 5 | using System.Reflection; 6 | using System.Reflection.Emit; 7 | using System.Security.Permissions; 8 | using System.Security; 9 | using System.Runtime.CompilerServices; 10 | 11 | namespace System.Data.Linq.Mapping 12 | { 13 | using Linq; 14 | using System.Diagnostics.CodeAnalysis; 15 | 16 | internal delegate V DGet(T t); 17 | internal delegate void DSet(T t, V v); 18 | internal delegate void DRSet(ref T t, V v); 19 | } 20 | -------------------------------------------------------------------------------- /src/Mapping/Accesssors/EntityRefDefSourceAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq.Expressions; 5 | using System.Reflection; 6 | using System.Reflection.Emit; 7 | using System.Security.Permissions; 8 | using System.Security; 9 | using System.Runtime.CompilerServices; 10 | 11 | namespace System.Data.Linq.Mapping 12 | { 13 | using Linq; 14 | using System.Diagnostics.CodeAnalysis; 15 | 16 | internal class EntityRefDefSourceAccessor : MetaAccessor> where V : class 17 | { 18 | MetaAccessor> acc; 19 | internal EntityRefDefSourceAccessor(MetaAccessor> acc) 20 | { 21 | this.acc = acc; 22 | } 23 | public override IEnumerable GetValue(T instance) 24 | { 25 | EntityRef er = this.acc.GetValue(instance); 26 | return (IEnumerable)er.Source; 27 | } 28 | public override void SetValue(ref T instance, IEnumerable value) 29 | { 30 | EntityRef er = this.acc.GetValue(instance); 31 | if(er.HasAssignedValue || er.HasLoadedValue) 32 | { 33 | throw Error.EntityRefAlreadyLoaded(); 34 | } 35 | this.acc.SetValue(ref instance, new EntityRef(value)); 36 | } 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/Mapping/Accesssors/EntityRefDefValueAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq.Expressions; 5 | using System.Reflection; 6 | using System.Reflection.Emit; 7 | using System.Security.Permissions; 8 | using System.Security; 9 | using System.Runtime.CompilerServices; 10 | 11 | namespace System.Data.Linq.Mapping 12 | { 13 | using Linq; 14 | using System.Diagnostics.CodeAnalysis; 15 | 16 | internal class EntityRefDefValueAccessor : MetaAccessor where V : class 17 | { 18 | MetaAccessor> acc; 19 | internal EntityRefDefValueAccessor(MetaAccessor> acc) 20 | { 21 | this.acc = acc; 22 | } 23 | public override V GetValue(T instance) 24 | { 25 | EntityRef er = this.acc.GetValue(instance); 26 | return er.UnderlyingValue; 27 | } 28 | public override void SetValue(ref T instance, V value) 29 | { 30 | this.acc.SetValue(ref instance, new EntityRef(value)); 31 | } 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/Mapping/Accesssors/EntityRefValueAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq.Expressions; 5 | using System.Reflection; 6 | using System.Reflection.Emit; 7 | using System.Security.Permissions; 8 | using System.Security; 9 | using System.Runtime.CompilerServices; 10 | 11 | namespace System.Data.Linq.Mapping 12 | { 13 | using Linq; 14 | using System.Diagnostics.CodeAnalysis; 15 | 16 | internal class EntityRefValueAccessor : MetaAccessor where V : class 17 | { 18 | MetaAccessor> acc; 19 | internal EntityRefValueAccessor(MetaAccessor> acc) 20 | { 21 | this.acc = acc; 22 | } 23 | public override V GetValue(T instance) 24 | { 25 | EntityRef er = this.acc.GetValue(instance); 26 | return er.Entity; 27 | } 28 | public override void SetValue(ref T instance, V value) 29 | { 30 | this.acc.SetValue(ref instance, new EntityRef(value)); 31 | } 32 | public override bool HasValue(object instance) 33 | { 34 | EntityRef er = this.acc.GetValue((T)instance); 35 | return er.HasValue; 36 | } 37 | public override bool HasAssignedValue(object instance) 38 | { 39 | EntityRef er = this.acc.GetValue((T)instance); 40 | return er.HasAssignedValue; 41 | } 42 | public override bool HasLoadedValue(object instance) 43 | { 44 | EntityRef er = this.acc.GetValue((T)instance); 45 | return er.HasLoadedValue; 46 | } 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/Mapping/Accesssors/EntitySetDefSourceAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq.Expressions; 5 | using System.Reflection; 6 | using System.Reflection.Emit; 7 | using System.Security.Permissions; 8 | using System.Security; 9 | using System.Runtime.CompilerServices; 10 | 11 | namespace System.Data.Linq.Mapping { 12 | using Linq; 13 | using System.Diagnostics.CodeAnalysis; 14 | 15 | internal class EntitySetDefSourceAccessor : MetaAccessor> where V : class { 16 | MetaAccessor> acc; 17 | internal EntitySetDefSourceAccessor(MetaAccessor> acc) { 18 | this.acc = acc; 19 | } 20 | public override IEnumerable GetValue(T instance) { 21 | EntitySet eset = this.acc.GetValue(instance); 22 | return (IEnumerable)eset.Source; 23 | } 24 | public override void SetValue(ref T instance, IEnumerable value) { 25 | EntitySet eset = this.acc.GetValue(instance); 26 | if (eset == null) { 27 | eset = new EntitySet(); 28 | this.acc.SetValue(ref instance, eset); 29 | } 30 | eset.SetSource(value); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Mapping/Accesssors/EntitySetDefValueAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq.Expressions; 5 | using System.Reflection; 6 | using System.Reflection.Emit; 7 | using System.Security.Permissions; 8 | using System.Security; 9 | using System.Runtime.CompilerServices; 10 | 11 | namespace System.Data.Linq.Mapping 12 | { 13 | using Linq; 14 | using System.Diagnostics.CodeAnalysis; 15 | 16 | internal class EntitySetDefValueAccessor : MetaAccessor> where V : class 17 | { 18 | MetaAccessor> acc; 19 | internal EntitySetDefValueAccessor(MetaAccessor> acc) 20 | { 21 | this.acc = acc; 22 | } 23 | public override IEnumerable GetValue(T instance) 24 | { 25 | EntitySet eset = this.acc.GetValue(instance); 26 | return eset.GetUnderlyingValues(); 27 | } 28 | public override void SetValue(ref T instance, IEnumerable value) 29 | { 30 | EntitySet eset = this.acc.GetValue(instance); 31 | if(eset == null) 32 | { 33 | eset = new EntitySet(); 34 | this.acc.SetValue(ref instance, eset); 35 | } 36 | eset.Assign(value); 37 | } 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/Mapping/Accesssors/EntitySetValueAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq.Expressions; 5 | using System.Reflection; 6 | using System.Reflection.Emit; 7 | using System.Security.Permissions; 8 | using System.Security; 9 | using System.Runtime.CompilerServices; 10 | 11 | namespace System.Data.Linq.Mapping 12 | { 13 | using Linq; 14 | using System.Diagnostics.CodeAnalysis; 15 | 16 | internal class EntitySetValueAccessor : MetaAccessor> where V : class 17 | { 18 | MetaAccessor> acc; 19 | internal EntitySetValueAccessor(MetaAccessor> acc) 20 | { 21 | this.acc = acc; 22 | } 23 | public override EntitySet GetValue(T instance) 24 | { 25 | return this.acc.GetValue(instance); 26 | } 27 | public override void SetValue(ref T instance, EntitySet value) 28 | { 29 | EntitySet eset = this.acc.GetValue(instance); 30 | if(eset == null) 31 | { 32 | eset = new EntitySet(); 33 | this.acc.SetValue(ref instance, eset); 34 | } 35 | eset.Assign(value); 36 | } 37 | public override bool HasValue(object instance) 38 | { 39 | EntitySet es = this.acc.GetValue((T)instance); 40 | return es != null && es.HasValues; 41 | } 42 | public override bool HasAssignedValue(object instance) 43 | { 44 | EntitySet es = this.acc.GetValue((T)instance); 45 | return es != null && es.HasAssignedValues; 46 | } 47 | public override bool HasLoadedValue(object instance) 48 | { 49 | EntitySet es = this.acc.GetValue((T)instance); 50 | return es != null && es.HasLoadedValues; 51 | } 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /src/Mapping/Accesssors/LinkDefSourceAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq.Expressions; 5 | using System.Reflection; 6 | using System.Reflection.Emit; 7 | using System.Security.Permissions; 8 | using System.Security; 9 | using System.Runtime.CompilerServices; 10 | 11 | namespace System.Data.Linq.Mapping 12 | { 13 | using Linq; 14 | using System.Diagnostics.CodeAnalysis; 15 | 16 | internal class LinkDefSourceAccessor : MetaAccessor> 17 | { 18 | MetaAccessor> acc; 19 | internal LinkDefSourceAccessor(MetaAccessor> acc) 20 | { 21 | this.acc = acc; 22 | } 23 | public override IEnumerable GetValue(T instance) 24 | { 25 | Link link = this.acc.GetValue(instance); 26 | return (IEnumerable)link.Source; 27 | } 28 | public override void SetValue(ref T instance, IEnumerable value) 29 | { 30 | Link link = this.acc.GetValue(instance); 31 | if(link.HasAssignedValue || link.HasLoadedValue) 32 | { 33 | throw Error.LinkAlreadyLoaded(); 34 | } 35 | this.acc.SetValue(ref instance, new Link(value)); 36 | } 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/Mapping/Accesssors/LinkDefValueAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq.Expressions; 5 | using System.Reflection; 6 | using System.Reflection.Emit; 7 | using System.Security.Permissions; 8 | using System.Security; 9 | using System.Runtime.CompilerServices; 10 | 11 | namespace System.Data.Linq.Mapping 12 | { 13 | using Linq; 14 | using System.Diagnostics.CodeAnalysis; 15 | 16 | internal class LinkDefValueAccessor : MetaAccessor 17 | { 18 | MetaAccessor> acc; 19 | internal LinkDefValueAccessor(MetaAccessor> acc) 20 | { 21 | this.acc = acc; 22 | } 23 | public override V GetValue(T instance) 24 | { 25 | Link link = this.acc.GetValue(instance); 26 | return link.UnderlyingValue; 27 | } 28 | public override void SetValue(ref T instance, V value) 29 | { 30 | this.acc.SetValue(ref instance, new Link(value)); 31 | } 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/Mapping/Accesssors/LinkValueAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq.Expressions; 5 | using System.Reflection; 6 | using System.Reflection.Emit; 7 | using System.Security.Permissions; 8 | using System.Security; 9 | using System.Runtime.CompilerServices; 10 | 11 | namespace System.Data.Linq.Mapping 12 | { 13 | using Linq; 14 | using System.Diagnostics.CodeAnalysis; 15 | 16 | // deferred type accessors 17 | internal class LinkValueAccessor : MetaAccessor 18 | { 19 | MetaAccessor> acc; 20 | internal LinkValueAccessor(MetaAccessor> acc) 21 | { 22 | this.acc = acc; 23 | } 24 | public override bool HasValue(object instance) 25 | { 26 | Link link = this.acc.GetValue((T)instance); 27 | return link.HasValue; 28 | } 29 | public override bool HasAssignedValue(object instance) 30 | { 31 | Link link = this.acc.GetValue((T)instance); 32 | return link.HasAssignedValue; 33 | } 34 | public override bool HasLoadedValue(object instance) 35 | { 36 | Link link = this.acc.GetValue((T)instance); 37 | return link.HasLoadedValue; 38 | } 39 | public override V GetValue(T instance) 40 | { 41 | Link link = this.acc.GetValue(instance); 42 | return link.Value; 43 | } 44 | public override void SetValue(ref T instance, V value) 45 | { 46 | this.acc.SetValue(ref instance, new Link(value)); 47 | } 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/Mapping/AttributedMetaModel/AttributedMetaParameter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | using System.Linq.Expressions; 6 | using System.Reflection; 7 | using System.Text; 8 | using System.Linq; 9 | using System.Data.Linq; 10 | using System.Threading; 11 | using LinqToSqlShared.Mapping; 12 | using System.Runtime.CompilerServices; 13 | 14 | namespace System.Data.Linq.Mapping 15 | { 16 | internal sealed class AttributedMetaParameter : MetaParameter 17 | { 18 | private ParameterInfo parameterInfo; 19 | private ParameterAttribute paramAttrib; 20 | 21 | public AttributedMetaParameter(ParameterInfo parameterInfo) 22 | { 23 | this.parameterInfo = parameterInfo; 24 | this.paramAttrib = Attribute.GetCustomAttribute(parameterInfo, typeof(ParameterAttribute), false) as ParameterAttribute; 25 | } 26 | public override ParameterInfo Parameter 27 | { 28 | get { return this.parameterInfo; } 29 | } 30 | public override string Name 31 | { 32 | get { return this.parameterInfo.Name; } 33 | } 34 | public override string MappedName 35 | { 36 | get 37 | { 38 | if(this.paramAttrib != null && this.paramAttrib.Name != null) 39 | return this.paramAttrib.Name; 40 | return this.parameterInfo.Name; 41 | } 42 | } 43 | public override Type ParameterType 44 | { 45 | get { return this.parameterInfo.ParameterType; } 46 | } 47 | public override string DbType 48 | { 49 | get 50 | { 51 | if(this.paramAttrib != null && this.paramAttrib.DbType != null) 52 | return this.paramAttrib.DbType; 53 | return null; 54 | } 55 | } 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /src/Mapping/AttributedMetaModel/InheritanceBaseFinder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | using System.Linq.Expressions; 6 | using System.Reflection; 7 | using System.Text; 8 | using System.Linq; 9 | using System.Data.Linq; 10 | using System.Threading; 11 | using LinqToSqlShared.Mapping; 12 | using System.Runtime.CompilerServices; 13 | 14 | namespace System.Data.Linq.Mapping 15 | { 16 | internal static class InheritanceBaseFinder 17 | { 18 | internal static MetaType FindBase(MetaType derivedType) 19 | { 20 | if(derivedType.Type == typeof(object)) 21 | { 22 | return null; 23 | } 24 | 25 | var clrType = derivedType.Type; // start 26 | var rootClrType = derivedType.InheritanceRoot.Type; // end 27 | var metaTable = derivedType.Table; 28 | MetaType metaType = null; 29 | 30 | while(true) 31 | { 32 | if(clrType == typeof(object) || clrType == rootClrType) 33 | { 34 | return null; 35 | } 36 | 37 | clrType = clrType.BaseType; 38 | metaType = derivedType.InheritanceRoot.GetInheritanceType(clrType); 39 | 40 | if(metaType != null) 41 | { 42 | return metaType; 43 | } 44 | } 45 | } 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/Mapping/AttributedMetaModel/MethodFinder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | using System.Linq.Expressions; 6 | using System.Reflection; 7 | using System.Text; 8 | using System.Linq; 9 | using System.Data.Linq; 10 | using System.Threading; 11 | using LinqToSqlShared.Mapping; 12 | using System.Runtime.CompilerServices; 13 | 14 | namespace System.Data.Linq.Mapping 15 | { 16 | internal static class MethodFinder 17 | { 18 | internal static MethodInfo FindMethod(Type type, string name, BindingFlags flags, Type[] argTypes) 19 | { 20 | return FindMethod(type, name, flags, argTypes, true); 21 | } 22 | 23 | internal static MethodInfo FindMethod(Type type, string name, BindingFlags flags, Type[] argTypes, bool allowInherit) 24 | { 25 | for(; type != typeof(object); type = type.BaseType) 26 | { 27 | MethodInfo mi = type.GetMethod(name, flags | BindingFlags.DeclaredOnly, null, argTypes, null); 28 | if(mi != null || !allowInherit) 29 | { 30 | return mi; 31 | } 32 | } 33 | return null; 34 | } 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/Mapping/ConstantsEnums.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LinqToSqlShared.Mapping 8 | { 9 | /// 10 | /// DatabaseMapping and related classes represent a parsed version of the 11 | /// XML mapping string. This unvalidated intermediate representation is 12 | /// necessary because unused mappings are intentially never validated. 13 | /// 14 | internal enum MappingParameterDirection 15 | { 16 | In, 17 | Out, 18 | InOut 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Mapping/DbmlShared/MemberMapping.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Data.Linq; 5 | using System.Data.Linq.Mapping; 6 | using System.Globalization; 7 | 8 | namespace LinqToSqlShared.Mapping 9 | { 10 | /// 11 | /// DatabaseMapping and related classes represent a parsed version of the 12 | /// XML mapping string. This unvalidated intermediate representation is 13 | /// necessary because unused mappings are intentially never validated. 14 | /// 15 | internal abstract class MemberMapping 16 | { 17 | string name; 18 | string member; 19 | string storageMember; 20 | 21 | internal MemberMapping() 22 | { 23 | } 24 | 25 | internal string DbName 26 | { 27 | get { return this.name; } 28 | set { this.name = value; } 29 | } 30 | 31 | internal string MemberName 32 | { 33 | get { return this.member; } 34 | set { this.member = value; } 35 | } 36 | 37 | internal string StorageMemberName 38 | { 39 | get { return this.storageMember; } 40 | set { this.storageMember = value; } 41 | } 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/Mapping/DbmlShared/ParameterMapping.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Data.Linq; 5 | using System.Data.Linq.Mapping; 6 | using System.Globalization; 7 | 8 | namespace LinqToSqlShared.Mapping 9 | { 10 | /// 11 | /// DatabaseMapping and related classes represent a parsed version of the 12 | /// XML mapping string. This unvalidated intermediate representation is 13 | /// necessary because unused mappings are intentially never validated. 14 | /// 15 | internal class ParameterMapping 16 | { 17 | string name; 18 | string parameterName; 19 | string dbType; 20 | MappingParameterDirection direction; 21 | 22 | internal string Name 23 | { 24 | get { return this.name; } 25 | set { this.name = value; } 26 | } 27 | 28 | internal string ParameterName 29 | { 30 | get { return this.parameterName; } 31 | set { this.parameterName = value; } 32 | } 33 | 34 | internal string DbType 35 | { 36 | get { return this.dbType; } 37 | set { this.dbType = value; } 38 | } 39 | 40 | public string XmlDirection 41 | { 42 | get { return this.direction == MappingParameterDirection.In ? null : this.direction.ToString(); } 43 | set 44 | { 45 | this.direction = (value == null) 46 | ? MappingParameterDirection.In 47 | : (MappingParameterDirection)Enum.Parse(typeof(MappingParameterDirection), value, true); 48 | } 49 | } 50 | 51 | public MappingParameterDirection Direction 52 | { 53 | get { return this.direction; } 54 | set { this.direction = value; } 55 | } 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /src/Mapping/DbmlShared/ReturnMapping.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Data.Linq; 5 | using System.Data.Linq.Mapping; 6 | using System.Globalization; 7 | 8 | namespace LinqToSqlShared.Mapping 9 | { 10 | /// 11 | /// DatabaseMapping and related classes represent a parsed version of the 12 | /// XML mapping string. This unvalidated intermediate representation is 13 | /// necessary because unused mappings are intentially never validated. 14 | /// 15 | internal class ReturnMapping 16 | { 17 | #warning [FB] THIS TYPE IS A BIT USELESS, AS IT ONLY WRAPS A STRING VALUE. SEE WHETHER IT'S REALLY NEEDED. 18 | string dbType; 19 | 20 | internal string DbType 21 | { 22 | get { return this.dbType; } 23 | set { this.dbType = value; } 24 | } 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/Mapping/DbmlShared/TableMapping.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Data.Linq; 5 | using System.Data.Linq.Mapping; 6 | using System.Globalization; 7 | 8 | namespace LinqToSqlShared.Mapping 9 | { 10 | /// 11 | /// DatabaseMapping and related classes represent a parsed version of the 12 | /// XML mapping string. This unvalidated intermediate representation is 13 | /// necessary because unused mappings are intentially never validated. 14 | /// 15 | internal class TableMapping 16 | { 17 | string tableName; 18 | string member; 19 | TypeMapping rowType; 20 | 21 | internal TableMapping() 22 | { 23 | } 24 | 25 | internal string TableName 26 | { 27 | get { return this.tableName; } 28 | set { this.tableName = value; } 29 | } 30 | 31 | internal string Member 32 | { 33 | get { return this.member; } 34 | set { this.member = value; } 35 | } 36 | 37 | internal TypeMapping RowType 38 | { 39 | get { return this.rowType; } 40 | set { this.rowType = value; } 41 | } 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/Mapping/MappedMetaModel/MappedParameter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | using System.Linq.Expressions; 6 | using System.Reflection; 7 | using System.Text; 8 | using System.Linq; 9 | using System.Data.Linq; 10 | using System.Threading; 11 | using System.Runtime.Versioning; 12 | using LinqToSqlShared.Mapping; 13 | using System.Runtime.CompilerServices; 14 | 15 | namespace System.Data.Linq.Mapping 16 | { 17 | internal sealed class MappedParameter : MetaParameter 18 | { 19 | private ParameterInfo parameterInfo; 20 | private ParameterMapping map; 21 | 22 | public MappedParameter(ParameterInfo parameterInfo, ParameterMapping map) 23 | { 24 | this.parameterInfo = parameterInfo; 25 | this.map = map; 26 | } 27 | public override ParameterInfo Parameter 28 | { 29 | get { return this.parameterInfo; } 30 | } 31 | public override string Name 32 | { 33 | get { return this.parameterInfo.Name; } 34 | } 35 | public override string MappedName 36 | { 37 | get { return this.map.Name; } 38 | } 39 | public override Type ParameterType 40 | { 41 | get { return this.parameterInfo.ParameterType; } 42 | } 43 | public override string DbType 44 | { 45 | get { return this.map.DbType; } 46 | } 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/Mapping/MappedMetaModel/MappedReturnParameter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | using System.Linq.Expressions; 6 | using System.Reflection; 7 | using System.Text; 8 | using System.Linq; 9 | using System.Data.Linq; 10 | using System.Threading; 11 | using System.Runtime.Versioning; 12 | using LinqToSqlShared.Mapping; 13 | using System.Runtime.CompilerServices; 14 | 15 | namespace System.Data.Linq.Mapping 16 | { 17 | internal sealed class MappedReturnParameter : MetaParameter 18 | { 19 | private ParameterInfo parameterInfo; 20 | private ReturnMapping map; 21 | 22 | public MappedReturnParameter(ParameterInfo parameterInfo, ReturnMapping map) 23 | { 24 | this.parameterInfo = parameterInfo; 25 | this.map = map; 26 | } 27 | public override ParameterInfo Parameter 28 | { 29 | get { return this.parameterInfo; } 30 | } 31 | public override string Name 32 | { 33 | get { return null; } 34 | } 35 | public override string MappedName 36 | { 37 | get { return null; } 38 | } 39 | public override Type ParameterType 40 | { 41 | get { return this.parameterInfo.ParameterType; } 42 | } 43 | public override string DbType 44 | { 45 | get { return this.map.DbType; } 46 | } 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/Mapping/MappingSource/AttributeMappingSource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.ObjectModel; 3 | using System.Collections.Generic; 4 | using System.Linq.Expressions; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Runtime.Versioning; 8 | using System.Text; 9 | using System.Threading; 10 | using System.Xml; 11 | using System.Xml.Serialization; 12 | using LinqToSqlShared.Mapping; 13 | 14 | namespace System.Data.Linq.Mapping 15 | { 16 | using Linq; 17 | using System.Diagnostics.CodeAnalysis; 18 | 19 | /// 20 | /// A mapping source that uses attributes on the context to create the mapping model. 21 | /// 22 | public sealed class AttributeMappingSource : MappingSource 23 | { 24 | public AttributeMappingSource() 25 | { 26 | } 27 | 28 | protected override MetaModel CreateModel(Type dataContextType) 29 | { 30 | if(dataContextType == null) 31 | { 32 | throw Error.ArgumentNull("dataContextType"); 33 | } 34 | return new AttributedMetaModel(this, dataContextType); 35 | } 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/Mapping/MetaModel/MetaParameter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | using System.Data.Linq; 6 | using System.Linq.Expressions; 7 | using System.Reflection; 8 | using System.Text; 9 | using System.Linq; 10 | using System.Diagnostics.CodeAnalysis; 11 | 12 | namespace System.Data.Linq.Mapping 13 | { 14 | /// 15 | /// A MetaParameter represents the mapping between a method parameter and a database function parameter. 16 | /// 17 | public abstract class MetaParameter 18 | { 19 | /// 20 | /// The underlying method parameter. 21 | /// 22 | public abstract ParameterInfo Parameter { get; } 23 | /// 24 | /// The name of the parameter (same as the ParameterInfo's name). 25 | /// 26 | public abstract string Name { get; } 27 | /// 28 | /// The name of the database function's parameter. 29 | /// 30 | public abstract string MappedName { get; } 31 | /// 32 | /// The CLR type of the parameter. 33 | /// 34 | public abstract Type ParameterType { get; } 35 | /// 36 | /// The database type of the parameter. 37 | /// 38 | [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db", Justification = "Conforms to legacy spelling.")] 39 | public abstract string DbType { get; } 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /src/Mapping/MetaModel/MetaTable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | using System.Data.Linq; 6 | using System.Linq.Expressions; 7 | using System.Reflection; 8 | using System.Text; 9 | using System.Linq; 10 | using System.Diagnostics.CodeAnalysis; 11 | 12 | namespace System.Data.Linq.Mapping 13 | { 14 | /// 15 | /// A MetaTable represents an abstraction of a database table (or view) 16 | /// 17 | public abstract class MetaTable 18 | { 19 | /// 20 | /// The MetaModel containing this MetaTable. 21 | /// 22 | public abstract MetaModel Model { get; } 23 | /// 24 | /// The name of the table as defined by the database. 25 | /// 26 | public abstract string TableName { get; } 27 | /// 28 | /// The MetaType describing the type of the rows of the table. 29 | /// 30 | public abstract MetaType RowType { get; } 31 | /// 32 | /// The DataContext method used to perform insert operations 33 | /// 34 | public abstract MethodInfo InsertMethod { get; } 35 | /// 36 | /// The DataContext method used to perform update operations 37 | /// 38 | public abstract MethodInfo UpdateMethod { get; } 39 | /// 40 | /// The DataContext method used to perform delete operations 41 | /// 42 | public abstract MethodInfo DeleteMethod { get; } 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /src/Mapping/SourceState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Linq.Expressions; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Reflection; 9 | using System.Text; 10 | using System.Diagnostics; 11 | using System.Runtime.Serialization; 12 | using System.Diagnostics.CodeAnalysis; 13 | using System.Data.Linq.BindingLists; 14 | 15 | namespace System.Data.Linq { 16 | internal static class SourceState { 17 | internal static readonly IEnumerable Loaded = (IEnumerable)new T[] { }; 18 | internal static readonly IEnumerable Assigned = (IEnumerable)new T[] { }; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Security; 6 | 7 | [assembly: SecurityTransparent] 8 | [assembly: AllowPartiallyTrustedCallers] 9 | [assembly: SecurityRules(System.Security.SecurityRuleSet.Level1, SkipVerificationInFullTrust = true)] 10 | [assembly: AssemblyTitleAttribute("Linq To SQL2")] 11 | [assembly: AssemblyDescriptionAttribute("Full featured ORM which is based on and backwards compatible with Linq to SQL.")] 12 | [assembly: AssemblyCompanyAttribute("Solutions Design bv / Microsoft Corporation")] 13 | [assembly: AssemblyProductAttribute("Linq to SQL2")] 14 | [assembly: AssemblyCopyrightAttribute("(c) Solutions Design bv / Microsoft Corporation")] 15 | [assembly: ComVisibleAttribute(false)] 16 | 17 | 18 | [assembly: AssemblyVersionAttribute("1.0.0.0")] 19 | [assembly: AssemblyFileVersionAttribute("1.0.15.0424")] // x.y.yy.mmdd 20 | -------------------------------------------------------------------------------- /src/Provider/Common/BigJoinChecker.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | using System.Data.Linq.Provider.Visitors; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | internal class BigJoinChecker 7 | { 8 | #region Private Classes 9 | private class Visitor : SqlVisitor 10 | { 11 | internal bool canBigJoin = true; 12 | 13 | 14 | internal override SqlExpression VisitMultiset(SqlSubSelect sms) 15 | { 16 | return sms; 17 | } 18 | 19 | 20 | internal override SqlExpression VisitElement(SqlSubSelect elem) 21 | { 22 | return elem; 23 | } 24 | 25 | 26 | internal override SqlExpression VisitClientQuery(SqlClientQuery cq) 27 | { 28 | return cq; 29 | } 30 | 31 | 32 | internal override SqlExpression VisitExists(SqlSubSelect ss) 33 | { 34 | return ss; 35 | } 36 | 37 | 38 | internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss) 39 | { 40 | return ss; 41 | } 42 | 43 | 44 | internal override SqlSelect VisitSelect(SqlSelect select) 45 | { 46 | // big-joins may need to lift PK's out for default ordering, so don't allow big-join if we see these 47 | this.canBigJoin &= select.GroupBy.Count == 0 && select.Top == null && !select.IsDistinct; 48 | if(!this.canBigJoin) 49 | { 50 | return select; 51 | } 52 | return base.VisitSelect(select); 53 | } 54 | } 55 | 56 | #endregion 57 | 58 | internal static bool CanBigJoin(SqlSelect select) 59 | { 60 | Visitor v = new Visitor(); 61 | v.Visit(select); 62 | return v.canBigJoin; 63 | } 64 | 65 | } 66 | } -------------------------------------------------------------------------------- /src/Provider/Common/CompatibilityAnnotation.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace System.Data.Linq.Provider.Common 4 | { 5 | 6 | /// 7 | /// Annotation which indicates that the given node will cause a compatibility problem 8 | /// for the indicated set of provider modes. 9 | /// 10 | internal class CompatibilityAnnotation : SqlNodeAnnotation 11 | { 12 | private Enum[] _providerModes; 13 | 14 | /// 15 | /// Constructor 16 | /// 17 | /// The compatibility message. 18 | /// The set of providers this compatibility issue applies to. 19 | internal CompatibilityAnnotation(string message, params Enum[] providerModes) 20 | : base(message) 21 | { 22 | _providerModes = providerModes; 23 | } 24 | 25 | 26 | /// 27 | /// Returns true if this annotation applies to the specified provider. 28 | /// 29 | internal bool AppliesTo(Enum provider) 30 | { 31 | return _providerModes.Any(p=>p.Equals(provider)); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Provider/Common/CompiledSubQuery.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.ObjectModel; 3 | using System.Data.Linq.Provider.Interfaces; 4 | 5 | namespace System.Data.Linq.Provider.Common 6 | { 7 | internal class CompiledSubQuery : ICompiledSubQuery 8 | { 9 | QueryInfo queryInfo; 10 | IObjectReaderFactory factory; 11 | ReadOnlyCollection parameters; 12 | ICompiledSubQuery[] subQueries; 13 | 14 | internal CompiledSubQuery(QueryInfo queryInfo, IObjectReaderFactory factory, ReadOnlyCollection parameters, 15 | ICompiledSubQuery[] subQueries) 16 | { 17 | this.queryInfo = queryInfo; 18 | this.factory = factory; 19 | this.parameters = parameters; 20 | this.subQueries = subQueries; 21 | } 22 | 23 | public IExecuteResult Execute(IProvider provider, object[] parentArgs, object[] userArgs) 24 | { 25 | if(parentArgs == null && !(this.parameters == null || this.parameters.Count == 0)) 26 | { 27 | throw Error.ArgumentNull("arguments"); 28 | } 29 | 30 | // construct new copy of query info 31 | List spis = new List(this.queryInfo.Parameters); 32 | 33 | // add call arguments 34 | for(int i = 0, n = this.parameters.Count; i < n; i++) 35 | { 36 | spis.Add(new SqlParameterInfo(this.parameters[i], parentArgs[i])); 37 | } 38 | 39 | QueryInfo qi = new QueryInfo( 40 | this.queryInfo.Query, 41 | this.queryInfo.CommandText, 42 | spis.AsReadOnly(), 43 | this.queryInfo.ResultShape, 44 | this.queryInfo.ResultType 45 | ); 46 | 47 | // execute query 48 | return provider.Execute(null, qi, this.factory, parentArgs, userArgs, subQueries, null); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /src/Provider/Common/DbFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Linq.Provider.NodeTypes; 4 | using System.Text; 5 | 6 | namespace System.Data.Linq.Provider.Common { 7 | internal abstract class DbFormatter { 8 | internal abstract string Format(SqlNode node, bool isDebug); 9 | internal abstract string Format(SqlNode node); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Provider/Common/Group.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace System.Data.Linq.Provider.Common 6 | { 7 | internal class Group : IGrouping, IEnumerable, IEnumerable 8 | { 9 | #region Member Declarations 10 | private K key; 11 | private IEnumerable items; 12 | #endregion 13 | 14 | internal Group(K key, IEnumerable items) 15 | { 16 | this.key = key; 17 | this.items = items; 18 | } 19 | 20 | K IGrouping.Key 21 | { 22 | get { return this.key; } 23 | } 24 | 25 | IEnumerator IEnumerable.GetEnumerator() 26 | { 27 | return (IEnumerator)this.GetEnumerator(); 28 | } 29 | 30 | public IEnumerator GetEnumerator() 31 | { 32 | return this.items.GetEnumerator(); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Provider/Common/HierarchyChecker.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | using System.Data.Linq.Provider.Visitors; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | internal class HierarchyChecker 7 | { 8 | internal static bool HasHierarchy(SqlExpression expr) 9 | { 10 | QueryHierarchyFinder v = new QueryHierarchyFinder(); 11 | v.Visit(expr); 12 | return v.FoundHierarchy; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Provider/Common/LinkOptimizationScope.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | internal class LinkOptimizationScope 7 | { 8 | Dictionary map; 9 | LinkOptimizationScope previous; 10 | 11 | internal LinkOptimizationScope(LinkOptimizationScope previous) { 12 | this.previous = previous; 13 | } 14 | internal void Add(object linkId, SqlExpression expr) { 15 | if (this.map == null) { 16 | this.map = new Dictionary(); 17 | } 18 | this.map.Add(linkId, expr); 19 | } 20 | internal bool TryGetValue(object linkId, out SqlExpression expr) { 21 | expr = null; 22 | return (this.map != null && this.map.TryGetValue(linkId, out expr)) || 23 | (this.previous != null && this.previous.TryGetValue(linkId, out expr)); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/Provider/Common/MultisetChecker.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | using System.Data.Linq.Provider.Visitors; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | internal class MultisetChecker 7 | { 8 | internal static bool HasMultiset(SqlExpression expr) 9 | { 10 | MultiSetDetector v = new MultiSetDetector(); 11 | v.Visit(expr); 12 | return v.FoundMultiset; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Provider/Common/NamedColumn.cs: -------------------------------------------------------------------------------- 1 | namespace System.Data.Linq.Provider.Common 2 | { 3 | internal struct NamedColumn 4 | { 5 | string name; 6 | bool isRequired; 7 | internal NamedColumn(string name, bool isRequired) 8 | { 9 | this.name = name; 10 | this.isRequired = isRequired; 11 | } 12 | internal string Name 13 | { 14 | get { return this.name; } 15 | } 16 | internal bool IsRequired 17 | { 18 | get { return this.isRequired; } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Provider/Common/ObjectReaderFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | using System.Data.Linq.Provider.Interfaces; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | internal class ObjectReaderFactory : IObjectReaderFactory 7 | where TDataReader : DbDataReader 8 | { 9 | #region Member Declarations 10 | private Func, TObject> _materializeFunc; 11 | private NamedColumn[] _namedColumns; 12 | private object[] _globals; 13 | private int _numberOfLocals; 14 | #endregion 15 | 16 | internal ObjectReaderFactory(Func, TObject> materializeFunc, NamedColumn[] namedColumns, object[] globals, int numberOfLocals) 17 | { 18 | _materializeFunc = materializeFunc; 19 | _namedColumns = namedColumns; 20 | _globals = globals; 21 | _numberOfLocals = numberOfLocals; 22 | } 23 | 24 | public IObjectReader Create(DbDataReader dataReader, bool disposeDataReader, IReaderProvider provider, object[] parentArgs, object[] userArgs, ICompiledSubQuery[] subQueries) 25 | { 26 | ObjectReaderSession session = new ObjectReaderSession((TDataReader)dataReader, provider, parentArgs, userArgs, subQueries); 27 | return session.CreateReader(_materializeFunc, _namedColumns, _globals, _numberOfLocals, disposeDataReader); 28 | } 29 | 30 | public IObjectReader GetNextResult(IObjectReaderSession session, bool disposeDataReader) 31 | { 32 | ObjectReaderSession ors = (ObjectReaderSession)session; 33 | IObjectReader reader = ors.GetNextResult(_materializeFunc, _namedColumns, _globals, _numberOfLocals, disposeDataReader); 34 | if(reader == null && disposeDataReader) 35 | { 36 | ors.Dispose(); 37 | } 38 | return reader; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/Provider/Common/OneTimeEnumerable.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | internal class OneTimeEnumerable : IEnumerable, IEnumerable 7 | { 8 | IEnumerator enumerator; 9 | 10 | internal OneTimeEnumerable(IEnumerator enumerator) 11 | { 12 | Diagnostics.Debug.Assert(enumerator != null); 13 | this.enumerator = enumerator; 14 | } 15 | 16 | public IEnumerator GetEnumerator() 17 | { 18 | if(this.enumerator == null) 19 | { 20 | throw Error.CannotEnumerateResultsMoreThanOnce(); 21 | } 22 | IEnumerator e = this.enumerator; 23 | this.enumerator = null; 24 | return e; 25 | } 26 | 27 | IEnumerator IEnumerable.GetEnumerator() 28 | { 29 | return this.GetEnumerator(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/Provider/Common/OrderedResults.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace System.Data.Linq.Provider.Common 6 | { 7 | internal class OrderedResults : IOrderedEnumerable, IEnumerable 8 | { 9 | #region Member Declarations 10 | private List values; 11 | #endregion 12 | 13 | internal OrderedResults(IEnumerable results) 14 | { 15 | this.values = results as List; 16 | if(this.values == null) 17 | this.values = new List(results); 18 | } 19 | IOrderedEnumerable IOrderedEnumerable.CreateOrderedEnumerable(Func keySelector, IComparer comparer, bool descending) 20 | { 21 | throw Error.NotSupported(); 22 | } 23 | IEnumerator IEnumerable.GetEnumerator() 24 | { 25 | return ((IEnumerable)this.values).GetEnumerator(); 26 | } 27 | IEnumerator IEnumerable.GetEnumerator() 28 | { 29 | return this.values.GetEnumerator(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/Provider/Common/QueryExtractor.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | using System.Data.Linq.Provider.Visitors; 4 | 5 | namespace System.Data.Linq.Provider.Common 6 | { 7 | internal class QueryExtractor 8 | { 9 | internal static SqlClientQuery Extract(SqlSubSelect subquery, IEnumerable parentParameters) 10 | { 11 | SqlClientQuery cq = new SqlClientQuery(subquery); 12 | if(parentParameters != null) 13 | { 14 | cq.Parameters.AddRange(parentParameters); 15 | } 16 | SubSelectDuplicator v = new SubSelectDuplicator(cq.Arguments, cq.Parameters); 17 | cq.Query = (SqlSubSelect)v.Visit(subquery); 18 | return cq; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Provider/Common/QueryInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.ObjectModel; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | internal class QueryInfo 7 | { 8 | SqlNode query; 9 | string commandText; 10 | ReadOnlyCollection parameters; 11 | ResultShape resultShape; 12 | Type resultType; 13 | 14 | internal QueryInfo(SqlNode query, string commandText, ReadOnlyCollection parameters, ResultShape resultShape, Type resultType) 15 | { 16 | this.query = query; 17 | this.commandText = commandText; 18 | this.parameters = parameters; 19 | this.resultShape = resultShape; 20 | this.resultType = resultType; 21 | } 22 | internal SqlNode Query 23 | { 24 | get { return this.query; } 25 | } 26 | internal string CommandText 27 | { 28 | get { return this.commandText; } 29 | } 30 | internal ReadOnlyCollection Parameters 31 | { 32 | get { return this.parameters; } 33 | } 34 | internal ResultShape ResultShape 35 | { 36 | get { return this.resultShape; } 37 | } 38 | internal Type ResultType 39 | { 40 | get { return this.resultType; } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/Provider/Common/SequenceOfOne.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | internal class SequenceOfOne : IEnumerable, IEnumerable 7 | { 8 | T[] sequence; 9 | internal SequenceOfOne(T value) 10 | { 11 | this.sequence = new T[] { value }; 12 | } 13 | public IEnumerator GetEnumerator() 14 | { 15 | return ((IEnumerable)this.sequence).GetEnumerator(); 16 | } 17 | 18 | IEnumerator IEnumerable.GetEnumerator() 19 | { 20 | return this.GetEnumerator(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Provider/Common/SqlAliasDependencyChecker.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | using System.Data.Linq.Provider.Visitors; 4 | 5 | namespace System.Data.Linq.Provider.Common 6 | { 7 | internal static class SqlAliasDependencyChecker 8 | { 9 | internal static bool IsDependent(SqlNode node, HashSet aliasesToCheck, HashSet ignoreExpressions) 10 | { 11 | AliasDependencyChecker v = new AliasDependencyChecker(aliasesToCheck, ignoreExpressions); 12 | v.Visit(node); 13 | return v.hasDependency; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Provider/Common/SqlAliasesReferenced.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | using System.Data.Linq.Provider.Visitors; 4 | 5 | namespace System.Data.Linq.Provider.Common 6 | { 7 | internal class SqlAliasesReferenced 8 | { 9 | #region Member Declarations 10 | private HashSet aliases; 11 | private bool referencesAny; 12 | private Visitor visitor; 13 | #endregion 14 | 15 | #region Private Classes 16 | private class Visitor : SqlVisitor 17 | { 18 | SqlAliasesReferenced parent; 19 | 20 | internal Visitor(SqlAliasesReferenced parent) 21 | { 22 | this.parent = parent; 23 | } 24 | internal override SqlExpression VisitColumnRef(SqlColumnRef cref) 25 | { 26 | if(this.parent.aliases.Contains(cref.Column.Alias)) 27 | { 28 | this.parent.referencesAny = true; 29 | } 30 | else if(cref.Column.Expression != null) 31 | { 32 | this.Visit(cref.Column.Expression); 33 | } 34 | return cref; 35 | } 36 | 37 | internal override SqlExpression VisitColumn(SqlColumn col) 38 | { 39 | if(col.Expression != null) 40 | { 41 | this.Visit(col.Expression); 42 | } 43 | return col; 44 | } 45 | } 46 | #endregion 47 | 48 | internal SqlAliasesReferenced(HashSet aliases) 49 | { 50 | this.aliases = aliases; 51 | this.visitor = new Visitor(this); 52 | } 53 | 54 | internal bool ReferencesAny(SqlExpression expression) 55 | { 56 | this.referencesAny = false; 57 | this.visitor.Visit(expression); 58 | return this.referencesAny; 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /src/Provider/Common/SqlCaseSimplifier.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | using System.Data.Linq.Provider.Visitors; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | 7 | /// 8 | /// SQL with CASE statements is harder to read. This visitor attempts to reduce CASE 9 | /// statements to equivalent (but easier to read) logic. 10 | /// 11 | internal class SqlCaseSimplifier 12 | { 13 | internal static SqlNode Simplify(SqlNode node, NodeFactory sql) 14 | { 15 | return new CaseSimplifier(sql).Visit(node); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlColumnizer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Reflection; 4 | using System.Data.Linq; 5 | using System.Data.Linq.DbEngines.SqlServer; 6 | using System.Data.Linq.Mapping; 7 | using System.Data.Linq.Provider.NodeTypes; 8 | using System.Data.Linq.Provider.Visitors; 9 | using System.Linq; 10 | using System.Diagnostics; 11 | 12 | namespace System.Data.Linq.Provider.Common 13 | { 14 | // partions select expressions and common subexpressions into scalar and non-scalar pieces by 15 | // wrapping scalar pieces floating column nodes. 16 | internal class SqlColumnizer 17 | { 18 | ColumnNominator nominator; 19 | ColumnDeclarer declarer; 20 | 21 | internal SqlColumnizer() 22 | { 23 | this.nominator = new ColumnNominator(); 24 | this.declarer = new ColumnDeclarer(); 25 | } 26 | 27 | internal SqlExpression ColumnizeSelection(SqlExpression selection) 28 | { 29 | return this.declarer.Declare(selection, this.nominator.Nominate(selection)); 30 | } 31 | 32 | internal static bool CanBeColumn(SqlExpression expression) 33 | { 34 | return ColumnNominator.CanBeColumn(expression); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlDeflator.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | using System.Data.Linq.Provider.Visitors; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | internal class SqlDeflator 7 | { 8 | #region Member Declarations 9 | private SqlValueDeflator _valueDeflator; 10 | private SqlColumnDeflator _columnDeflator; 11 | private SqlAliasDeflator _aliasDeflator; 12 | private SqlTopSelectDeflator _topselectDeflator; 13 | private SqlDuplicateColumnDeflator _duplicateColumnDeflator; 14 | #endregion 15 | 16 | internal SqlDeflator() 17 | { 18 | _valueDeflator = new SqlValueDeflator(); 19 | _columnDeflator = new SqlColumnDeflator(); 20 | _aliasDeflator = new SqlAliasDeflator(); 21 | _topselectDeflator = new SqlTopSelectDeflator(); 22 | _duplicateColumnDeflator = new SqlDuplicateColumnDeflator(); 23 | } 24 | 25 | internal SqlNode Deflate(SqlNode node) 26 | { 27 | node = _valueDeflator.Visit(node); 28 | node = _columnDeflator.Visit(node); 29 | node = _aliasDeflator.Visit(node); 30 | node = _topselectDeflator.Visit(node); 31 | node = _duplicateColumnDeflator.Visit(node); 32 | return node; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlDuplicator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | using System.Data.Linq.Provider.Visitors; 4 | 5 | namespace System.Data.Linq.Provider.Common 6 | { 7 | 8 | internal class SqlDuplicator 9 | { 10 | DuplicatingVisitor superDuper; 11 | 12 | internal SqlDuplicator() 13 | : this(true) 14 | { 15 | } 16 | 17 | internal SqlDuplicator(bool ignoreExternalRefs) 18 | { 19 | this.superDuper = new DuplicatingVisitor(ignoreExternalRefs); 20 | } 21 | 22 | internal static SqlNode Copy(SqlNode node) 23 | { 24 | if(node == null) 25 | return null; 26 | switch(node.NodeType) 27 | { 28 | case SqlNodeType.ColumnRef: 29 | case SqlNodeType.Value: 30 | case SqlNodeType.Parameter: 31 | case SqlNodeType.Variable: 32 | return node; 33 | default: 34 | return new SqlDuplicator().Duplicate(node); 35 | } 36 | } 37 | 38 | internal SqlNode Duplicate(SqlNode node) 39 | { 40 | return this.superDuper.Visit(node); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlExpander.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | using System.Data.Linq.Provider.Visitors; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | 7 | /// 8 | /// duplicates an expression up until a column or column ref is encountered 9 | /// goes 'deep' through alias ref's 10 | /// assumes that columnizing has been done already 11 | /// 12 | internal class SqlExpander 13 | { 14 | NodeFactory factory; 15 | 16 | internal SqlExpander(NodeFactory factory) 17 | { 18 | this.factory = factory; 19 | } 20 | 21 | internal SqlExpression Expand(SqlExpression exp) 22 | { 23 | return (new ExpressionDuplicator(this.factory)).VisitExpression(exp); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlFlattener.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | using System.Data.Linq.Provider.Visitors; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | /// 7 | /// Class which flatten object expressions into rows 8 | /// 9 | internal class SqlFlattener 10 | { 11 | ObjectExpressionFlattener visitor; 12 | 13 | internal SqlFlattener(NodeFactory sql, SqlColumnizer columnizer) 14 | { 15 | this.visitor = new ObjectExpressionFlattener(sql, columnizer); 16 | } 17 | 18 | internal SqlNode Flatten(SqlNode node) 19 | { 20 | node = this.visitor.Visit(node); 21 | return node; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlGatherColumnsProduced.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | using System.Data.Linq.Provider.Visitors; 4 | 5 | namespace System.Data.Linq.Provider.Common 6 | { 7 | internal class SqlGatherColumnsProduced 8 | { 9 | static internal List GatherColumns(SqlSource source) 10 | { 11 | List columns = new List(); 12 | new ProducedColumnsGatherer(columns).Visit(source); 13 | return columns; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Provider/Common/SqlGatherConsumedAliases.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | using System.Data.Linq.Provider.Visitors; 4 | 5 | namespace System.Data.Linq.Provider.Common 6 | { 7 | /// 8 | /// Walk a tree and return the set of unique aliases it consumes. 9 | /// 10 | internal class SqlGatherConsumedAliases 11 | { 12 | internal static HashSet Gather(SqlNode node) 13 | { 14 | ConsumedAliaseGatherer g = new ConsumedAliaseGatherer(); 15 | g.Visit(node); 16 | return g.Consumed; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlGatherProducedAliases.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | using System.Data.Linq.Provider.Visitors; 4 | 5 | namespace System.Data.Linq.Provider.Common 6 | { 7 | /// 8 | /// Walk a tree and return the set of unique aliases it produces. 9 | /// 10 | internal class SqlGatherProducedAliases 11 | { 12 | internal static HashSet Gather(SqlNode node) 13 | { 14 | ProducedAliasGatherer g = new ProducedAliasGatherer(); 15 | g.Visit(node); 16 | return g.Produced; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlGatherReferencedColumns.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | using System.Data.Linq.Provider.Visitors; 4 | 5 | namespace System.Data.Linq.Provider.Common 6 | { 7 | internal static class SqlGatherReferencedColumns 8 | { 9 | #region Private Classes 10 | private class Visitor : SqlVisitor 11 | { 12 | HashSet columns; 13 | internal Visitor(HashSet columns) 14 | { 15 | this.columns = columns; 16 | } 17 | internal override SqlExpression VisitColumnRef(SqlColumnRef cref) 18 | { 19 | if(!this.columns.Contains(cref.Column)) 20 | { 21 | this.columns.Add(cref.Column); 22 | if(cref.Column.Expression != null) 23 | { 24 | this.Visit(cref.Column.Expression); 25 | } 26 | } 27 | return cref; 28 | } 29 | } 30 | #endregion 31 | 32 | internal static HashSet Gather(SqlNode node, HashSet columns) 33 | { 34 | Visitor v = new Visitor(columns); 35 | v.Visit(node); 36 | return columns; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/Provider/Common/SqlLiftIndependentRowExpressions.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | using System.Data.Linq.Provider.Visitors; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | 7 | /// 8 | /// Find projection expressions on the right side of CROSS APPLY that do not 9 | /// depend exclusively on right side productions and move them outside of the 10 | /// CROSS APPLY by enclosing the CROSS APPLY with a new source. 11 | /// 12 | internal class SqlLiftIndependentRowExpressions 13 | { 14 | internal static SqlNode Lift(SqlNode node) 15 | { 16 | ColumnLifter cl = new ColumnLifter(); 17 | node = cl.Visit(node); 18 | return node; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlLiftWhereClauses.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Common 4 | { 5 | 6 | /// 7 | /// Hoist WHERE clauses as close to the root as possible. 8 | /// 9 | internal class SqlLiftWhereClauses 10 | { 11 | internal static SqlNode Lift(SqlNode node, NodeFactory factory) 12 | { 13 | return new WhereClauseLifter(factory).Visit(node); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlMultiplexer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | using System.Data.Linq.Provider.Visitors; 4 | 5 | namespace System.Data.Linq.Provider.Common 6 | { 7 | /// 8 | /// convert multiset & element expressions into separate queries 9 | /// 10 | internal class SqlMultiplexer 11 | { 12 | MultiSetMultiPlexer _multiSetMultiPlexor; 13 | 14 | internal SqlMultiplexer(SqlMultiplexerOptionType options, IEnumerable parentParameters, NodeFactory sqlFactory) 15 | { 16 | this._multiSetMultiPlexor = new MultiSetMultiPlexer(options, parentParameters, sqlFactory); 17 | } 18 | 19 | internal SqlNode Multiplex(SqlNode node) 20 | { 21 | return this._multiSetMultiPlexor.Visit(node); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlNamer.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | using System.Data.Linq.Provider.Visitors; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | 7 | internal class SqlNamer 8 | { 9 | private NameAssigner visitor; 10 | 11 | internal SqlNamer() 12 | { 13 | this.visitor = new NameAssigner(); 14 | } 15 | 16 | internal SqlNode AssignNames(SqlNode node) 17 | { 18 | return this.visitor.Visit(node); 19 | } 20 | 21 | internal static string DiscoverName(SqlExpression e) 22 | { 23 | if(e != null) 24 | { 25 | switch(e.NodeType) 26 | { 27 | case SqlNodeType.Column: 28 | return DiscoverName(((SqlColumn)e).Expression); 29 | case SqlNodeType.ColumnRef: 30 | SqlColumnRef cref = (SqlColumnRef)e; 31 | if(cref.Column.Name != null) return cref.Column.Name; 32 | return DiscoverName(cref.Column); 33 | case SqlNodeType.ExprSet: 34 | SqlExprSet eset = (SqlExprSet)e; 35 | return DiscoverName(eset.Expressions[0]); 36 | } 37 | } 38 | return "value"; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlNodeAnnotation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace System.Data.Linq.Provider.Common { 6 | 7 | /// 8 | /// Annotation about a particular SqlNode. 9 | /// 10 | internal abstract class SqlNodeAnnotation { 11 | string message; 12 | internal SqlNodeAnnotation(string message) { 13 | this.message = message; 14 | } 15 | internal string Message { 16 | get {return this.message;} 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlParameterInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Common 4 | { 5 | internal class SqlParameterInfo 6 | { 7 | #region Member Declarations 8 | private SqlParameter parameter; 9 | private object value; 10 | private Delegate accessor; 11 | #endregion 12 | 13 | internal SqlParameterInfo(SqlParameter parameter, Delegate accessor) 14 | { 15 | this.parameter = parameter; 16 | this.accessor = accessor; 17 | } 18 | internal SqlParameterInfo(SqlParameter parameter, object value) 19 | { 20 | this.parameter = parameter; 21 | this.value = value; 22 | } 23 | internal SqlParameterInfo(SqlParameter parameter) 24 | { 25 | this.parameter = parameter; 26 | } 27 | 28 | internal SqlParameterType Type 29 | { 30 | get 31 | { 32 | if(this.accessor != null) 33 | { 34 | return SqlParameterType.UserArgument; 35 | } 36 | #warning [FB] REFACTOR: SQL SERVER SPECIFIC 37 | if(this.parameter.Name == "@ROWCOUNT") 38 | { 39 | return SqlParameterType.PreviousResult; 40 | } 41 | return SqlParameterType.Value; 42 | } 43 | } 44 | internal SqlParameter Parameter 45 | { 46 | get { return this.parameter; } 47 | } 48 | internal Delegate Accessor 49 | { 50 | get { return this.accessor; } 51 | } 52 | internal object Value 53 | { 54 | get { return this.value; } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/Provider/Common/SqlPredicateLifter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | using System.Data.Linq.Provider.Visitors; 4 | 5 | namespace System.Data.Linq.Provider.Common 6 | { 7 | internal static class SqlPredicateLifter 8 | { 9 | internal static bool CanLift(SqlSource source, HashSet aliasesForLifting, HashSet liftedExpressions) 10 | { 11 | Diagnostics.Debug.Assert(source != null); 12 | Diagnostics.Debug.Assert(aliasesForLifting != null); 13 | PredicateLifter v = new PredicateLifter(false, aliasesForLifting, liftedExpressions); 14 | v.VisitSource(source); 15 | return v.CanLiftAll; 16 | } 17 | 18 | internal static SqlExpression Lift(SqlSource source, HashSet aliasesForLifting) 19 | { 20 | Diagnostics.Debug.Assert(source != null); 21 | Diagnostics.Debug.Assert(aliasesForLifting != null); 22 | PredicateLifter v = new PredicateLifter(true, aliasesForLifting, null); 23 | v.VisitSource(source); 24 | return v.Lifted; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Provider/Common/SqlRemoveConstantOrderBy.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | using System.Data.Linq.Provider.Visitors; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | /// 7 | /// SQL doesn't allow constants in ORDER BY. 8 | /// 9 | /// Worse, an integer constant greater than 0 is treated as ORDER BY ProjectionColumn[i] so the results 10 | /// can be unexpected. 11 | /// 12 | /// The LINQ semantic for OrderBy(o=>constant) is for it to have no effect on the ordering. We enforce 13 | /// that semantic here by removing all constant columns from OrderBy. 14 | /// 15 | internal class SqlRemoveConstantOrderBy 16 | { 17 | /// 18 | /// Remove relative constants from OrderBy. 19 | /// 20 | internal static SqlNode Remove(SqlNode node) 21 | { 22 | return new ConstantInOrderByRemover().Visit(node); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlReorderer.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | using System.Data.Linq.Provider.Visitors; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | /// 7 | /// moves order-by clauses from sub-queries to outer-most or top selects 8 | /// removes ordering in correlated sub-queries 9 | /// 10 | internal class SqlReorderer 11 | { 12 | #region Member Declarations 13 | private TypeSystemProvider typeProvider; 14 | private NodeFactory sql; 15 | #endregion 16 | 17 | internal SqlReorderer(TypeSystemProvider typeProvider, NodeFactory sqlFactory) 18 | { 19 | this.typeProvider = typeProvider; 20 | this.sql = sqlFactory; 21 | } 22 | 23 | internal SqlNode Reorder(SqlNode node) 24 | { 25 | return new OrderByLifter(this.typeProvider, this.sql).Visit(node); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlResolver.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | using System.Data.Linq.Provider.Visitors; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | 7 | /// 8 | /// Resolves references to columns/expressions defined in other scopes 9 | /// 10 | internal class SqlResolver 11 | { 12 | Visitor visitor; 13 | 14 | #region Private Classes 15 | private class Visitor : SqlScopedVisitor 16 | { 17 | SqlBubbler bubbler; 18 | 19 | internal Visitor() 20 | { 21 | this.bubbler = new SqlBubbler(); 22 | } 23 | 24 | internal override SqlExpression VisitColumnRef(SqlColumnRef cref) 25 | { 26 | SqlColumnRef result = this.BubbleUp(cref); 27 | if(result == null) 28 | { 29 | throw Error.ColumnReferencedIsNotInScope(GetColumnName(cref.Column)); 30 | } 31 | return result; 32 | } 33 | 34 | private SqlColumnRef BubbleUp(SqlColumnRef cref) 35 | { 36 | for(SqlScope s = this.CurrentScope; s != null; s = s.ContainingScope) 37 | { 38 | if(s.Source != null) 39 | { 40 | SqlColumn found = this.bubbler.BubbleUp(cref.Column, s.Source); 41 | if(found != null) 42 | { 43 | if(found != cref.Column) 44 | return new SqlColumnRef(found); 45 | return cref; 46 | } 47 | } 48 | } 49 | return null; 50 | } 51 | } 52 | #endregion 53 | 54 | internal SqlResolver() 55 | { 56 | this.visitor = new Visitor(); 57 | } 58 | 59 | internal SqlNode Resolve(SqlNode node) 60 | { 61 | return this.visitor.Visit(node); 62 | } 63 | 64 | private static string GetColumnName(SqlColumn c) 65 | { 66 | #if DEBUG 67 | return c.Text; 68 | #else 69 | return c.Name; 70 | #endif 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlRetyper.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | using System.Data.Linq.Provider.Visitors; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | internal class SqlRetyper 7 | { 8 | TypeCorrector visitor; 9 | 10 | internal SqlRetyper(NodeFactory factory) 11 | { 12 | this.visitor = new TypeCorrector(factory); 13 | } 14 | 15 | internal SqlNode Retype(SqlNode node) 16 | { 17 | return this.visitor.Visit(node); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlRewriteScalarSubqueries.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | using System.Data.Linq.Provider.Visitors; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | /// 7 | /// converts correlated scalar subqueries into outer-applies 8 | /// 9 | /// must be run after flattener. 10 | internal class SqlRewriteScalarSubqueries 11 | { 12 | ScalarSubQueryRewriter visitor; 13 | 14 | internal SqlRewriteScalarSubqueries(NodeFactory sqlFactory) 15 | { 16 | this.visitor = new ScalarSubQueryRewriter(sqlFactory); 17 | } 18 | 19 | internal SqlNode Rewrite(SqlNode node) 20 | { 21 | return this.visitor.Visit(node); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Provider/Common/SqlScope.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Common 4 | { 5 | internal class SqlScope 6 | { 7 | #region Member Declarations 8 | private SqlNode source; 9 | private SqlScope containing; 10 | #endregion 11 | 12 | internal SqlScope(SqlNode source, SqlScope containing) 13 | { 14 | this.source = source; 15 | this.containing = containing; 16 | } 17 | internal SqlNode Source 18 | { 19 | get { return this.source; } 20 | } 21 | internal SqlScope ContainingScope 22 | { 23 | get { return this.containing; } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/Provider/Common/SqlSelectionLifter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | using System.Data.Linq.Provider.Visitors; 4 | 5 | namespace System.Data.Linq.Provider.Common 6 | { 7 | internal static class SqlSelectionLifter 8 | { 9 | internal static bool CanLift(SqlSource source, HashSet aliasesForLifting, HashSet liftedExpressions) 10 | { 11 | SelectionLifter v = new SelectionLifter(false, aliasesForLifting, liftedExpressions); 12 | v.VisitSource(source); 13 | return v.CanLiftAll; 14 | } 15 | 16 | internal static List> Lift(SqlSource source, HashSet aliasesForLifting, HashSet liftedExpressions) 17 | { 18 | SelectionLifter v = new SelectionLifter(true, aliasesForLifting, liftedExpressions); 19 | v.VisitSource(source); 20 | return v.Lifted; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Provider/Common/SqlUnionizer.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | using System.Data.Linq.Provider.Visitors; 3 | 4 | namespace System.Data.Linq.Provider.Common 5 | { 6 | internal class SqlUnionizer 7 | { 8 | internal static SqlNode Unionize(SqlNode node) 9 | { 10 | return new QueryUnionizer().Visit(node); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Provider/Expressions/InternalExpression.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Data.SqlClient; 5 | using System.Linq.Expressions; 6 | using System.Linq; 7 | using System.Reflection; 8 | using System.Text; 9 | using System.Data.Linq; 10 | using System.Data.Linq.Provider.NodeTypes; 11 | 12 | namespace System.Data.Linq.Provider.Expressions { 13 | 14 | // SQL Client extensions to ExpressionType 15 | 16 | abstract internal class InternalExpression : Expression { 17 | #pragma warning disable 618 // Disable the 'obsolete' warning. 18 | internal InternalExpression(InternalExpressionType nt, Type type) 19 | : base ((ExpressionType)nt, type) { 20 | } 21 | #pragma warning restore 618 22 | internal static KnownExpression Known(SqlExpression expr) { 23 | return new KnownExpression(expr, expr.ClrType); 24 | } 25 | internal static KnownExpression Known(SqlNode node, Type type) { 26 | return new KnownExpression(node, type); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Provider/Expressions/KnownExpression.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Expressions 4 | { 5 | internal sealed class KnownExpression : InternalExpression { 6 | SqlNode node; 7 | internal KnownExpression(SqlNode node, Type type) 8 | : base(InternalExpressionType.Known, type) { 9 | this.node = node; 10 | } 11 | internal SqlNode Node { 12 | get { return this.node; } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Provider/Expressions/LinkedTableExpression.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Expressions 4 | { 5 | internal sealed class LinkedTableExpression : InternalExpression { 6 | private SqlLink link; 7 | private ITable table; 8 | internal LinkedTableExpression(SqlLink link, ITable table, Type type) 9 | : base(InternalExpressionType.LinkedTable, type) { 10 | this.link = link; 11 | this.table = table; 12 | } 13 | internal SqlLink Link { 14 | get {return this.link;} 15 | } 16 | internal ITable Table { 17 | get {return this.table;} 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Provider/Interfaces/ICompiledSubQuery.cs: -------------------------------------------------------------------------------- 1 | namespace System.Data.Linq.Provider.Interfaces 2 | { 3 | internal interface ICompiledSubQuery { 4 | IExecuteResult Execute(IProvider provider, object[] parentArgs, object[] userArgs); 5 | } 6 | } -------------------------------------------------------------------------------- /src/Provider/Interfaces/IConnectionManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data; 3 | using System.Data.Common; 4 | 5 | namespace System.Data.Linq.Provider.Interfaces 6 | { 7 | 8 | internal interface IConnectionManager 9 | { 10 | DbConnection UseConnection(IConnectionUser user); 11 | void ReleaseConnection(IConnectionUser user); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Provider/Interfaces/IConnectionUser.cs: -------------------------------------------------------------------------------- 1 | namespace System.Data.Linq.Provider.Interfaces 2 | { 3 | /// 4 | /// Interface for objects which use a connection at a given time T, e.g. an active data reader. 5 | /// 6 | internal interface IConnectionUser 7 | { 8 | void CompleteUse(); 9 | } 10 | } -------------------------------------------------------------------------------- /src/Provider/Interfaces/IObjectReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | using System.Data; 6 | using System.Linq.Expressions; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Reflection; 10 | using System.Text; 11 | using System.Globalization; 12 | using System.Data.Linq; 13 | 14 | namespace System.Data.Linq.Provider.Interfaces 15 | { 16 | 17 | internal interface IObjectReader : IEnumerator, IDisposable { 18 | IObjectReaderSession Session { get; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Provider/Interfaces/IObjectReaderCompiler.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | 4 | namespace System.Data.Linq.Provider.Interfaces 5 | { 6 | internal interface IObjectReaderCompiler { 7 | IObjectReaderFactory Compile(SqlExpression expression, Type elementType); 8 | IObjectReaderSession CreateSession(DbDataReader reader, IReaderProvider provider, object[] parentArgs, object[] userArgs, ICompiledSubQuery[] subQueries); 9 | } 10 | } -------------------------------------------------------------------------------- /src/Provider/Interfaces/IObjectReaderFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Common; 2 | 3 | namespace System.Data.Linq.Provider.Interfaces 4 | { 5 | internal interface IObjectReaderFactory { 6 | IObjectReader Create(DbDataReader reader, bool disposeReader, IReaderProvider provider, object[] parentArgs, object[] userArgs, ICompiledSubQuery[] subQueries); 7 | IObjectReader GetNextResult(IObjectReaderSession session, bool disposeReader); 8 | } 9 | } -------------------------------------------------------------------------------- /src/Provider/Interfaces/IObjectReaderSession.cs: -------------------------------------------------------------------------------- 1 | namespace System.Data.Linq.Provider.Interfaces 2 | { 3 | internal interface IObjectReaderSession : IConnectionUser, IDisposable { 4 | bool IsBuffered { get; } 5 | void Buffer(); 6 | } 7 | } -------------------------------------------------------------------------------- /src/Provider/Interfaces/IReaderProvider.cs: -------------------------------------------------------------------------------- 1 | namespace System.Data.Linq.Provider.Interfaces 2 | { 3 | internal interface IReaderProvider : IProvider { 4 | IDataServices Services { get; } 5 | IConnectionManager ConnectionManager { get; } 6 | } 7 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlAlias.cs: -------------------------------------------------------------------------------- 1 | namespace System.Data.Linq.Provider.NodeTypes 2 | { 3 | internal class SqlAlias : SqlSource { 4 | private string name; 5 | private SqlNode node; 6 | 7 | internal SqlAlias(SqlNode node) 8 | : base(SqlNodeType.Alias, node.SourceExpression) { 9 | this.Node = node; 10 | } 11 | 12 | internal string Name { 13 | get { return this.name; } 14 | set { this.name = value; } 15 | } 16 | 17 | internal SqlNode Node { 18 | get { return this.node; } 19 | set { 20 | if (value == null) 21 | throw Error.ArgumentNull("value"); 22 | if (!(value is SqlExpression || value is SqlSelect || value is SqlTable || value is SqlUnion)) 23 | throw Error.UnexpectedNode(value.NodeType); 24 | this.node = value; 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlAssign.cs: -------------------------------------------------------------------------------- 1 | using System.Linq.Expressions; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal class SqlAssign : SqlStatement { 6 | private SqlExpression leftValue; 7 | private SqlExpression rightValue; 8 | 9 | internal SqlAssign(SqlExpression lValue, SqlExpression rValue, Expression sourceExpression) 10 | : base(SqlNodeType.Assign, sourceExpression) { 11 | this.LValue = lValue; 12 | this.RValue = rValue; 13 | } 14 | 15 | internal SqlExpression LValue { 16 | get { return this.leftValue; } 17 | set { 18 | if (value == null) 19 | throw Error.ArgumentNull("value"); 20 | if (this.rightValue != null && !value.ClrType.IsAssignableFrom(this.rightValue.ClrType)) 21 | throw Error.ArgumentWrongType("value", this.rightValue.ClrType, value.ClrType); 22 | this.leftValue = value; 23 | } 24 | } 25 | 26 | internal SqlExpression RValue { 27 | get { return this.rightValue; } 28 | set { 29 | if (value == null) 30 | throw Error.ArgumentNull("value"); 31 | if (this.leftValue != null && !this.leftValue.ClrType.IsAssignableFrom(value.ClrType)) 32 | throw Error.ArgumentWrongType("value", this.leftValue.ClrType, value.ClrType); 33 | this.rightValue = value; 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlBetween.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlBetween : SqlSimpleTypeExpression { 7 | SqlExpression expression; 8 | SqlExpression start; 9 | SqlExpression end; 10 | 11 | internal SqlBetween(Type clrType, ProviderType sqlType, SqlExpression expr, SqlExpression start, SqlExpression end, Expression source) 12 | : base(SqlNodeType.Between, clrType, sqlType, source) { 13 | this.expression = expr; 14 | this.start = start; 15 | this.end = end; 16 | } 17 | 18 | internal SqlExpression Expression { 19 | get { return this.expression; } 20 | set { this.expression = value; } 21 | } 22 | 23 | internal SqlExpression Start { 24 | get { return this.start; } 25 | set { this.start = value; } 26 | } 27 | 28 | internal SqlExpression End { 29 | get { return this.end; } 30 | set { this.end = value; } 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlBlock.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlBlock : SqlStatement { 7 | private List statements; 8 | 9 | internal SqlBlock(Expression sourceExpression) 10 | : base(SqlNodeType.Block, sourceExpression) { 11 | this.statements = new List(); 12 | } 13 | 14 | internal List Statements { 15 | get { return this.statements; } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlClientArray.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.Common; 3 | using System.Linq.Expressions; 4 | 5 | namespace System.Data.Linq.Provider.NodeTypes 6 | { 7 | internal class SqlClientArray : SqlSimpleTypeExpression { 8 | private List expressions; 9 | 10 | internal SqlClientArray(Type clrType, ProviderType sqlType, SqlExpression[ ] exprs, Expression sourceExpression) 11 | : base(SqlNodeType.ClientArray, clrType, sqlType, sourceExpression) { 12 | this.expressions = new List(); 13 | if (exprs != null) 14 | this.Expressions.AddRange(exprs); 15 | } 16 | 17 | internal List Expressions { 18 | get { return this.expressions; } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlClientCase.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.Common; 3 | using System.Linq.Expressions; 4 | 5 | namespace System.Data.Linq.Provider.NodeTypes 6 | { 7 | /// 8 | /// A case statement that must be evaluated on the client. For example, a case statement 9 | /// that contains values of LINK, Element, or Multi-set are not directly handleable by 10 | /// SQL. 11 | /// 12 | /// CASE inputExpression 13 | /// WHEN whenExpression THEN resultExpression 14 | /// [ ...n ] 15 | /// END 16 | /// 17 | internal class SqlClientCase : SqlExpression { 18 | private SqlExpression expression; 19 | private List whens = new List(); 20 | 21 | internal SqlClientCase(Type clrType, SqlExpression expr, IEnumerable whens, Expression sourceExpression) 22 | : base(SqlNodeType.ClientCase, clrType, sourceExpression) { 23 | this.Expression = expr; 24 | if (whens == null) 25 | throw Error.ArgumentNull("whens"); 26 | this.whens.AddRange(whens); 27 | if (this.whens.Count == 0) 28 | throw Error.ArgumentOutOfRange("whens"); 29 | } 30 | 31 | internal SqlExpression Expression { 32 | get { return this.expression; } 33 | set { 34 | if (value == null) 35 | throw Error.ArgumentNull("value"); 36 | if (this.expression != null && this.expression.ClrType != value.ClrType) 37 | throw Error.ArgumentWrongType("value", this.expression.ClrType, value.ClrType); 38 | this.expression = value; 39 | } 40 | } 41 | 42 | internal List Whens { 43 | get { return this.whens; } 44 | } 45 | 46 | internal override ProviderType SqlType { 47 | get { return this.whens[0].Value.SqlType; } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlClientParameter.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlClientParameter : SqlSimpleTypeExpression { 7 | // Expression> 8 | LambdaExpression accessor; 9 | internal SqlClientParameter(Type clrType, ProviderType sqlType, LambdaExpression accessor, Expression sourceExpression): 10 | base(SqlNodeType.ClientParameter, clrType, sqlType, sourceExpression) { 11 | this.accessor = accessor; 12 | } 13 | internal LambdaExpression Accessor { 14 | get { return this.accessor; } 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlClientQuery.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal class SqlClientQuery : SqlSimpleTypeExpression { 6 | private SqlSubSelect query; 7 | private List arguments; 8 | private List parameters; 9 | int ordinal; 10 | 11 | internal SqlClientQuery(SqlSubSelect subquery) 12 | : base(SqlNodeType.ClientQuery, subquery.ClrType, subquery.SqlType, subquery.SourceExpression) { 13 | this.query = subquery; 14 | this.arguments = new List(); 15 | this.parameters = new List(); 16 | } 17 | 18 | internal SqlSubSelect Query { 19 | get { return this.query; } 20 | set { 21 | if (value == null || (this.query != null && this.query.ClrType != value.ClrType)) 22 | throw Error.ArgumentWrongType(value, this.query.ClrType, value.ClrType); 23 | this.query = value; 24 | } 25 | } 26 | 27 | internal List Arguments { 28 | get { return this.arguments; } 29 | } 30 | 31 | internal List Parameters { 32 | get { return this.parameters; } 33 | } 34 | 35 | internal int Ordinal { 36 | get { return this.ordinal; } 37 | set { this.ordinal = value; } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlClientWhen.cs: -------------------------------------------------------------------------------- 1 | namespace System.Data.Linq.Provider.NodeTypes 2 | { 3 | /// 4 | /// A single WHEN clause for ClientCase. 5 | /// 6 | internal class SqlClientWhen { 7 | private SqlExpression matchExpression; 8 | private SqlExpression matchValue; 9 | 10 | internal SqlClientWhen(SqlExpression match, SqlExpression value) { 11 | // 'match' may be null when this when represents the ELSE condition. 12 | if (value == null) 13 | throw Error.ArgumentNull("value"); 14 | this.Match = match; 15 | this.Value = value; 16 | } 17 | 18 | internal SqlExpression Match { 19 | get { return this.matchExpression; } 20 | set { 21 | if (this.matchExpression != null && value != null && this.matchExpression.ClrType != value.ClrType) 22 | throw Error.ArgumentWrongType("value", this.matchExpression.ClrType, value.ClrType); 23 | this.matchExpression = value; 24 | } 25 | } 26 | 27 | internal SqlExpression Value { 28 | get { return this.matchValue; } 29 | set { 30 | if (value == null) 31 | throw Error.ArgumentNull("value"); 32 | if (this.matchValue != null && this.matchValue.ClrType != value.ClrType) 33 | throw Error.ArgumentWrongType("value", this.matchValue.ClrType, value.ClrType); 34 | this.matchValue = value; 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlColumnRef.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal class SqlColumnRef : SqlExpression { 6 | private SqlColumn column; 7 | internal SqlColumnRef(SqlColumn col) 8 | : base(SqlNodeType.ColumnRef, col.ClrType, col.SourceExpression) { 9 | this.column = col; 10 | } 11 | 12 | internal SqlColumn Column { 13 | get { return this.column; } 14 | } 15 | 16 | internal override ProviderType SqlType { 17 | get { return this.column.SqlType; } 18 | } 19 | 20 | public override bool Equals(object obj) { 21 | SqlColumnRef cref = obj as SqlColumnRef; 22 | return cref != null && cref.Column == this.column; 23 | } 24 | 25 | public override int GetHashCode() { 26 | return this.column.GetHashCode(); 27 | } 28 | 29 | internal SqlColumn GetRootColumn() { 30 | SqlColumn c = this.column; 31 | while (c.Expression != null && c.Expression.NodeType == SqlNodeType.ColumnRef) { 32 | c = ((SqlColumnRef)c.Expression).Column; 33 | } 34 | return c; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlDelete.cs: -------------------------------------------------------------------------------- 1 | using System.Linq.Expressions; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal class SqlDelete : SqlStatement { 6 | private SqlSelect select; 7 | 8 | internal SqlDelete(SqlSelect select, Expression sourceExpression) 9 | : base(SqlNodeType.Delete, sourceExpression) { 10 | this.Select = select; 11 | } 12 | 13 | internal SqlSelect Select { 14 | get { return this.select; } 15 | set { 16 | if (value == null) 17 | throw Error.ArgumentNull("value"); 18 | this.select = value; 19 | } 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlDiscriminatedType.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Mapping; 2 | using System.Data.Linq.Provider.Common; 3 | using System.Linq.Expressions; 4 | 5 | namespace System.Data.Linq.Provider.NodeTypes 6 | { 7 | /// 8 | /// Represents a dynamic CLR type that is chosen based on a discriminator expression. 9 | /// 10 | internal class SqlDiscriminatedType : SqlExpression { 11 | private ProviderType sqlType; 12 | private SqlExpression discriminator; 13 | private MetaType targetType; 14 | internal SqlDiscriminatedType(ProviderType sqlType, SqlExpression discriminator, MetaType targetType, Expression sourceExpression) 15 | : base(SqlNodeType.DiscriminatedType, 16 | typeof(Type), 17 | sourceExpression) { 18 | if (discriminator == null) 19 | throw Error.ArgumentNull("discriminator"); 20 | this.discriminator = discriminator; 21 | this.targetType = targetType; 22 | this.sqlType = sqlType; 23 | } 24 | internal override ProviderType SqlType { 25 | get { return this.sqlType; } 26 | } 27 | internal SqlExpression Discriminator { 28 | get { return this.discriminator; } 29 | set { this.discriminator = value; } 30 | } 31 | 32 | internal MetaType TargetType { 33 | get { return this.targetType; } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlDiscriminatorOf.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlDiscriminatorOf : SqlSimpleTypeExpression { 7 | SqlExpression obj; 8 | internal SqlDiscriminatorOf(SqlExpression obj, Type clrType, ProviderType sqlType, Expression sourceExpression) 9 | : base(SqlNodeType.DiscriminatorOf, clrType, sqlType, sourceExpression) { 10 | this.obj = obj; 11 | } 12 | internal SqlExpression Object { 13 | get { return this.obj; } 14 | set { this.obj = value; } 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlDoNotVisitExpression.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal class SqlDoNotVisitExpression : SqlExpression { 6 | private SqlExpression expression; 7 | 8 | internal SqlDoNotVisitExpression(SqlExpression expr) 9 | : base(SqlNodeType.DoNotVisit, expr.ClrType, expr.SourceExpression) { 10 | if (expr == null) 11 | throw Error.ArgumentNull("expr"); 12 | this.expression = expr; 13 | } 14 | 15 | internal SqlExpression Expression { 16 | get { return this.expression; } 17 | } 18 | 19 | internal override ProviderType SqlType { 20 | get { return this.expression.SqlType; } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlExprSet.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.Common; 3 | using System.Linq.Expressions; 4 | 5 | namespace System.Data.Linq.Provider.NodeTypes 6 | { 7 | internal class SqlExprSet : SqlExpression { 8 | private List expressions; 9 | 10 | internal SqlExprSet(Type clrType, IEnumerable exprs, Expression sourceExpression) 11 | : base(SqlNodeType.ExprSet, clrType, sourceExpression) { 12 | this.expressions = new List(exprs); 13 | } 14 | 15 | internal List Expressions { 16 | get { return this.expressions; } 17 | } 18 | 19 | /// 20 | /// Get the first non-set expression of the set by drilling 21 | /// down the left expressions. 22 | /// 23 | internal SqlExpression GetFirstExpression() { 24 | SqlExpression expr = expressions[0]; 25 | while (expr is SqlExprSet) { 26 | expr = ((SqlExprSet)expr).Expressions[0]; 27 | } 28 | return expr; 29 | } 30 | 31 | internal override ProviderType SqlType { 32 | get { return this.expressions[0].SqlType; } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlExpression.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal abstract class SqlExpression : SqlNode { 7 | private Type clrType; 8 | internal SqlExpression(SqlNodeType nodeType, Type clrType, Expression sourceExpression) 9 | : base(nodeType, sourceExpression) { 10 | this.clrType = clrType; 11 | } 12 | 13 | internal Type ClrType { 14 | get { return this.clrType; } 15 | } 16 | 17 | // note: changing the CLR type of a node is potentially dangerous 18 | internal void SetClrType(Type type) { 19 | this.clrType = type; 20 | } 21 | 22 | internal abstract ProviderType SqlType { get; } 23 | 24 | /// 25 | /// Drill down looking for a constant root expression, returning true if found. 26 | /// 27 | internal bool IsConstantColumn { 28 | get { 29 | if (this.NodeType == SqlNodeType.Column) { 30 | SqlColumn col = (SqlColumn)this; 31 | if (col.Expression != null) { 32 | return col.Expression.IsConstantColumn; 33 | } 34 | } 35 | else if (this.NodeType == SqlNodeType.ColumnRef) { 36 | return ((SqlColumnRef)this).Column.IsConstantColumn; 37 | } 38 | else if (this.NodeType == SqlNodeType.OptionalValue) { 39 | return ((SqlOptionalValue)this).Value.IsConstantColumn; 40 | } 41 | else if (this.NodeType == SqlNodeType.Value || 42 | this.NodeType == SqlNodeType.Parameter) { 43 | return true; 44 | } 45 | return false; 46 | } 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlFunctionCall.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.Common; 3 | using System.Linq.Expressions; 4 | 5 | namespace System.Data.Linq.Provider.NodeTypes 6 | { 7 | internal class SqlFunctionCall : SqlSimpleTypeExpression { 8 | private string name; 9 | private List arguments; 10 | 11 | internal SqlFunctionCall(Type clrType, ProviderType sqlType, string name, IEnumerable args , Expression source) 12 | : this(SqlNodeType.FunctionCall, clrType , sqlType, name, args, source) { 13 | } 14 | 15 | internal SqlFunctionCall(SqlNodeType nodeType, Type clrType, ProviderType sqlType, string name , IEnumerable args , Expression source) 16 | : base(nodeType, clrType, sqlType, source) { 17 | this.name = name; 18 | this.arguments = new List(args); 19 | } 20 | 21 | internal string Name { 22 | get { return this.name; } 23 | } 24 | 25 | internal List Arguments { 26 | get { return this.arguments; } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlGrouping.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlGrouping : SqlSimpleTypeExpression { 7 | private SqlExpression key; 8 | private SqlExpression group; 9 | 10 | internal SqlGrouping(Type clrType, ProviderType sqlType, SqlExpression key, SqlExpression group, Expression sourceExpression) 11 | : base(SqlNodeType.Grouping, clrType, sqlType, sourceExpression) { 12 | if (key == null) throw Error.ArgumentNull("key"); 13 | if (group == null) throw Error.ArgumentNull("group"); 14 | this.key = key; 15 | this.group = group; 16 | } 17 | 18 | internal SqlExpression Key { 19 | get { return this.key; } 20 | set { 21 | if (value == null) 22 | throw Error.ArgumentNull("value"); 23 | if (!this.key.ClrType.IsAssignableFrom(value.ClrType) 24 | && !value.ClrType.IsAssignableFrom(this.key.ClrType)) 25 | throw Error.ArgumentWrongType("value", this.key.ClrType, value.ClrType); 26 | this.key = value; 27 | } 28 | } 29 | 30 | internal SqlExpression Group { 31 | get { return this.group; } 32 | set { 33 | if (value == null) 34 | throw Error.ArgumentNull("value"); 35 | if (value.ClrType != this.group.ClrType) 36 | throw Error.ArgumentWrongType("value", this.group.ClrType, value.ClrType); 37 | this.group = value; 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlIn.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.Common; 3 | using System.Linq.Expressions; 4 | 5 | namespace System.Data.Linq.Provider.NodeTypes 6 | { 7 | internal class SqlIn : SqlSimpleTypeExpression { 8 | private SqlExpression expression; 9 | private List values; 10 | 11 | internal SqlIn(Type clrType, ProviderType sqlType, SqlExpression expression, IEnumerable values, Expression sourceExpression) 12 | :base(SqlNodeType.In, clrType, sqlType, sourceExpression) { 13 | this.expression = expression; 14 | this.values = values != null ? new List(values) : new List(0); 15 | } 16 | 17 | internal SqlExpression Expression { 18 | get { return this.expression; } 19 | set { 20 | if (value == null) { 21 | throw Error.ArgumentNull("value"); 22 | } 23 | this.expression = value; 24 | } 25 | } 26 | internal List Values { 27 | get { return this.values; } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlIncludeScope.cs: -------------------------------------------------------------------------------- 1 | using System.Linq.Expressions; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal class SqlIncludeScope : SqlNode { 6 | SqlNode child; 7 | internal SqlIncludeScope(SqlNode child, Expression sourceExpression) 8 | : base(SqlNodeType.IncludeScope, sourceExpression) { 9 | this.child = child; 10 | } 11 | internal SqlNode Child { 12 | get {return this.child;} 13 | set {this.child = value;} 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlInsert.cs: -------------------------------------------------------------------------------- 1 | using System.Linq.Expressions; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal class SqlInsert : SqlStatement { 6 | private SqlTable table; 7 | private SqlRow row; 8 | private SqlExpression expression; 9 | private SqlColumn outputKey; 10 | private bool outputToLocal; 11 | 12 | internal SqlInsert(SqlTable table, SqlExpression expr, Expression sourceExpression) 13 | : base(SqlNodeType.Insert, sourceExpression) { 14 | this.Table = table; 15 | this.Expression = expr; 16 | this.Row = new SqlRow(sourceExpression); 17 | } 18 | 19 | internal SqlTable Table { 20 | get { return this.table; } 21 | set { 22 | if (value == null) 23 | throw Error.ArgumentNull("null"); 24 | this.table = value; 25 | } 26 | } 27 | 28 | internal SqlRow Row { 29 | get { return this.row; } 30 | set { this.row = value; } 31 | } 32 | 33 | internal SqlExpression Expression { 34 | get { return this.expression; } 35 | set { 36 | if (value == null) 37 | throw Error.ArgumentNull("null"); 38 | if (!this.table.RowType.Type.IsAssignableFrom(value.ClrType)) 39 | throw Error.ArgumentWrongType("value", this.table.RowType, value.ClrType); 40 | this.expression = value; 41 | } 42 | } 43 | 44 | internal SqlColumn OutputKey { 45 | get { return this.outputKey; } 46 | set { this.outputKey = value; } 47 | } 48 | 49 | internal bool OutputToLocal { 50 | get { return this.outputToLocal; } 51 | set { this.outputToLocal = value; } 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlJoin.cs: -------------------------------------------------------------------------------- 1 | using System.Linq.Expressions; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal class SqlJoin : SqlSource { 6 | private SqlJoinType joinType; 7 | private SqlSource left; 8 | private SqlSource right; 9 | private SqlExpression condition; 10 | 11 | internal SqlJoin(SqlJoinType type, SqlSource left, SqlSource right, SqlExpression cond, Expression sourceExpression) 12 | : base(SqlNodeType.Join, sourceExpression) { 13 | this.JoinType = type; 14 | this.Left = left; 15 | this.Right = right; 16 | this.Condition = cond; 17 | } 18 | 19 | internal SqlJoinType JoinType { 20 | get { return this.joinType; } 21 | set { this.joinType = value; } 22 | } 23 | 24 | internal SqlSource Left { 25 | get { return this.left; } 26 | set { 27 | if (value == null) 28 | throw Error.ArgumentNull("value"); 29 | this.left = value; 30 | } 31 | } 32 | 33 | internal SqlSource Right { 34 | get { return this.right; } 35 | set { 36 | if (value == null) 37 | throw Error.ArgumentNull("value"); 38 | this.right = value; 39 | } 40 | } 41 | 42 | internal SqlExpression Condition { 43 | get { return this.condition; } 44 | set { this.condition = value; } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlJoinedCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlJoinedCollection : SqlSimpleTypeExpression { 7 | private SqlExpression expression; 8 | private SqlExpression count; 9 | 10 | internal SqlJoinedCollection(Type clrType, ProviderType sqlType, SqlExpression expression, SqlExpression count, Expression sourceExpression) 11 | : base(SqlNodeType.JoinedCollection, clrType, sqlType, sourceExpression) { 12 | this.expression = expression; 13 | this.count = count; 14 | } 15 | 16 | internal SqlExpression Expression { 17 | get { return this.expression; } 18 | set { 19 | if (value == null || this.expression != null && this.expression.ClrType != value.ClrType) 20 | throw Error.ArgumentWrongType(value, this.expression.ClrType, value.ClrType); 21 | this.expression = value; 22 | } 23 | } 24 | 25 | internal SqlExpression Count { 26 | get { return this.count; } 27 | set { 28 | if (value == null) 29 | throw Error.ArgumentNull("value"); 30 | if (value.ClrType != typeof(int)) 31 | throw Error.ArgumentWrongType(value, typeof(int), value.ClrType); 32 | this.count = value; 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlLift.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlLift : SqlExpression { 7 | internal SqlExpression liftedExpression; 8 | 9 | internal SqlLift(Type type, SqlExpression liftedExpression, Expression sourceExpression) 10 | : base(SqlNodeType.Lift, type, sourceExpression) { 11 | if (liftedExpression == null) 12 | throw Error.ArgumentNull("liftedExpression"); 13 | this.liftedExpression = liftedExpression; 14 | } 15 | 16 | internal SqlExpression Expression { 17 | get { return this.liftedExpression; } 18 | set { 19 | if (value == null) 20 | throw Error.ArgumentNull("value"); 21 | this.liftedExpression = value; 22 | } 23 | } 24 | 25 | internal override ProviderType SqlType { 26 | get { return this.liftedExpression.SqlType; } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlLike.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlLike : SqlSimpleTypeExpression { 7 | private SqlExpression expression; 8 | private SqlExpression pattern; 9 | private SqlExpression escape; 10 | 11 | internal SqlLike(Type clrType, ProviderType sqlType, SqlExpression expr, SqlExpression pattern, SqlExpression escape, Expression source) 12 | : base(SqlNodeType.Like, clrType, sqlType, source) { 13 | if (expr == null) 14 | throw Error.ArgumentNull("expr"); 15 | if (pattern == null) 16 | throw Error.ArgumentNull("pattern"); 17 | this.Expression = expr; 18 | this.Pattern = pattern; 19 | this.Escape = escape; 20 | } 21 | 22 | internal SqlExpression Expression { 23 | get { return this.expression; } 24 | set { 25 | if (value == null) 26 | throw Error.ArgumentNull("value"); 27 | if (value.ClrType != typeof(string)) 28 | throw Error.ArgumentWrongType("value", "string", value.ClrType); 29 | this.expression = value; 30 | } 31 | } 32 | 33 | internal SqlExpression Pattern { 34 | get { return this.pattern; } 35 | set { 36 | if (value == null) 37 | throw Error.ArgumentNull("value"); 38 | if (value.ClrType != typeof(string)) 39 | throw Error.ArgumentWrongType("value", "string", value.ClrType); 40 | this.pattern = value; 41 | } 42 | } 43 | 44 | internal SqlExpression Escape { 45 | get { return this.escape; } 46 | set { 47 | if (value != null && value.ClrType != typeof(string)) 48 | throw Error.ArgumentWrongType("value", "string", value.ClrType); 49 | this.escape = value; 50 | } 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlLink.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Mapping; 3 | using System.Data.Linq.Provider.Common; 4 | using System.Linq.Expressions; 5 | 6 | namespace System.Data.Linq.Provider.NodeTypes 7 | { 8 | internal class SqlLink : SqlSimpleTypeExpression { 9 | private MetaType rowType; 10 | private SqlExpression expression; 11 | private MetaDataMember member; 12 | private List keyExpressions; 13 | private SqlExpression expansion; 14 | private object id; 15 | 16 | internal SqlLink(object id, MetaType rowType, Type clrType, ProviderType sqlType, SqlExpression expression, MetaDataMember member, IEnumerable keyExpressions, SqlExpression expansion, Expression sourceExpression) 17 | : base(SqlNodeType.Link, clrType, sqlType, sourceExpression) { 18 | this.id = id; 19 | this.rowType = rowType; 20 | this.expansion = expansion; 21 | this.expression = expression; 22 | this.member = member; 23 | this.keyExpressions = new List(); 24 | if (keyExpressions != null) 25 | this.keyExpressions.AddRange(keyExpressions); 26 | } 27 | 28 | internal MetaType RowType { 29 | get { return this.rowType; } 30 | } 31 | 32 | internal SqlExpression Expansion { 33 | get { return this.expansion; } 34 | set { this.expansion = value; } 35 | } 36 | 37 | 38 | internal SqlExpression Expression { 39 | get { return this.expression; } 40 | set { this.expression = value; } 41 | } 42 | 43 | internal MetaDataMember Member { 44 | get { return this.member; } 45 | } 46 | 47 | internal List KeyExpressions { 48 | get { return this.keyExpressions; } 49 | } 50 | 51 | internal object Id { 52 | get { return this.id; } 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlMember.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Reflection; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlMember : SqlSimpleTypeExpression { 7 | private SqlExpression expression; 8 | private MemberInfo member; 9 | 10 | internal SqlMember(Type clrType, ProviderType sqlType, SqlExpression expr, MemberInfo member) 11 | : base(SqlNodeType.Member, clrType, sqlType, expr.SourceExpression) { 12 | this.member = member; 13 | this.Expression = expr; 14 | } 15 | 16 | internal MemberInfo Member { 17 | get { return this.member; } 18 | } 19 | 20 | internal SqlExpression Expression { 21 | get { 22 | return this.expression; 23 | } 24 | set { 25 | if (value == null) 26 | throw Error.ArgumentNull("value"); 27 | if (!this.member.ReflectedType.IsAssignableFrom(value.ClrType) && 28 | !value.ClrType.IsAssignableFrom(this.member.ReflectedType)) 29 | throw Error.MemberAccessIllegal(this.member, this.member.ReflectedType, value.ClrType); 30 | this.expression = value; 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlMemberAssign.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal class SqlMemberAssign : SqlNode { 6 | private MemberInfo member; 7 | private SqlExpression expression; 8 | 9 | internal SqlMemberAssign(MemberInfo member, SqlExpression expr) 10 | : base(SqlNodeType.MemberAssign, expr.SourceExpression) { 11 | if (member == null) 12 | throw Error.ArgumentNull("member"); 13 | this.member = member; 14 | this.Expression = expr; 15 | } 16 | 17 | internal MemberInfo Member { 18 | get { return this.member; } 19 | } 20 | 21 | internal SqlExpression Expression { 22 | get { return this.expression; } 23 | set { 24 | if (value == null) 25 | throw Error.ArgumentNull("value"); 26 | this.expression = value; 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlMethodCall.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.Common; 3 | using System.Linq.Expressions; 4 | using System.Reflection; 5 | 6 | namespace System.Data.Linq.Provider.NodeTypes 7 | { 8 | internal class SqlMethodCall : SqlSimpleTypeExpression { 9 | private MethodInfo method; 10 | private SqlExpression obj; 11 | private List arguments; 12 | 13 | internal SqlMethodCall(Type clrType, ProviderType sqlType, MethodInfo method, SqlExpression obj, IEnumerable args, Expression sourceExpression) 14 | : base(SqlNodeType.MethodCall, clrType, sqlType, sourceExpression) { 15 | if (method == null) 16 | throw Error.ArgumentNull("method"); 17 | this.method = method; 18 | this.Object = obj; 19 | this.arguments = new List(); 20 | if (args != null) 21 | this.arguments.AddRange(args); 22 | } 23 | 24 | internal MethodInfo Method { 25 | get { return this.method; } 26 | } 27 | 28 | internal SqlExpression Object { 29 | get { return this.obj; } 30 | set { 31 | if (value == null && !this.method.IsStatic) 32 | throw Error.ArgumentNull("value"); 33 | if (value != null && !this.method.DeclaringType.IsAssignableFrom(value.ClrType)) 34 | throw Error.ArgumentWrongType("value", this.method.DeclaringType, value.ClrType); 35 | this.obj = value; 36 | } 37 | } 38 | 39 | internal List Arguments { 40 | get { return this.arguments; } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Linq.Expressions; 4 | using System.Diagnostics; 5 | using System.Data; 6 | using System.Data.Linq.Provider.Common; 7 | 8 | namespace System.Data.Linq.Provider.NodeTypes { 9 | 10 | 11 | [System.Diagnostics.DebuggerDisplay("text = {Text}, \r\nsource = {SourceExpression}")] 12 | internal abstract class SqlNode { 13 | private SqlNodeType nodeType; 14 | private Expression sourceExpression; 15 | 16 | internal SqlNode(SqlNodeType nodeType, Expression sourceExpression) { 17 | this.nodeType = nodeType; 18 | this.sourceExpression = sourceExpression; 19 | } 20 | 21 | internal Expression SourceExpression { 22 | get { return this.sourceExpression; } 23 | } 24 | 25 | internal void ClearSourceExpression() { 26 | this.sourceExpression = null; 27 | } 28 | 29 | internal SqlNodeType NodeType { 30 | get { return this.nodeType; } 31 | } 32 | 33 | #if DEBUG 34 | private static DbFormatter formatter; 35 | internal static DbFormatter Formatter { 36 | get { return formatter; } 37 | set { formatter = value; } 38 | } 39 | 40 | internal string Text { 41 | get { 42 | if (Formatter == null) 43 | return "SqlNode.Formatter is not assigned"; 44 | return SqlNode.Formatter.Format(this, true); 45 | } 46 | } 47 | #endif 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlNop.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlNop : SqlSimpleTypeExpression { 7 | internal SqlNop(Type clrType, ProviderType sqlType, Expression sourceExpression) 8 | : base(SqlNodeType.Nop, clrType, sqlType, sourceExpression) { 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlOptionalValue.cs: -------------------------------------------------------------------------------- 1 | namespace System.Data.Linq.Provider.NodeTypes 2 | { 3 | internal class SqlOptionalValue : SqlSimpleTypeExpression { 4 | private SqlExpression hasValue; 5 | private SqlExpression expressionValue; 6 | 7 | internal SqlOptionalValue( SqlExpression hasValue, SqlExpression value) 8 | : base(SqlNodeType.OptionalValue, value.ClrType, value.SqlType, value.SourceExpression) { 9 | this.HasValue = hasValue; 10 | this.Value = value; 11 | } 12 | 13 | internal SqlExpression HasValue { 14 | get { return this.hasValue; } 15 | set { 16 | if (value == null) 17 | throw Error.ArgumentNull("value"); 18 | this.hasValue = value; 19 | } 20 | } 21 | 22 | internal SqlExpression Value { 23 | get { return this.expressionValue; } 24 | set { 25 | if (value == null) 26 | throw Error.ArgumentNull("value"); 27 | if (value.ClrType != this.ClrType) 28 | throw Error.ArgumentWrongType("value", this.ClrType, value.ClrType); 29 | this.expressionValue = value; 30 | } 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlParameter.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlParameter : SqlSimpleTypeExpression { 7 | private string name; 8 | private System.Data.ParameterDirection direction; 9 | 10 | internal SqlParameter(Type clrType, ProviderType sqlType, string name, Expression sourceExpression) 11 | : base(SqlNodeType.Parameter, clrType, sqlType, sourceExpression) { 12 | if (name == null) 13 | throw Error.ArgumentNull("name"); 14 | if (typeof(Type).IsAssignableFrom(clrType)) 15 | throw Error.ArgumentWrongValue("clrType"); 16 | this.name = name; 17 | this.direction = System.Data.ParameterDirection.Input; 18 | } 19 | 20 | internal string Name { 21 | get { return this.name; } 22 | } 23 | 24 | internal System.Data.ParameterDirection Direction { 25 | get { return this.direction; } 26 | set { this.direction = value; } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlRow.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlRow : SqlNode { 7 | private List columns; 8 | 9 | internal SqlRow(Expression sourceExpression) 10 | : base(SqlNodeType.Row, sourceExpression) { 11 | this.columns = new List(); 12 | } 13 | 14 | internal List Columns { 15 | get { return this.columns; } 16 | } 17 | 18 | internal SqlColumn Find(string name) { 19 | foreach (SqlColumn c in this.columns) { 20 | if (name == c.Name) 21 | return c; 22 | } 23 | return null; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlRowNumber.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.Common; 3 | using System.Linq.Expressions; 4 | 5 | namespace System.Data.Linq.Provider.NodeTypes 6 | { 7 | internal class SqlRowNumber : SqlSimpleTypeExpression { 8 | private List orderBy; 9 | 10 | internal List OrderBy { 11 | get { return orderBy; } 12 | } 13 | 14 | internal SqlRowNumber(Type clrType, ProviderType sqlType, List orderByList, Expression sourceExpression) 15 | : base(SqlNodeType.RowNumber, clrType, sqlType, sourceExpression) { 16 | if (orderByList == null) { 17 | throw Error.ArgumentNull("orderByList"); 18 | } 19 | 20 | this.orderBy = orderByList; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlSearchedCase.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.Common; 3 | using System.Linq.Expressions; 4 | 5 | namespace System.Data.Linq.Provider.NodeTypes 6 | { 7 | /* 8 | * Searched CASE function: 9 | * CASE 10 | * WHEN BooleanExpression THEN resultExpression 11 | * [ ...n ] 12 | * [ 13 | * ELSE elseResultExpression 14 | * ] 15 | * END 16 | */ 17 | internal class SqlSearchedCase : SqlExpression 18 | { 19 | private List whens; 20 | private SqlExpression @else; 21 | 22 | internal SqlSearchedCase(Type clrType, IEnumerable whens, SqlExpression @else, Expression sourceExpression) 23 | : base(SqlNodeType.SearchedCase, clrType, sourceExpression) 24 | { 25 | if(whens == null) 26 | throw Error.ArgumentNull("whens"); 27 | this.whens = new List(whens); 28 | if(this.whens.Count == 0) 29 | throw Error.ArgumentOutOfRange("whens"); 30 | this.Else = @else; 31 | } 32 | 33 | internal List Whens 34 | { 35 | get { return this.whens; } 36 | } 37 | 38 | internal SqlExpression Else 39 | { 40 | get { return this.@else; } 41 | set 42 | { 43 | if(value == null) 44 | throw Error.ArgumentNull("value"); 45 | if(this.@else != null && !this.@else.ClrType.IsAssignableFrom(value.ClrType)) 46 | throw Error.ArgumentWrongType("value", this.@else.ClrType, value.ClrType); 47 | this.@else = value; 48 | } 49 | } 50 | 51 | internal override ProviderType SqlType 52 | { 53 | get { return this.whens[0].Value.SqlType; } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlSharedExpression.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal class SqlSharedExpression : SqlExpression { 6 | private SqlExpression expr; 7 | 8 | internal SqlSharedExpression(SqlExpression expr) 9 | : base(SqlNodeType.SharedExpression, expr.ClrType, expr.SourceExpression) { 10 | this.expr = expr; 11 | } 12 | 13 | internal SqlExpression Expression { 14 | get { return this.expr; } 15 | set { 16 | if (value == null) 17 | throw Error.ArgumentNull("value"); 18 | if (!this.ClrType.IsAssignableFrom(value.ClrType) 19 | && !value.ClrType.IsAssignableFrom(this.ClrType)) 20 | throw Error.ArgumentWrongType("value", this.ClrType, value.ClrType); 21 | this.expr = value; 22 | } 23 | } 24 | 25 | internal override ProviderType SqlType { 26 | get { return this.expr.SqlType; } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlSharedExpressionRef.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal class SqlSharedExpressionRef : SqlExpression { 6 | private SqlSharedExpression expr; 7 | 8 | internal SqlSharedExpressionRef(SqlSharedExpression expr) 9 | : base(SqlNodeType.SharedExpressionRef, expr.ClrType, expr.SourceExpression) { 10 | this.expr = expr; 11 | } 12 | 13 | internal SqlSharedExpression SharedExpression { 14 | get { return this.expr; } 15 | } 16 | 17 | internal override ProviderType SqlType { 18 | get { return this.expr.SqlType; } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlSimpleCase.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.Common; 3 | using System.Linq.Expressions; 4 | 5 | namespace System.Data.Linq.Provider.NodeTypes 6 | { 7 | /* 8 | * Simple CASE function: 9 | * CASE inputExpression 10 | * WHEN whenExpression THEN resultExpression 11 | * [ ...n ] 12 | * [ 13 | * ELSE elseResultExpression 14 | * ] 15 | * END 16 | */ 17 | internal class SqlSimpleCase : SqlExpression 18 | { 19 | private SqlExpression expression; 20 | private List whens = new List(); 21 | 22 | internal SqlSimpleCase(Type clrType, SqlExpression expr, IEnumerable whens, Expression sourceExpression) 23 | : base(SqlNodeType.SimpleCase, clrType, sourceExpression) 24 | { 25 | this.Expression = expr; 26 | if(whens == null) 27 | throw Error.ArgumentNull("whens"); 28 | this.whens.AddRange(whens); 29 | if(this.whens.Count == 0) 30 | throw Error.ArgumentOutOfRange("whens"); 31 | } 32 | 33 | internal SqlExpression Expression 34 | { 35 | get { return this.expression; } 36 | set 37 | { 38 | if(value == null) 39 | throw Error.ArgumentNull("value"); 40 | if(this.expression != null && this.expression.ClrType != value.ClrType) 41 | throw Error.ArgumentWrongType("value", this.expression.ClrType, value.ClrType); 42 | this.expression = value; 43 | } 44 | } 45 | 46 | internal List Whens 47 | { 48 | get { return this.whens; } 49 | } 50 | 51 | internal override ProviderType SqlType 52 | { 53 | get { return this.whens[0].Value.SqlType; } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlSimpleExpression.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal class SqlSimpleExpression : SqlExpression { 6 | private SqlExpression expr; 7 | 8 | internal SqlSimpleExpression(SqlExpression expr) 9 | : base(SqlNodeType.SimpleExpression, expr.ClrType, expr.SourceExpression) { 10 | this.expr = expr; 11 | } 12 | 13 | internal SqlExpression Expression { 14 | get { return this.expr; } 15 | set { 16 | if (value == null) 17 | throw Error.ArgumentNull("value"); 18 | if (!TypeSystem.GetNonNullableType(this.ClrType).IsAssignableFrom(TypeSystem.GetNonNullableType(value.ClrType))) 19 | throw Error.ArgumentWrongType("value", this.ClrType, value.ClrType); 20 | this.expr = value; 21 | } 22 | } 23 | 24 | internal override ProviderType SqlType { 25 | get { return this.expr.SqlType; } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlSimpleTypeExpression.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | /// 7 | /// A SqlExpression with a simple implementation of ClrType and SqlType. 8 | /// 9 | internal abstract class SqlSimpleTypeExpression : SqlExpression { 10 | private ProviderType sqlType; 11 | 12 | internal SqlSimpleTypeExpression(SqlNodeType nodeType, Type clrType, ProviderType sqlType, Expression sourceExpression) 13 | : base(nodeType, clrType, sourceExpression) { 14 | this.sqlType = sqlType; 15 | } 16 | 17 | internal override ProviderType SqlType { 18 | get { return this.sqlType; } 19 | } 20 | 21 | internal void SetSqlType(ProviderType type) { 22 | this.sqlType = type; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlSource.cs: -------------------------------------------------------------------------------- 1 | using System.Linq.Expressions; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal abstract class SqlSource : SqlNode { 6 | internal SqlSource(SqlNodeType nt, Expression sourceExpression) 7 | : base(nt, sourceExpression) { 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlStatement.cs: -------------------------------------------------------------------------------- 1 | using System.Linq.Expressions; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal abstract class SqlStatement : SqlNode { 6 | internal SqlStatement(SqlNodeType nodeType, Expression sourceExpression) 7 | : base(nodeType, sourceExpression) { 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlStoredProcedureCall.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Mapping; 3 | using System.Linq.Expressions; 4 | 5 | namespace System.Data.Linq.Provider.NodeTypes 6 | { 7 | internal class SqlStoredProcedureCall : SqlUserQuery { 8 | private MetaFunction function; 9 | 10 | internal SqlStoredProcedureCall(MetaFunction function, SqlExpression projection, IEnumerable args, Expression source) 11 | : base(SqlNodeType.StoredProcedureCall, projection, args, source) { 12 | if (function == null) 13 | throw Error.ArgumentNull("function"); 14 | this.function = function; 15 | } 16 | 17 | internal MetaFunction Function { 18 | get { return this.function; } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlSubSelect.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal class SqlSubSelect : SqlSimpleTypeExpression { 6 | private SqlSelect select; 7 | 8 | internal SqlSubSelect(SqlNodeType nt , Type clrType, ProviderType sqlType , SqlSelect select) 9 | : base(nt, clrType, sqlType, select.SourceExpression) { 10 | switch (nt) { 11 | case SqlNodeType.Multiset: 12 | case SqlNodeType.ScalarSubSelect: 13 | case SqlNodeType.Element: 14 | case SqlNodeType.Exists: 15 | break; 16 | default: 17 | throw Error.UnexpectedNode(nt); 18 | } 19 | this.Select = select; 20 | } 21 | 22 | internal SqlSelect Select { 23 | get { return this.select; } 24 | set { 25 | if (value == null) 26 | throw Error.ArgumentNull("value"); 27 | this.select = value; 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlTable.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Mapping; 3 | using System.Data.Linq.Provider.Common; 4 | using System.Linq.Expressions; 5 | 6 | namespace System.Data.Linq.Provider.NodeTypes 7 | { 8 | internal class SqlTable : SqlNode { 9 | private MetaTable table; 10 | private MetaType rowType; 11 | private ProviderType sqlRowType; 12 | private List columns; 13 | 14 | internal SqlTable(MetaTable table, MetaType rowType, ProviderType sqlRowType, Expression sourceExpression) 15 | : base(SqlNodeType.Table, sourceExpression) { 16 | this.table = table; 17 | this.rowType = rowType; 18 | this.sqlRowType = sqlRowType; 19 | this.columns = new List(); 20 | } 21 | 22 | internal MetaTable MetaTable { 23 | get { return this.table; } 24 | } 25 | 26 | internal string Name { 27 | get { return this.table.TableName; } 28 | } 29 | 30 | internal List Columns { 31 | get { return this.columns; } 32 | } 33 | 34 | internal MetaType RowType { 35 | get { return this.rowType; } 36 | } 37 | 38 | internal ProviderType SqlRowType { 39 | get { return this.sqlRowType; } 40 | } 41 | 42 | internal SqlColumn Find(string columnName) { 43 | foreach (SqlColumn c in this.Columns) { 44 | if (c.Name == columnName) 45 | return c; 46 | } 47 | return null; 48 | } 49 | 50 | } 51 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlTableValuedFunctionCall.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Mapping; 3 | using System.Data.Linq.Provider.Common; 4 | using System.Linq.Expressions; 5 | 6 | namespace System.Data.Linq.Provider.NodeTypes 7 | { 8 | /// 9 | /// This class is used to represent a table value function. It inherits normal function 10 | /// call functionality, and adds TVF specific members. 11 | /// 12 | internal class SqlTableValuedFunctionCall : SqlFunctionCall { 13 | private MetaType rowType; 14 | private List columns; 15 | 16 | internal SqlTableValuedFunctionCall(MetaType rowType, Type clrType, ProviderType sqlType, string name, IEnumerable args , Expression source) 17 | : base(SqlNodeType.TableValuedFunctionCall, clrType , sqlType, name, args, source) { 18 | this.rowType = rowType; 19 | this.columns = new List(); 20 | } 21 | 22 | internal MetaType RowType { 23 | get { return this.rowType; } 24 | } 25 | 26 | internal List Columns { 27 | get { return this.columns; } 28 | } 29 | 30 | internal SqlColumn Find(string name) { 31 | foreach (SqlColumn c in this.Columns) { 32 | if (c.Name == name) 33 | return c; 34 | } 35 | return null; 36 | } 37 | 38 | } 39 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlTypeCaseWhen.cs: -------------------------------------------------------------------------------- 1 | namespace System.Data.Linq.Provider.NodeTypes 2 | { 3 | /// 4 | /// Represents one choice of object instantiation type in a type case. 5 | /// When 'match' is the same as type case Discriminator then the corresponding 6 | /// type binding is the one used for instantiation. 7 | /// 8 | internal class SqlTypeCaseWhen { 9 | private SqlExpression match; 10 | private SqlExpression @new; 11 | 12 | internal SqlTypeCaseWhen(SqlExpression match, SqlExpression typeBinding) { 13 | this.Match = match; 14 | this.TypeBinding = typeBinding; 15 | } 16 | internal SqlExpression Match { 17 | get { return this.match; } 18 | set { 19 | if (this.match != null && value != null && this.match.ClrType != value.ClrType) 20 | throw Error.ArgumentWrongType("value", this.match.ClrType, value.ClrType); 21 | this.match = value; 22 | } 23 | } 24 | internal SqlExpression TypeBinding { 25 | get { return this.@new; } 26 | set { this.@new = value; } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlUpdate.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlUpdate : SqlStatement { 7 | private SqlSelect select; 8 | private List assignments; 9 | 10 | internal SqlUpdate(SqlSelect select, IEnumerable assignments, Expression sourceExpression) 11 | : base(SqlNodeType.Update, sourceExpression) { 12 | this.Select = select; 13 | this.assignments = new List(assignments); 14 | } 15 | 16 | internal SqlSelect Select { 17 | get { return this.select; } 18 | set { 19 | if (value == null) 20 | throw Error.ArgumentNull("value"); 21 | this.select = value; 22 | } 23 | } 24 | 25 | internal List Assignments { 26 | get { return this.assignments; } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlUserColumn.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlUserColumn : SqlSimpleTypeExpression { 7 | private SqlUserQuery query; 8 | private string name; 9 | private bool isRequired; 10 | 11 | internal SqlUserColumn(Type clrType, ProviderType sqlType, SqlUserQuery query, string name, bool isRequired, Expression source) 12 | : base(SqlNodeType.UserColumn, clrType, sqlType, source) { 13 | this.Query = query; 14 | this.name = name; 15 | this.isRequired = isRequired; 16 | } 17 | 18 | internal SqlUserQuery Query { 19 | get { return this.query; } 20 | set { 21 | if (value == null) 22 | throw Error.ArgumentNull("value"); 23 | if (this.query != null && this.query != value) 24 | throw Error.ArgumentWrongValue("value"); 25 | this.query = value; 26 | } 27 | } 28 | 29 | internal string Name { 30 | get { return this.name; } 31 | } 32 | 33 | internal bool IsRequired { 34 | get { return this.isRequired; } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlUserRow.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Mapping; 2 | using System.Data.Linq.Provider.Common; 3 | using System.Linq.Expressions; 4 | 5 | namespace System.Data.Linq.Provider.NodeTypes 6 | { 7 | internal class SqlUserRow : SqlSimpleTypeExpression { 8 | private SqlUserQuery query; 9 | private MetaType rowType; 10 | 11 | internal SqlUserRow(MetaType rowType, ProviderType sqlType, SqlUserQuery query, Expression source) 12 | : base(SqlNodeType.UserRow, rowType.Type, sqlType, source) { 13 | this.Query = query; 14 | this.rowType = rowType; 15 | } 16 | 17 | internal MetaType RowType { 18 | get { return this.rowType; } 19 | } 20 | 21 | internal SqlUserQuery Query { 22 | get { return this.query; } 23 | set { 24 | if (value == null) 25 | throw Error.ArgumentNull("value"); 26 | if (value.Projection != null && value.Projection.ClrType != this.ClrType) 27 | throw Error.ArgumentWrongType("value", this.ClrType, value.Projection.ClrType); 28 | this.query = value; 29 | } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlValue.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlValue : SqlSimpleTypeExpression { 7 | private object value; 8 | private bool isClient; 9 | 10 | internal SqlValue(Type clrType, ProviderType sqlType, object value, bool isClientSpecified, Expression sourceExpression) 11 | : base(SqlNodeType.Value, clrType, sqlType, sourceExpression) { 12 | this.value = value; 13 | this.isClient = isClientSpecified; 14 | } 15 | 16 | internal object Value { 17 | get { return this.value; } 18 | } 19 | 20 | internal bool IsClientSpecified { 21 | get { return this.isClient; } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlVariable.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.NodeTypes 5 | { 6 | internal class SqlVariable : SqlSimpleTypeExpression { 7 | private string name; 8 | 9 | internal SqlVariable(Type clrType, ProviderType sqlType, string name, Expression sourceExpression) 10 | : base(SqlNodeType.Variable, clrType, sqlType, sourceExpression) { 11 | if (name == null) 12 | throw Error.ArgumentNull("name"); 13 | this.name = name; 14 | } 15 | 16 | internal string Name { 17 | get { return this.name; } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Provider/NodeTypes/SqlWhen.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | 3 | namespace System.Data.Linq.Provider.NodeTypes 4 | { 5 | internal class SqlWhen { 6 | private SqlExpression matchExpression; 7 | private SqlExpression valueExpression; 8 | 9 | internal SqlWhen(SqlExpression match, SqlExpression value) { 10 | // 'match' may be null when this when represents the ELSE condition. 11 | if (value == null) 12 | throw Error.ArgumentNull("value"); 13 | this.Match = match; 14 | this.Value = value; 15 | } 16 | 17 | internal SqlExpression Match { 18 | get { return this.matchExpression; } 19 | set { 20 | if (this.matchExpression != null && value != null && this.matchExpression.ClrType != value.ClrType 21 | // Exception: bool types, because predicates can have type bool or bool? 22 | && !TypeSystem.GetNonNullableType(this.matchExpression.ClrType).Equals(typeof(bool)) 23 | && !TypeSystem.GetNonNullableType(value.ClrType).Equals(typeof(bool))) 24 | throw Error.ArgumentWrongType("value", this.matchExpression.ClrType, value.ClrType); 25 | this.matchExpression = value; 26 | } 27 | } 28 | 29 | internal SqlExpression Value { 30 | get { return this.valueExpression; } 31 | set { 32 | if (value == null) 33 | throw Error.ArgumentNull("value"); 34 | if (this.valueExpression != null && !this.valueExpression.ClrType.IsAssignableFrom(value.ClrType)) 35 | throw Error.ArgumentWrongType("value", this.valueExpression.ClrType, value.ClrType); 36 | this.valueExpression = value; 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/AliasDependencyChecker.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | 4 | namespace System.Data.Linq.Provider.Visitors 5 | { 6 | internal class AliasDependencyChecker : SqlVisitor 7 | { 8 | HashSet aliasesToCheck; 9 | HashSet ignoreExpressions; 10 | internal bool hasDependency; 11 | 12 | internal AliasDependencyChecker(HashSet aliasesToCheck, HashSet ignoreExpressions) 13 | { 14 | this.aliasesToCheck = aliasesToCheck; 15 | this.ignoreExpressions = ignoreExpressions; 16 | } 17 | internal override SqlNode Visit(SqlNode node) 18 | { 19 | SqlExpression e = node as SqlExpression; 20 | if(this.hasDependency) 21 | return node; 22 | if(e != null && this.ignoreExpressions.Contains(e)) 23 | { 24 | return node; 25 | } 26 | return base.Visit(node); 27 | } 28 | internal override SqlExpression VisitColumnRef(SqlColumnRef cref) 29 | { 30 | if(this.aliasesToCheck.Contains(cref.Column.Alias)) 31 | { 32 | this.hasDependency = true; 33 | } 34 | else if(cref.Column.Expression != null) 35 | { 36 | this.Visit(cref.Column.Expression); 37 | } 38 | return cref; 39 | } 40 | internal override SqlExpression VisitColumn(SqlColumn col) 41 | { 42 | if(col.Expression != null) 43 | { 44 | this.Visit(col.Expression); 45 | } 46 | return col; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/AliasMapper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | 4 | namespace System.Data.Linq.Provider.Visitors 5 | { 6 | internal class AliasMapper : SqlVisitor 7 | { 8 | #region Member Declarations 9 | private Dictionary _aliasMap; 10 | private SqlAlias _currentAlias; 11 | #endregion 12 | 13 | internal AliasMapper(Dictionary aliasMap) 14 | { 15 | _aliasMap = aliasMap; 16 | } 17 | 18 | internal override SqlAlias VisitAlias(SqlAlias a) 19 | { 20 | SqlAlias save = _currentAlias; 21 | _currentAlias = a; 22 | base.VisitAlias(a); 23 | _currentAlias = save; 24 | return a; 25 | } 26 | 27 | internal override SqlExpression VisitColumn(SqlColumn col) 28 | { 29 | _aliasMap[col] = _currentAlias; 30 | this.Visit(col.Expression); 31 | return col; 32 | } 33 | 34 | internal override SqlRow VisitRow(SqlRow row) 35 | { 36 | foreach(SqlColumn col in row.Columns) 37 | { 38 | this.VisitColumn(col); 39 | } 40 | return row; 41 | } 42 | 43 | internal override SqlTable VisitTable(SqlTable tab) 44 | { 45 | foreach(SqlColumn col in tab.Columns) 46 | { 47 | this.VisitColumn(col); 48 | } 49 | return tab; 50 | } 51 | 52 | internal override SqlExpression VisitTableValuedFunctionCall(SqlTableValuedFunctionCall fc) 53 | { 54 | foreach(SqlColumn col in fc.Columns) 55 | { 56 | this.VisitColumn(col); 57 | } 58 | return fc; 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/ColumnDeclarer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | 4 | namespace System.Data.Linq.Provider.Visitors 5 | { 6 | internal class ColumnDeclarer : SqlVisitor { 7 | HashSet candidates; 8 | 9 | internal ColumnDeclarer() { 10 | } 11 | 12 | internal SqlExpression Declare(SqlExpression expression, HashSet candidates) { 13 | this.candidates = candidates; 14 | return (SqlExpression)this.Visit(expression); 15 | } 16 | 17 | internal override SqlNode Visit(SqlNode node) { 18 | SqlExpression expr = node as SqlExpression; 19 | if (expr != null) { 20 | if (this.candidates.Contains(expr)) { 21 | if (expr.NodeType == SqlNodeType.Column || 22 | expr.NodeType == SqlNodeType.ColumnRef) { 23 | return expr; 24 | } 25 | else { 26 | return new SqlColumn(expr.ClrType, expr.SqlType, null, null, expr, expr.SourceExpression); 27 | } 28 | } 29 | } 30 | return base.Visit(node); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/ColumnNameGatherer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | 4 | namespace System.Data.Linq.Provider.Visitors 5 | { 6 | internal class ColumnNameGatherer : SqlVisitor 7 | { 8 | public ColumnNameGatherer() 9 | : base() 10 | { 11 | this.Names = new HashSet(); 12 | } 13 | 14 | internal override SqlExpression VisitColumn(SqlColumn col) 15 | { 16 | if(!String.IsNullOrEmpty(col.Name)) 17 | { 18 | this.Names.Add(col.Name); 19 | } 20 | 21 | return base.VisitColumn(col); 22 | } 23 | 24 | internal override SqlExpression VisitColumnRef(SqlColumnRef cref) 25 | { 26 | Visit(cref.Column); 27 | 28 | return base.VisitColumnRef(cref); 29 | } 30 | 31 | public HashSet Names { get; set; } 32 | } 33 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/ColumnTypeValidator.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | 4 | namespace System.Data.Linq.Provider.Visitors 5 | { 6 | /// 7 | /// Column ClrType must agree with the expression that it points to. 8 | /// 9 | internal class ColumnTypeValidator : SqlVisitor 10 | { 11 | 12 | internal override SqlRow VisitRow(SqlRow row) 13 | { 14 | for(int i = 0, n = row.Columns.Count; i < n; i++) 15 | { 16 | SqlColumn col = row.Columns[i]; 17 | SqlExpression expr = this.VisitExpression(col.Expression); 18 | if(expr != null) 19 | { 20 | if(TypeSystem.GetNonNullableType(col.ClrType) != TypeSystem.GetNonNullableType(expr.ClrType)) 21 | { 22 | throw Error.ColumnClrTypeDoesNotAgreeWithExpressionsClrType(); 23 | } 24 | } 25 | } 26 | return row; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/ConstantInOrderByRemover.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | 4 | namespace System.Data.Linq.Provider.Visitors 5 | { 6 | /// 7 | /// SQL doesn't allow constants in ORDER BY. 8 | /// 9 | /// Worse, an integer constant greater than 0 is treated as ORDER BY ProjectionColumn[i] so the results 10 | /// can be unexpected. 11 | /// 12 | /// The LINQ semantic for OrderBy(o=>constant) is for it to have no effect on the ordering. We enforce 13 | /// that semantic here by removing all constant columns from OrderBy. 14 | /// 15 | internal class ConstantInOrderByRemover : SqlVisitor 16 | { 17 | internal override SqlSelect VisitSelect(SqlSelect select) 18 | { 19 | int i = 0; 20 | List orders = @select.OrderBy; 21 | while(i < orders.Count) 22 | { 23 | SqlExpression expr = orders[i].Expression; 24 | while(expr.NodeType == SqlNodeType.DiscriminatedType) 25 | { 26 | expr = ((SqlDiscriminatedType)expr).Discriminator; 27 | } 28 | switch(expr.NodeType) 29 | { 30 | case SqlNodeType.Value: 31 | case SqlNodeType.Parameter: 32 | orders.RemoveAt(i); 33 | break; 34 | default: 35 | ++i; 36 | break; 37 | } 38 | } 39 | return base.VisitSelect(@select); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/ConsumedAliaseGatherer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | 4 | namespace System.Data.Linq.Provider.Visitors 5 | { 6 | internal class ConsumedAliaseGatherer : SqlVisitor 7 | { 8 | private HashSet _consumed = new HashSet(); 9 | 10 | internal void VisitAliasConsumed(SqlAlias a) 11 | { 12 | _consumed.Add(a); 13 | } 14 | 15 | internal override SqlExpression VisitColumn(SqlColumn col) 16 | { 17 | VisitAliasConsumed(col.Alias); 18 | VisitExpression(col.Expression); 19 | return col; 20 | } 21 | internal override SqlExpression VisitColumnRef(SqlColumnRef cref) 22 | { 23 | VisitAliasConsumed(cref.Column.Alias); 24 | return cref; 25 | } 26 | 27 | internal HashSet Consumed 28 | { 29 | get { return _consumed; } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/DependenceChecker.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.Visitors 5 | { 6 | internal class DependenceChecker : ExpressionVisitor { 7 | HashSet inScope = new HashSet(); 8 | bool isIndependent = true; 9 | 10 | /// 11 | /// This method returns 'true' when the expression doesn't reference any parameters 12 | /// from outside the scope of the expression. 13 | /// 14 | static public bool IsIndependent(Expression expression) { 15 | var v = new DependenceChecker(); 16 | v.Visit(expression); 17 | return v.isIndependent; 18 | } 19 | internal override Expression VisitLambda(LambdaExpression lambda) { 20 | foreach (var p in lambda.Parameters) { 21 | this.inScope.Add(p); 22 | } 23 | return base.VisitLambda(lambda); 24 | } 25 | internal override Expression VisitParameter(ParameterExpression p) { 26 | this.isIndependent &= this.inScope.Contains(p); 27 | return p; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/ExpectNoAliasRefs.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Visitors 4 | { 5 | internal class ExpectNoAliasRefs : SqlVisitor 6 | { 7 | internal override SqlExpression VisitAliasRef(SqlAliasRef aref) 8 | { 9 | throw Error.UnexpectedNode(aref.NodeType); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/ExpectNoFloatingColumns.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Visitors 4 | { 5 | internal class ExpectNoFloatingColumns : SqlVisitor 6 | { 7 | internal override SqlRow VisitRow(SqlRow row) 8 | { 9 | foreach(SqlColumn c in row.Columns) 10 | { 11 | this.Visit(c.Expression); 12 | } 13 | return row; 14 | } 15 | internal override SqlTable VisitTable(SqlTable tab) 16 | { 17 | foreach(SqlColumn c in tab.Columns) 18 | { 19 | this.Visit(c.Expression); 20 | } 21 | return tab; 22 | } 23 | internal override SqlExpression VisitColumn(SqlColumn col) 24 | { 25 | throw Error.UnexpectedFloatingColumn(); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/ExpectNoMethodCalls.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Visitors 4 | { 5 | /// 6 | /// A validator which enforces that no more SqlMethodCall nodes exist in the tree. 7 | /// 8 | internal class ExpectNoMethodCalls : SqlVisitor 9 | { 10 | 11 | internal override SqlExpression VisitMethodCall(SqlMethodCall mc) 12 | { 13 | // eventually we may support this type of stuff given the SQL CLR, but for now it is illegal 14 | throw Error.MethodHasNoSupportConversionToSql(mc.Method.Name); 15 | } 16 | 17 | // check everything except selection expressions (which will be client or ignored) 18 | internal override SqlSelect VisitSelect(SqlSelect select) 19 | { 20 | return this.VisitSelectCore(select); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/ExpectNoSharedExpressions.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Visitors 4 | { 5 | internal class ExpectNoSharedExpressions : SqlVisitor 6 | { 7 | internal override SqlExpression VisitSharedExpression(SqlSharedExpression shared) 8 | { 9 | throw Error.UnexpectedSharedExpression(); 10 | } 11 | internal override SqlExpression VisitSharedExpressionRef(SqlSharedExpressionRef sref) 12 | { 13 | throw Error.UnexpectedSharedExpressionReference(); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/ExpectRationalizedBooleans.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Visitors 4 | { 5 | /// 6 | /// A validator which enforces rationalized boolean expressions. 7 | /// 8 | internal class ExpectRationalizedBooleans : SqlBooleanMismatchVisitor 9 | { 10 | internal override SqlExpression ConvertValueToPredicate(SqlExpression bitExpression) 11 | { 12 | throw Error.ExpectedPredicateFoundBit(); 13 | } 14 | 15 | internal override SqlExpression ConvertPredicateToValue(SqlExpression predicateExpression) 16 | { 17 | throw Error.ExpectedBitFoundPredicate(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/Funcletizer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | 5 | namespace System.Data.Linq.Provider.Visitors 6 | { 7 | internal static class Funcletizer 8 | { 9 | /// 10 | /// Expression handler which marks all expressions which solely refer to local elements, so these can be inlined and won't be 11 | /// converted to SQL fragments. 12 | /// 13 | /// 14 | /// 15 | internal static Expression Funcletize(Expression expression) 16 | { 17 | return new Localizer(new LocalMapper().MapLocals(expression)).Localize(expression); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Provider/Visitors/LiteralValidator.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Visitors 4 | { 5 | /// 6 | /// A validator that ensures literal values are reasonable. 7 | /// 8 | internal class LiteralValidator : SqlVisitor 9 | { 10 | internal override SqlExpression VisitValue(SqlValue value) 11 | { 12 | if(!value.IsClientSpecified 13 | && value.ClrType.IsClass 14 | && value.ClrType != typeof(string) 15 | && value.ClrType != typeof(Type) 16 | && value.Value != null) 17 | { 18 | throw Error.ClassLiteralsNotAllowed(value.ClrType); 19 | } 20 | return value; 21 | } 22 | 23 | internal override SqlExpression VisitBinaryOperator(SqlBinary bo) 24 | { 25 | bo.Left = this.VisitExpression(bo.Left); 26 | return bo; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/Localizer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq.Expressions; 3 | 4 | namespace System.Data.Linq.Provider.Visitors 5 | { 6 | internal class Localizer : ExpressionVisitor { 7 | Dictionary locals; 8 | 9 | internal Localizer(Dictionary locals) { 10 | this.locals = locals; 11 | } 12 | 13 | internal Expression Localize(Expression expression) { 14 | return this.Visit(expression); 15 | } 16 | 17 | internal override Expression Visit(Expression exp) { 18 | if (exp == null) { 19 | return null; 20 | } 21 | if (this.locals.ContainsKey(exp)) { 22 | return MakeLocal(exp); 23 | } 24 | if (exp.NodeType == (ExpressionType)InternalExpressionType.Known) { 25 | return exp; 26 | } 27 | return base.Visit(exp); 28 | } 29 | 30 | private static Expression MakeLocal(Expression e) { 31 | if (e.NodeType == ExpressionType.Constant) { 32 | return e; 33 | } 34 | if (e.NodeType == ExpressionType.Convert || e.NodeType == ExpressionType.ConvertChecked) { 35 | UnaryExpression ue = (UnaryExpression)e; 36 | if (ue.Type == typeof(object)) { 37 | Expression local = MakeLocal(ue.Operand); 38 | return (e.NodeType == ExpressionType.Convert) ? Expression.Convert(local, e.Type) : Expression.ConvertChecked(local, e.Type); 39 | } 40 | // convert a const null 41 | if (ue.Operand.NodeType == ExpressionType.Constant) { 42 | ConstantExpression c = (ConstantExpression)ue.Operand; 43 | if (c.Value == null) { 44 | return Expression.Constant(null, ue.Type); 45 | } 46 | } 47 | } 48 | return Expression.Invoke(Expression.Constant(Expression.Lambda(e).Compile())); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/MultiSetDetector.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Visitors 4 | { 5 | internal class MultiSetDetector : SqlVisitor 6 | { 7 | internal bool FoundMultiset { get; set; } 8 | 9 | 10 | internal override SqlExpression VisitMultiset(SqlSubSelect sms) 11 | { 12 | this.FoundMultiset = true; 13 | return sms; 14 | } 15 | 16 | internal override SqlExpression VisitElement(SqlSubSelect elem) 17 | { 18 | return elem; 19 | } 20 | 21 | internal override SqlExpression VisitClientQuery(SqlClientQuery cq) 22 | { 23 | return cq; 24 | } 25 | 26 | internal override SqlExpression VisitExists(SqlSubSelect ss) 27 | { 28 | return ss; 29 | } 30 | 31 | internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss) 32 | { 33 | return ss; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/ProducedAliasGatherer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | 4 | namespace System.Data.Linq.Provider.Visitors 5 | { 6 | internal class ProducedAliasGatherer : SqlVisitor 7 | { 8 | private HashSet _produced = new HashSet(); 9 | 10 | internal override SqlAlias VisitAlias(SqlAlias a) 11 | { 12 | _produced.Add(a); 13 | return base.VisitAlias(a); 14 | } 15 | 16 | internal HashSet Produced 17 | { 18 | get { return _produced; } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/ProducedColumnsGatherer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | 4 | namespace System.Data.Linq.Provider.Visitors 5 | { 6 | internal class ProducedColumnsGatherer : SqlVisitor 7 | { 8 | private List columns; 9 | 10 | internal ProducedColumnsGatherer(List columns) 11 | { 12 | this.columns = columns; 13 | } 14 | internal override SqlSelect VisitSelect(SqlSelect select) 15 | { 16 | foreach(SqlColumn c in @select.Row.Columns) 17 | { 18 | this.columns.Add(c); 19 | } 20 | return @select; 21 | } 22 | internal override SqlNode VisitUnion(SqlUnion su) 23 | { 24 | return su; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/QueryHierarchyFinder.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Visitors 4 | { 5 | /// 6 | /// Class which determines whether there's a query hierarchy in the visited node tree 7 | /// 8 | internal class QueryHierarchyFinder : SqlVisitor 9 | { 10 | internal bool FoundHierarchy { get; set; } 11 | 12 | internal override SqlExpression VisitMultiset(SqlSubSelect sms) 13 | { 14 | this.FoundHierarchy = true; 15 | return sms; 16 | } 17 | 18 | internal override SqlExpression VisitElement(SqlSubSelect elem) 19 | { 20 | this.FoundHierarchy = true; 21 | return elem; 22 | } 23 | 24 | internal override SqlExpression VisitClientQuery(SqlClientQuery cq) 25 | { 26 | this.FoundHierarchy = true; 27 | return cq; 28 | } 29 | 30 | internal override SqlExpression VisitExists(SqlSubSelect ss) 31 | { 32 | return ss; 33 | } 34 | 35 | internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss) 36 | { 37 | return ss; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/ScalarSubQueryRewriter.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.Common; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | 4 | namespace System.Data.Linq.Provider.Visitors 5 | { 6 | /// 7 | /// converts correlated scalar subqueries into outer-applies 8 | /// 9 | /// must be run after flattener. 10 | internal class ScalarSubQueryRewriter : SqlVisitor 11 | { 12 | NodeFactory sql; 13 | SqlSelect currentSelect; 14 | SqlAggregateChecker aggregateChecker; 15 | 16 | internal ScalarSubQueryRewriter(NodeFactory sqlFactory) 17 | { 18 | this.sql = sqlFactory; 19 | this.aggregateChecker = new SqlAggregateChecker(); 20 | } 21 | 22 | internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss) 23 | { 24 | SqlSelect innerSelect = this.VisitSelect(ss.Select); 25 | if(!this.aggregateChecker.HasAggregates(innerSelect)) 26 | { 27 | innerSelect.Top = this.sql.ValueFromObject(1, ss.SourceExpression); 28 | } 29 | innerSelect.OrderingType = SqlOrderingType.Blocked; 30 | SqlAlias alias = new SqlAlias(innerSelect); 31 | this.currentSelect.From = new SqlJoin(SqlJoinType.OuterApply, this.currentSelect.From, alias, null, ss.SourceExpression); 32 | return new SqlColumnRef(innerSelect.Row.Columns[0]); 33 | } 34 | 35 | internal override SqlSelect VisitSelect(SqlSelect select) 36 | { 37 | SqlSelect save = this.currentSelect; 38 | try 39 | { 40 | this.currentSelect = @select; 41 | return base.VisitSelect(@select); 42 | } 43 | finally 44 | { 45 | this.currentSelect = save; 46 | } 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/SideEffectChecker.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Visitors 4 | { 5 | /// 6 | /// Visitor which checks whether there's a side effect to be expected when the query is compiled. 7 | /// 8 | internal class SideEffectChecker : SqlVisitor 9 | { 10 | bool hasSideEffect; 11 | 12 | internal bool HasSideEffect(SqlNode node) 13 | { 14 | this.hasSideEffect = false; 15 | this.Visit(node); 16 | return this.hasSideEffect; 17 | } 18 | 19 | internal override SqlExpression VisitJoinedCollection(SqlJoinedCollection jc) 20 | { 21 | this.hasSideEffect = true; 22 | return jc; 23 | } 24 | 25 | internal override SqlExpression VisitClientQuery(SqlClientQuery cq) 26 | { 27 | return cq; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/SourceExpressionRemover.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Visitors 4 | { 5 | internal class SourceExpressionRemover : DuplicatingVisitor { 6 | internal SourceExpressionRemover() 7 | : base(true) { 8 | } 9 | internal override SqlNode Visit(SqlNode node) { 10 | node = base.Visit(node); 11 | if (node != null) { 12 | node.ClearSourceExpression(); 13 | } 14 | return node; 15 | } 16 | internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { 17 | SqlExpression result = base.VisitColumnRef(cref); 18 | if (result != null && result == cref) { 19 | // reference to outer scope, don't propogate references to expressions or aliases 20 | SqlColumn col = cref.Column; 21 | SqlColumn newcol = new SqlColumn(col.ClrType, col.SqlType, col.Name, col.MetaMember, null, col.SourceExpression); 22 | newcol.Ordinal = col.Ordinal; 23 | result = new SqlColumnRef(newcol); 24 | newcol.ClearSourceExpression(); 25 | } 26 | return result; 27 | } 28 | internal override SqlExpression VisitAliasRef(SqlAliasRef aref) { 29 | SqlExpression result = base.VisitAliasRef(aref); 30 | if (result != null && result == aref) { 31 | // reference to outer scope, don't propogate references to expressions or aliases 32 | SqlAlias alias = aref.Alias; 33 | SqlAlias newalias = new SqlAlias(new SqlNop(aref.ClrType, aref.SqlType, null)); 34 | return new SqlAliasRef(newalias); 35 | } 36 | return result; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/SqlAggregateChecker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Data.Linq.Provider.NodeTypes; 5 | 6 | namespace System.Data.Linq.Provider.Visitors { 7 | 8 | internal class SqlAggregateChecker { 9 | Visitor visitor; 10 | 11 | internal SqlAggregateChecker() { 12 | this.visitor = new Visitor(); 13 | } 14 | 15 | internal bool HasAggregates(SqlNode node) { 16 | visitor.hasAggregates = false; 17 | visitor.Visit(node); 18 | return visitor.hasAggregates; 19 | } 20 | 21 | class Visitor : SqlVisitor { 22 | internal bool hasAggregates; 23 | 24 | internal Visitor() { 25 | } 26 | 27 | internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { 28 | return ss; 29 | } 30 | internal override SqlSource VisitSource(SqlSource source) { 31 | return source; 32 | } 33 | internal override SqlExpression VisitUnaryOperator(SqlUnary uo) { 34 | switch (uo.NodeType) { 35 | case SqlNodeType.Min: 36 | case SqlNodeType.Max: 37 | case SqlNodeType.Avg: 38 | case SqlNodeType.Sum: 39 | case SqlNodeType.Count: 40 | case SqlNodeType.LongCount: 41 | this.hasAggregates = true; 42 | return uo; 43 | default: 44 | return base.VisitUnaryOperator(uo); 45 | } 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Provider/Visitors/SqlSelectionSkipper.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Visitors 4 | { 5 | /// 6 | /// Skips over client portion of selection expression 7 | /// 8 | internal class SqlSelectionSkipper : SqlVisitor 9 | { 10 | SqlVisitor parent; 11 | internal SqlSelectionSkipper(SqlVisitor parent) 12 | { 13 | this.parent = parent; 14 | } 15 | internal override SqlExpression VisitColumn(SqlColumn col) 16 | { 17 | // pass control back to parent 18 | return parent.VisitColumn(col); 19 | } 20 | internal override SqlExpression VisitSubSelect(SqlSubSelect ss) 21 | { 22 | // pass control back to parent 23 | return this.parent.VisitSubSelect(ss); 24 | } 25 | internal override SqlExpression VisitClientQuery(SqlClientQuery cq) 26 | { 27 | // pass control back to parent 28 | return this.parent.VisitClientQuery(cq); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/SqlSupersetValidator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.NodeTypes; 3 | 4 | namespace System.Data.Linq.Provider.Visitors 5 | { 6 | /// 7 | /// Validates the integrity of super-SQL trees. 8 | /// 9 | internal class SqlSupersetValidator 10 | { 11 | 12 | List validators = new List(); 13 | 14 | /// 15 | /// Add a validator to the collection of validators to run. 16 | /// 17 | internal void AddValidator(SqlVisitor validator) 18 | { 19 | this.validators.Add(validator); 20 | } 21 | 22 | /// 23 | /// Execute each current validator. 24 | /// 25 | internal void Validate(SqlNode node) 26 | { 27 | foreach(SqlVisitor validator in this.validators) 28 | { 29 | validator.Visit(node); 30 | } 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/SqlValueDeflator.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Visitors 4 | { 5 | /// 6 | /// Removes references to literal values 7 | /// 8 | internal class SqlValueDeflator : SqlVisitor 9 | { 10 | #region Member Declarations 11 | private SelectionDeflator _sDeflator; 12 | private bool _isTopLevel = true; 13 | #endregion 14 | 15 | internal SqlValueDeflator() 16 | { 17 | _sDeflator = new SelectionDeflator(); 18 | } 19 | 20 | internal override SqlSelect VisitSelect(SqlSelect select) 21 | { 22 | if(_isTopLevel) 23 | { 24 | @select.Selection = _sDeflator.VisitExpression(@select.Selection); 25 | } 26 | return @select; 27 | } 28 | 29 | internal override SqlExpression VisitSubSelect(SqlSubSelect ss) 30 | { 31 | bool saveIsTopLevel = _isTopLevel; 32 | try 33 | { 34 | return base.VisitSubSelect(ss); 35 | } 36 | finally 37 | { 38 | _isTopLevel = saveIsTopLevel; 39 | } 40 | } 41 | 42 | class SelectionDeflator : SqlVisitor 43 | { 44 | internal override SqlExpression VisitColumnRef(SqlColumnRef cref) 45 | { 46 | SqlExpression literal = this.GetLiteralValue(cref); 47 | if(literal != null) 48 | { 49 | return literal; 50 | } 51 | return cref; 52 | } 53 | 54 | private SqlValue GetLiteralValue(SqlExpression expr) 55 | { 56 | while(expr != null && expr.NodeType == SqlNodeType.ColumnRef) 57 | { 58 | expr = ((SqlColumnRef)expr).Column.Expression; 59 | } 60 | return expr as SqlValue; 61 | } 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/SubQueryCompiler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data.Linq.Provider.Common; 3 | using System.Data.Linq.Provider.Interfaces; 4 | using System.Data.Linq.Provider.NodeTypes; 5 | 6 | namespace System.Data.Linq.Provider.Visitors 7 | { 8 | internal class SubQueryCompiler : SqlVisitor 9 | { 10 | IProvider provider; 11 | List subQueries; 12 | 13 | internal SubQueryCompiler(IProvider provider) 14 | { 15 | this.provider = provider; 16 | } 17 | 18 | internal ICompiledSubQuery[] Compile(SqlNode node) 19 | { 20 | this.subQueries = new List(); 21 | this.Visit(node); 22 | return this.subQueries.ToArray(); 23 | } 24 | 25 | internal override SqlSelect VisitSelect(SqlSelect select) 26 | { 27 | this.Visit(@select.Selection); 28 | return @select; 29 | } 30 | 31 | internal override SqlExpression VisitSubSelect(SqlSubSelect ss) 32 | { 33 | return ss; 34 | } 35 | 36 | internal override SqlExpression VisitClientQuery(SqlClientQuery cq) 37 | { 38 | Type clientElementType = cq.Query.NodeType == SqlNodeType.Multiset ? TypeSystem.GetElementType(cq.ClrType) : cq.ClrType; 39 | ICompiledSubQuery c = this.provider.CompileSubQuery(cq.Query.Select, clientElementType, cq.Parameters.AsReadOnly()); 40 | cq.Ordinal = this.subQueries.Count; 41 | this.subQueries.Add(c); 42 | return cq; 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/SubqueryValidator.cs: -------------------------------------------------------------------------------- 1 | using System.Linq.Expressions; 2 | 3 | namespace System.Data.Linq.Provider.Visitors 4 | { 5 | /// 6 | /// Ensure that the subquery follows the rules for subqueries. 7 | /// 8 | internal class SubqueryValidator : Provider.Visitors.ExpressionVisitor 9 | { 10 | bool isTopLevel = true; 11 | internal override Expression VisitMethodCall(MethodCallExpression m) 12 | { 13 | bool was = isTopLevel; 14 | try 15 | { 16 | if(isTopLevel && !SubqueryRules.IsSupportedTopLevelMethod(m.Method)) 17 | throw Error.SubqueryDoesNotSupportOperator(m.Method.Name); 18 | isTopLevel = false; 19 | return base.VisitMethodCall(m); 20 | } 21 | finally 22 | { 23 | isTopLevel = was; 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Provider/Visitors/ValidateNoInvalidComparison.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq.Provider.NodeTypes; 2 | 3 | namespace System.Data.Linq.Provider.Visitors 4 | { 5 | /// 6 | /// Determines if there is a boolean NText/Text/Image comparison and if so throws an exception 7 | /// because this is not valid in SQLServer. 8 | /// 9 | internal class ValidateNoInvalidComparison : SqlVisitor 10 | { 11 | 12 | internal override SqlExpression VisitBinaryOperator(SqlBinary bo) 13 | { 14 | if(bo.NodeType == SqlNodeType.EQ || bo.NodeType == SqlNodeType.NE || 15 | bo.NodeType == SqlNodeType.EQ2V || bo.NodeType == SqlNodeType.NE2V || 16 | bo.NodeType == SqlNodeType.GT || bo.NodeType == SqlNodeType.GE || 17 | bo.NodeType == SqlNodeType.LT || bo.NodeType == SqlNodeType.LE) 18 | { 19 | if(!bo.Left.SqlType.SupportsComparison || 20 | !bo.Right.SqlType.SupportsComparison) 21 | { 22 | throw Error.UnhandledStringTypeComparison(); 23 | } 24 | } 25 | bo.Left = this.VisitExpression(bo.Left); 26 | bo.Right = this.VisitExpression(bo.Right); 27 | return bo; 28 | } 29 | 30 | } 31 | } -------------------------------------------------------------------------------- /src/Querying/SubqueryRules.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Reflection; 5 | using System.Linq.Expressions; 6 | 7 | namespace System.Data.Linq { 8 | /// 9 | /// Encodes the rules for subqueries. 10 | /// 11 | static class SubqueryRules { 12 | /// 13 | /// This list of top-level methods that are supported in subqueries. 14 | /// 15 | /// 16 | /// 17 | static internal bool IsSupportedTopLevelMethod(MethodInfo mi) { 18 | if (!IsSequenceOperatorCall(mi)) 19 | return false; 20 | switch (mi.Name) { 21 | case "Where": 22 | case "OrderBy": 23 | case "OrderByDescending": 24 | case "ThenBy": 25 | case "ThenByDescending": 26 | case "Take": 27 | return true; 28 | } 29 | return false; 30 | } 31 | private static bool IsSequenceOperatorCall(MethodInfo mi) { 32 | Type declType = mi.DeclaringType; 33 | if (declType == typeof(System.Linq.Enumerable) || 34 | declType == typeof(System.Linq.Queryable)) { 35 | return true; 36 | } 37 | return false; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/SD.Tools.LinqToDB.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FransBouma/LinqToSQL2/6928cd728095dc7e03a8ec23f75a83d912acc780/src/SD.Tools.LinqToDB.snk -------------------------------------------------------------------------------- /src/SD.Tools.LinqToSQL2.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard2.0;net452 4 | SD.Tools.LinqToSQL2 5 | System.Data.Linq 6 | 1.0 7 | 1.0.0.0 8 | true 9 | false 10 | Solutions Design bv 11 | false 12 | 13 | 14 | Linq to SQL Database Data O/RM ADO.NET 15 | Off 16 | 17 | 18 | 19 | 20 | 21 | 4.4.1 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/SD.Tools.LinqToSQL2.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SD.Tools.LinqToSQL2", "SD.Tools.LinqToSQL2.csproj", "{B4CDAAE3-F3AF-4D58-86F1-D3D756D61888}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B4CDAAE3-F3AF-4D58-86F1-D3D756D61888}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {B4CDAAE3-F3AF-4D58-86F1-D3D756D61888}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {B4CDAAE3-F3AF-4D58-86F1-D3D756D61888}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {B4CDAAE3-F3AF-4D58-86F1-D3D756D61888}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /tests/AdventureWorks2008Model/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/AdventureWorks2008Model/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | [assembly: AssemblyTitle("Linq to Sql 2 AdventureWorks 2008 model")] 5 | [assembly: AssemblyDescription("AdventureWorks 2008 model for read tests for Linq to Sql 2, a full featured ORM based on Linq to Sql.")] 6 | [assembly: AssemblyConfiguration(".NET 4.5+")] 7 | [assembly: AssemblyCompany("Solutions Design bv")] 8 | [assembly: AssemblyProduct("Linq to Sql 2")] 9 | [assembly: AssemblyCopyright("(c) Solutions Design bv")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | [assembly: System.CLSCompliant(false)] 13 | 14 | // Version information for an assembly consists of the following four values: 15 | // 16 | // Major Version 17 | // Minor Version 18 | // Build Number 19 | // Revision 20 | // 21 | // You can specify all the values or you can default the Build and Revision Numbers 22 | // by using the '*' as shown below: 23 | // [assembly: AssemblyVersion("1.0.*")] 24 | [assembly: AssemblyVersion("1.0.0.0")] 25 | [assembly: AssemblyFileVersion("1.0.0.0")] 26 | -------------------------------------------------------------------------------- /tests/AdventureWorks2008Model/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /tests/GenerateTestCode.cmd: -------------------------------------------------------------------------------- 1 | @Echo off 2 | 3 | Echo ================================================================ 4 | Echo Generating code: Read test model, AdventureWorks2008, C# 5 | Echo ================================================================ 6 | "C:\users\frans\LLBLGen Pro v4.2\cligenerator.exe" "SourceProjects\AdventureWorks2008.llblgenproj" "ReadTestsAdventureWorks2008" "C#" ".NET 4.5" "General" "SD.LinqToSql" "AdventureWorks2008Model" 0 "SourceProjects\log_AdventureWorks2008.txt" 7 | Echo ================================================================ 8 | Echo Generating code: Write test model, WriteTests, C# 9 | Echo ================================================================ 10 | "C:\users\frans\LLBLGen Pro v4.2\cligenerator.exe" "SourceProjects\WriteTests.llblgenproj" "WriteTests" "C#" ".NET 4.5" "General" "SD.LinqToSql" "WriteTestsModel" 0 "SourceProjects\log_WriteTests.txt" 11 | -------------------------------------------------------------------------------- /tests/ReadWriteTests/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/ReadWriteTests/Pair.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace ReadWriteTests.SqlServer 7 | { 8 | public class Pair 9 | { 10 | public Pair() 11 | { 12 | } 13 | 14 | public Pair(T1 v1, T2 v2) 15 | { 16 | this.Value1 = v1; 17 | this.Value2 = v2; 18 | } 19 | 20 | public T1 Value1 { get; set; } 21 | public T2 Value2 { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/ReadWriteTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ReadTestsAdventureWorks2008")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ReadTestsAdventureWorks2008")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8d34e233-2375-44a8-9523-1676bf89187b")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /tests/ReadWriteTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /tests/SourceProjects/WriteTests.llblgenproj.typeimports: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /tests/SourceProjects/log_AdventureWorks2008.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FransBouma/LinqToSQL2/6928cd728095dc7e03a8ec23f75a83d912acc780/tests/SourceProjects/log_AdventureWorks2008.txt -------------------------------------------------------------------------------- /tests/SourceProjects/log_WriteTests.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FransBouma/LinqToSQL2/6928cd728095dc7e03a8ec23f75a83d912acc780/tests/SourceProjects/log_WriteTests.txt -------------------------------------------------------------------------------- /tests/WriteTestsModel/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/WriteTestsModel/EntityClasses/DerivedType1.cs: -------------------------------------------------------------------------------- 1 | #pragma warning disable 0649 2 | //------------------------------------------------------------------------------ 3 | // This code was generated by LLBLGen Pro v4.2. 4 | //------------------------------------------------------------------------------ 5 | using System; 6 | using System.Data.Linq; 7 | using System.Data.Linq.Mapping; 8 | using System.ComponentModel; 9 | 10 | namespace WriteTests.EntityClasses 11 | { 12 | /// Class which represents the entity 'DerivedType1', mapped on table 'LLBLGenProUnitTest.dbo.GuidTPEHTester'. 13 | public partial class DerivedType1 : GuidTpehTester 14 | { 15 | #region Class Member Declarations 16 | private System.String _element2; 17 | #endregion 18 | 19 | #region Extensibility Method Definitions 20 | partial void OnLoaded(); 21 | partial void OnValidate(System.Data.Linq.ChangeAction action); 22 | partial void OnCreated(); 23 | partial void OnElement2Changing(System.String value); 24 | partial void OnElement2Changed(); 25 | #endregion 26 | 27 | /// Initializes a new instance of the class. 28 | public DerivedType1() 29 | { 30 | 31 | OnCreated(); 32 | } 33 | 34 | 35 | #region Class Property Declarations 36 | /// Gets or sets the Element2 field. Mapped on target field 'Element2'. 37 | public System.String Element2 38 | { 39 | get { return _element2; } 40 | set 41 | { 42 | if((_element2 != value)) 43 | { 44 | OnElement2Changing(value); 45 | SendPropertyChanging("Element2"); 46 | _element2 = value; 47 | SendPropertyChanged("Element2"); 48 | OnElement2Changed(); 49 | } 50 | } 51 | } 52 | 53 | #endregion 54 | } 55 | } 56 | #pragma warning restore 0649 -------------------------------------------------------------------------------- /tests/WriteTestsModel/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | [assembly: AssemblyTitle("")] 5 | [assembly: AssemblyDescription("")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCompany("")] 8 | [assembly: AssemblyProduct("")] 9 | [assembly: AssemblyCopyright("")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | 13 | // Version information for an assembly consists of the following four values: 14 | // 15 | // Major Version 16 | // Minor Version 17 | // Build Number 18 | // Revision 19 | // 20 | // You can specify all the values or you can default the Build and Revision Numbers 21 | // by using the '*' as shown below: 22 | // [assembly: AssemblyVersion("1.0.*")] 23 | [assembly: AssemblyVersion("1.0.0.0")] 24 | [assembly: AssemblyFileVersion("1.0.0.0")] 25 | --------------------------------------------------------------------------------