From b8c34bd17f5b256ad05ea1665427f48453b4c7e5 Mon Sep 17 00:00:00 2001 From: BriceLambson Date: Fri, 25 Jan 2013 16:11:01 -0800 Subject: [PATCH] Quarantining FunctionalTest files (and their dependencies) that take advantage of EntityFramework's InternalsVisibleTo attribute. --- EF.msbuild | 1 + EF.xunit.targets | 1 + EntityFramework.sln | 11 + packages/repositories.config | 1 + .../Properties/InternalsVisibleTo.cs | 2 +- .../! DON'T ADD TESTS HERE/ReadMe.txt | 2 + .../FunctionalTests.Transitional/App.config | 44 + .../CodeFirst/AdvancedMappingScenarioTests.cs | 1034 +- .../CodeFirst/AssociationScenarioTests.cs | 7058 ++++----- .../CodeFirst/BasicMappingScenarioTests.cs | 12678 ++++++++-------- .../CodeFirst/ComplexTypeScenarioTests.cs | 1306 +- .../CodeFirst/ConfigurationScenarioTests.cs | 696 +- .../CodeFirst/ConventionsScenarioTests.cs | 634 +- .../CodeFirst/DataAnnotationScenarioTests.cs | 1968 +-- .../CodeFirst/DataServicesTests.cs | 132 +- .../CodeFirst/EnumsScenarioTests.cs | 724 +- .../CodeFirst/InheritanceScenarioTests.cs | 3702 ++--- .../PropertyConfigurationScenarioTests.cs | 1098 +- .../FunctionalTests.Transitional.csproj | 591 + .../Metadata/MetadataCachingModel.csdl | 24 +- .../Metadata/MetadataCachingModel.msl | 24 +- .../Metadata/MetadataCachingModel.ssdl | 24 +- .../Metadata/MetadataCachingTests.cs | 292 +- .../Metadata/MetadataEnumTests.cs | 1866 +-- .../Metadata/MetadataFunctionsTests.cs | 848 +- .../Metadata/MetadataSpatialTests.cs | 410 +- .../MetadataMapping/Enum.csdl | 114 +- .../MetadataMapping/Enum.msl | 44 +- .../MetadataMapping/Enum.ssdl | 78 +- .../MetadataMapping/EnumOCMappingTests.cs | 1810 +-- .../Migrations/BasicMigrationScenarios.cs | 1386 +- .../Migrations/CustomHistoryScenarios.cs | 0 .../TestHelpers/DatabaseProviderFixture.cs | 138 +- .../TestHelpers/DbMigratorExtensions.cs | 54 +- .../Migrations/TestHelpers/DbTestCase.cs | 664 +- .../Migrations/TestHelpers/InfoContext.cs | 664 +- .../TestHelpers/MigrationCompiler.cs | 204 +- .../TestHelpers/MigrationsTheoryAttribute.cs | 114 +- .../TestHelpers/MigrationsTheoryCommand.cs | 122 +- .../Migrations/TestHelpers/TestDatabase.cs | 682 +- .../TestHelpers/VariantAttribute.cs | 34 +- .../Migrations/TestModel/TestModels.cs | 802 +- .../Migrations/UpgradeScenarios.cs | 0 .../Objects/TransactionsModel.csdl | 24 +- .../Objects/TransactionsModel.msl | 40 +- .../Objects/TransactionsModel.ssdl | 26 +- .../Objects/TransactionsTests.cs | 2926 ++-- .../ProductivityApi/DbContextTests.cs | 7092 ++++----- .../ProductivityApi/DbFunctionScenarios.cs | 3122 ++-- .../PluralizationServiceTests.cs | 0 .../ProductivityApi/TemplateTests.cs | 1486 +- .../Properties/InternalsVisibleTo.cs | 8 + .../Query/LinqToEntities/EnumTests.cs | 0 .../Query/ModelDefinedFunctionTests.cs | 1364 +- .../Query/ProductModel.cs | 1390 +- .../Query/QueryTestHelpers.cs | 0 .../TestHelpers/AdventureWorksModelBuilder.cs | 92 +- .../TestHelpers/AssemblyResourceLookup.cs | 130 +- .../TestHelpers/ConnectionEventsTracker.cs | 174 +- .../TestHelpers/ConstructionStrategies.cs | 206 +- .../TestHelpers/CsdlToClrAssemblyConverter.cs | 866 +- .../TestHelpers/DbContextExtensions.cs | 50 +- .../DbDatabaseMappingExtensions.cs | 190 +- .../DefaultConnectionFactoryResolver.cs | 72 +- ...DefaultFunctionalTestsConnectionFactory.cs | 42 +- .../DefaultPluralizationServiceResolver.cs | 0 .../DefaultUnitTestsConnectionFactory.cs | 24 +- .../TestHelpers/DynamicAssembly.cs | 1672 +- .../TestHelpers/DynamicTypeDescriptor.cs | 262 +- .../TestHelpers/ExceptionHelpers.cs | 0 .../TestHelpers/ExceptionTestExtensions.cs | 126 +- .../TestHelpers/FakePluralizationService.cs | 48 +- .../TestHelpers/FunctionalTestBase.cs | 646 +- .../FunctionalTestsConfiguration.cs | 0 .../FunctionalTestsManifestTokenService.cs | 42 +- .../TestHelpers/HashSetBasedDbSet.cs | 218 +- .../TestHelpers/IOHelpers.cs | 576 +- .../TestHelpers/ModelAssertions.cs | 894 +- .../TestHelpers/ModelHelpers.cs | 836 +- .../TestHelpers/MutableResolver.cs | 118 +- .../TestHelpers/ObservableListSource`.cs | 162 +- .../TestHelpers/ProviderRegistry.cs | 62 +- .../TestHelpers/ResourceUtilities.cs | 270 +- .../TestHelpers/StringResourceVerifier.cs | 454 +- .../TestHelpers/TestBase.cs | 914 +- .../TestHelpers/TypeAssertion`.cs | 72 +- .../AdvancedPatternsModel/Address.cs | 72 +- .../AdvancedPatternsInitializer.cs | 258 +- .../AdvancedPatternsMasterContext.cs | 114 +- .../AdvancedPatternsModelFirstInitializer.cs | 280 +- .../AdvancedPatternsModel/Building.cs | 90 +- .../AdvancedPatternsModel/BuildingDetail.cs | 26 +- .../AdvancedPatternsModel/CurrentEmployee.cs | 22 +- .../AdvancedPatternsModel/Employee.cs | 18 +- .../AdvancedPatternsModel/MailRoom.cs | 26 +- .../AdvancedPatternsModel/Office.cs | 38 +- .../AdvancedPatternsModel/PastEmployee.cs | 22 +- .../AdvancedPatternsModel/SiteInfo.cs | 20 +- .../AdvancedPatternsModel/UnMappedOffice.cs | 16 +- .../UnMappedOfficeBase.cs | 20 +- .../UnMappedPersonBase.cs | 20 +- .../AdvancedPatternsModel/Whiteboard.cs | 22 +- .../AdvancedPatternsModel/WorkOrder.cs | 24 +- .../AllTypeKeysModel/AllTypeKeysContext.cs | 138 +- .../AllTypeKeysModelInitializer.cs | 256 +- .../AllTypeKeysModel/BoolKeyEntity.cs | 28 +- .../AllTypeKeysModel/ByteKeyEntity.cs | 28 +- .../AllTypeKeysModel/CompositeKeyEntity.cs | 40 +- ...mpositeKeyEntityWithOrderingAnnotations.cs | 44 +- .../AllTypeKeysModel/DateTimeKeyEntity.cs | 30 +- .../DateTimeOffsetKeyEntity.cs | 30 +- .../AllTypeKeysModel/DecimalKeyEntity.cs | 28 +- .../AllTypeKeysModel/DoubleKeyEntity.cs | 28 +- .../AllTypeKeysModel/FloatKeyEntity.cs | 28 +- .../AllTypeKeysModel/GuidKeyEntity.cs | 30 +- .../AllTypeKeysModel/LongKeyEntity.cs | 32 +- .../AllTypeKeysModel/ShortKeyEntity.cs | 28 +- .../AllTypeKeysModel/TimeSpanKeyEntity.cs | 30 +- .../TestModels/ArubaModel/ArubaAllTypes.cs | 0 .../TestModels/ArubaModel/ArubaBaseline.cs | 0 .../TestModels/ArubaModel/ArubaBug.cs | 0 .../TestModels/ArubaModel/ArubaConfig.cs | 0 .../TestModels/ArubaModel/ArubaContext.cs | 0 .../TestModels/ArubaModel/ArubaFailure.cs | 0 .../TestModels/ArubaModel/ArubaInitializer.cs | 0 .../ArubaModel/ArubaMachineConfig.cs | 0 .../TestModels/ArubaModel/ArubaOwner.cs | 0 .../TestModels/ArubaModel/ArubaRun.cs | 0 .../TestModels/ArubaModel/ArubaTask.cs | 0 .../TestModels/ArubaModel/ArubaTaskInfo.cs | 0 .../TestModels/ArubaModel/ArubaTestFailure.cs | 0 .../TestModels/ConcurrencyModel/Chassis.cs | 42 +- .../ConcurrencyModelInitializer.cs | 1748 +-- .../TestModels/ConcurrencyModel/Driver.cs | 52 +- .../TestModels/ConcurrencyModel/Engine.cs | 52 +- .../ConcurrencyModel/EngineSupplier.cs | 30 +- .../TestModels/ConcurrencyModel/F1Context.cs | 190 +- .../TestModels/ConcurrencyModel/Gearbox.cs | 26 +- .../TestModels/ConcurrencyModel/Location.cs | 30 +- .../TestModels/ConcurrencyModel/Sponsor.cs | 48 +- .../ConcurrencyModel/SponsorDetails.cs | 26 +- .../TestModels/ConcurrencyModel/Team.cs | 126 +- .../TestModels/ConcurrencyModel/TestDriver.cs | 16 +- .../ConcurrencyModel/TitleSponsor.cs | 18 +- .../201112202056275_InitialCreate.cs | 52 +- .../201112202056275_InitialCreate.designer.cs | 46 +- .../201112202056573_AddUrlToBlog.cs | 38 +- .../201112202056573_AddUrlToBlog.designer.cs | 46 +- .../TestModels/SimpleMigrationsModel/Blog.cs | 22 +- .../MigrateInitializerConfiguration.cs | 56 +- .../MigrateInitializerContext.cs | 22 +- .../TestModels/SimpleModel/Blog.cs | 30 +- .../TestModels/SimpleModel/Category.cs | 48 +- .../TestModels/SimpleModel/EmptyContext.cs | 48 +- .../TestModels/SimpleModel/ExtraEntity.cs | 26 +- .../TestModels/SimpleModel/FeaturedProduct.cs | 18 +- .../TestModels/SimpleModel/FuncyContexts.cs | 80 +- .../SimpleModel/LiveWriterContext.cs | 64 +- .../TestModels/SimpleModel/Login.cs | 42 +- .../TestModels/SimpleModel/Product.cs | 20 +- .../TestModels/SimpleModel/ProductBase.cs | 20 +- .../SimpleModel/SimpleModelContext.cs | 120 +- .../SimpleModelContextWithNoData.cs | 148 +- .../SimpleModel/SimpleModelInitializer.cs | 146 +- .../TestModels/StoreModel/AbstractType1.cs | 26 +- .../TestModels/StoreModel/AbstractType1_1.cs | 18 +- .../TestModels/StoreModel/Address.cs | 712 +- .../TestModels/StoreModel/AddressType.cs | 258 +- .../TestModels/StoreModel/BillOfMaterials.cs | 368 +- .../TestModels/StoreModel/ColoredProduct.cs | 18 +- .../StoreModel/ConcreteType1_1_1.cs | 18 +- .../TestModels/StoreModel/ConcreteType1_2.cs | 18 +- .../TestModels/StoreModel/Contact.cs | 736 +- .../StoreModel/ContactCreditCard.cs | 246 +- .../TestModels/StoreModel/ContactType.cs | 254 +- .../TestModels/StoreModel/CountryRegion.cs | 254 +- .../StoreModel/CountryRegionCurrency.cs | 246 +- .../TestModels/StoreModel/CreditCard.cs | 284 +- .../TestModels/StoreModel/Culture.cs | 144 +- .../TestModels/StoreModel/Currency.cs | 364 +- .../TestModels/StoreModel/CurrencyRate.cs | 376 +- .../TestModels/StoreModel/Customer.cs | 526 +- .../TestModels/StoreModel/CustomerAddress.cs | 362 +- .../TestModels/StoreModel/CustomerDiscount.cs | 38 +- .../TestModels/StoreModel/Department.cs | 148 +- .../StoreModel/DiscontinuedProduct.cs | 22 +- .../TestModels/StoreModel/Document.cs | 172 +- .../TestModels/StoreModel/Employee.cs | 1070 +- .../TestModels/StoreModel/EmployeeAddress.cs | 254 +- .../StoreModel/EmployeeDepartmentHistory.cs | 366 +- .../StoreModel/EmployeePayHistory.cs | 146 +- .../TestModels/StoreModel/FixupCollection'.cs | 50 +- .../TestModels/StoreModel/Illustration.cs | 144 +- .../TestModels/StoreModel/Individual.cs | 244 +- .../TestModels/StoreModel/JobCandidate.cs | 170 +- .../TestModels/StoreModel/Location.cs | 262 +- .../TestModels/StoreModel/Product.cs | 1920 +-- .../TestModels/StoreModel/ProductCategory.cs | 148 +- .../StoreModel/ProductCostHistory.cs | 146 +- .../StoreModel/ProductDescription.cs | 36 +- .../TestModels/StoreModel/ProductDocument.cs | 246 +- .../TestModels/StoreModel/ProductInventory.cs | 262 +- .../StoreModel/ProductListPriceHistory.cs | 146 +- .../TestModels/StoreModel/ProductModel.cs | 376 +- .../StoreModel/ProductModelIllustration.cs | 246 +- .../ProductModelProductDescriptionCulture.cs | 358 +- .../TestModels/StoreModel/ProductPhoto.cs | 166 +- .../StoreModel/ProductProductPhoto.cs | 250 +- .../TestModels/StoreModel/ProductReview.cs | 158 +- .../StoreModel/ProductSubcategory.cs | 260 +- .../TestModels/StoreModel/ProductVendor.cs | 316 +- .../StoreModel/PurchaseOrderDetail.cs | 278 +- .../StoreModel/PurchaseOrderHeader.cs | 508 +- .../TestModels/StoreModel/RowDetails.cs | 28 +- .../TestModels/StoreModel/SalesOrderDetail.cs | 320 +- .../TestModels/StoreModel/SalesOrderHeader.cs | 1400 +- .../TestModels/StoreModel/SalesPerson.cs | 752 +- .../StoreModel/SalesPersonQuotaHistory.cs | 146 +- .../TestModels/StoreModel/SalesReason.cs | 40 +- .../TestModels/StoreModel/SalesTaxRate.cs | 154 +- .../TestModels/StoreModel/SalesTerritory.cs | 616 +- .../StoreModel/SalesTerritoryHistory.cs | 258 +- .../TestModels/StoreModel/ScrapReason.cs | 144 +- .../TestModels/StoreModel/Shift.cs | 152 +- .../TestModels/StoreModel/ShipMethod.cs | 266 +- .../TestModels/StoreModel/ShoppingCartItem.cs | 154 +- .../TestModels/StoreModel/SpecialOffer.cs | 176 +- .../StoreModel/SpecialOfferProduct.cs | 364 +- .../TestModels/StoreModel/StateProvince.cs | 490 +- .../TestModels/StoreModel/Store.cs | 410 +- .../TestModels/StoreModel/StoreContact.cs | 362 +- .../TestModels/StoreModel/StyledProduct.cs | 24 +- .../StoreModel/TransactionHistory.cs | 44 +- .../StoreModel/TransactionHistoryArchive.cs | 44 +- .../TestModels/StoreModel/UnitMeasure.cs | 28 +- .../TestModels/StoreModel/User.cs | 44 +- .../TestModels/StoreModel/Vendor.cs | 494 +- .../TestModels/StoreModel/VendorAddress.cs | 358 +- .../TestModels/StoreModel/VendorContact.cs | 358 +- .../TestModels/StoreModel/WorkOrder.cs | 432 +- .../TestModels/StoreModel/WorkOrderRouting.cs | 282 +- .../CsAdvancedPatterns/AddressMf.cs | 56 +- .../CsAdvancedPatterns/BuildingDetailMf.cs | 44 +- .../CsAdvancedPatterns/BuildingMf.cs | 66 +- .../CsAdvancedPatterns.Context.cs | 198 +- .../CsAdvancedPatterns.Context.tt | 1468 +- .../CsAdvancedPatterns/CsAdvancedPatterns.cs | 18 +- .../CsAdvancedPatterns/CsAdvancedPatterns.tt | 1688 +- .../CsAdvancedPatterns/CurrentEmployeeMf.cs | 44 +- .../EF.Utility.CS.ttinclude | 5096 +++---- .../CsAdvancedPatterns/EmployeeMf.cs | 42 +- .../CsAdvancedPatterns/MailRoomMf.cs | 44 +- .../CsAdvancedPatterns/OfficeMf.cs | 58 +- .../CsAdvancedPatterns/Partials/AddressMf.cs | 32 +- .../AdvancedPatternsModelFirstContext.cs | 26 +- .../CsAdvancedPatterns/Partials/BuildingMf.cs | 36 +- .../Partials/CurrentEmployeeMf.cs | 32 +- .../CsAdvancedPatterns/Partials/EmployeeMf.cs | 34 +- .../CsAdvancedPatterns/Partials/OfficeMf.cs | 24 +- .../Partials/PastEmployeeMf.cs | 32 +- .../CsAdvancedPatterns/Partials/SiteInfoMf.cs | 34 +- .../CsAdvancedPatterns/PastEmployeeMf.cs | 38 +- .../CsAdvancedPatterns/SiteInfoMf.cs | 38 +- .../CsAdvancedPatterns/WhiteboardMf.cs | 44 +- .../CsAdvancedPatterns/WorkOrderMf.cs | 46 +- .../CsMonsterModel/BackOrderLine2Mm.cs | 36 +- .../CsMonsterModel/BackOrderLineMm.cs | 42 +- .../CsMonsterModel/BarcodeDetailMm.cs | 40 +- .../CsMonsterModel/BarcodeMm.cs | 60 +- .../CsMonsterModel/ComplaintMm.cs | 50 +- .../CsMonsterModel/ComputerDetailMm.cs | 66 +- .../CsMonsterModel/ComputerMm.cs | 44 +- .../CsMonsterModel/ConcurrencyInfoMm.cs | 38 +- .../CsMonsterModel/ContactDetailsMm.cs | 58 +- .../CsMonsterModel/CsMonsterModel.Context.cs | 234 +- .../CsMonsterModel/CsMonsterModel.Context.tt | 1468 +- .../CsMonsterModel/CsMonsterModel.cs | 18 +- .../CsMonsterModel/CsMonsterModel.tt | 1688 +- .../CsMonsterModel/CustomerInfoMm.cs | 40 +- .../CsMonsterModel/DimensionsMm.cs | 40 +- .../CsMonsterModel/DiscontinuedProductMm.cs | 44 +- .../TemplateModels/CsMonsterModel/DriverMm.cs | 44 +- .../CsMonsterModel/EF.Utility.CS.ttinclude | 5096 +++---- .../ExternalTypes/AuditInfoMm.cs | 40 +- .../ExternalTypes/CustomerMm.cs | 60 +- .../ExternalTypes/LicenseStateMm.cs | 22 +- .../CsMonsterModel/ExternalTypes/LoginMm.cs | 52 +- .../CsMonsterModel/ExternalTypes/PhoneMm.cs | 32 +- .../ExternalTypes/PhoneTypeMm.cs | 22 +- .../CsMonsterModel/IncorrectScanMm.cs | 52 +- .../CsMonsterModel/LastLoginMm.cs | 46 +- .../CsMonsterModel/LicenseMm.cs | 62 +- .../CsMonsterModel/MessageMm.cs | 56 +- .../CsMonsterModel/OrderLineMm.cs | 60 +- .../TemplateModels/CsMonsterModel/OrderMm.cs | 68 +- .../CsMonsterModel/OrderNoteMm.cs | 44 +- .../CsMonsterModel/OrderQualityCheckMm.cs | 46 +- .../CsMonsterModel/PageViewMm.cs | 48 +- .../CsMonsterModel/PasswordResetMm.cs | 48 +- .../CsMonsterModel/ProductDetailMm.cs | 44 +- .../CsMonsterModel/ProductMm.cs | 88 +- .../CsMonsterModel/ProductPageViewMm.cs | 42 +- .../CsMonsterModel/ProductPhotoMm.cs | 56 +- .../CsMonsterModel/ProductReviewMm.cs | 58 +- .../CsMonsterModel/ProductWebFeatureMm.cs | 52 +- .../CsMonsterModel/RSATokenMm.cs | 44 +- .../CsMonsterModel/ResolutionMm.cs | 44 +- .../CsMonsterModel/SmartCardMm.cs | 48 +- .../CsMonsterModel/SupplierInfoMm.cs | 44 +- .../CsMonsterModel/SupplierLogoMm.cs | 40 +- .../CsMonsterModel/SupplierMm.cs | 60 +- .../CsMonsterModel/SuspiciousActivityMm.cs | 40 +- .../TemplateModels/ProcessCsTemplate.bat | 10 +- .../TemplateModels/ProcessTemplates.bat | 8 +- .../TemplateModels/ProcessVbTemplate.bat | 10 +- .../Schemas/AdvancedPatterns.edmx | 1154 +- .../TemplateModels/Schemas/MonsterModel.csdl | 1848 +-- .../TemplateModels/Schemas/MonsterModel.msl | 1026 +- .../TemplateModels/Schemas/MonsterModel.ssdl | 1914 +-- .../packages.config | 7 + .../FunctionalTests/App.config | 12 +- .../FunctionalTests/FunctionalTests.csproj | 452 +- .../ProductivityApi/InvalidTypeTests.cs | 2 +- test/EntityFramework/UnitTests/App.config | 2 +- .../UnitTests/UnitTests.csproj | 22 +- test/EntityFramework/VBTests/App.Config | 2 +- test/EntityFramework/VBTests/VBTests.vbproj | 4 + 327 files changed, 61549 insertions(+), 61319 deletions(-) create mode 100644 test/EntityFramework/FunctionalTests.Transitional/! DON'T ADD TESTS HERE/ReadMe.txt create mode 100644 test/EntityFramework/FunctionalTests.Transitional/App.config rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/CodeFirst/AdvancedMappingScenarioTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/CodeFirst/AssociationScenarioTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/CodeFirst/BasicMappingScenarioTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/CodeFirst/ComplexTypeScenarioTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/CodeFirst/ConfigurationScenarioTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/CodeFirst/ConventionsScenarioTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/CodeFirst/DataAnnotationScenarioTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/CodeFirst/DataServicesTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/CodeFirst/EnumsScenarioTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/CodeFirst/InheritanceScenarioTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/CodeFirst/PropertyConfigurationScenarioTests.cs (97%) create mode 100644 test/EntityFramework/FunctionalTests.Transitional/FunctionalTests.Transitional.csproj rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Metadata/MetadataCachingModel.csdl (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Metadata/MetadataCachingModel.msl (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Metadata/MetadataCachingModel.ssdl (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Metadata/MetadataCachingTests.cs (89%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Metadata/MetadataEnumTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Metadata/MetadataFunctionsTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Metadata/MetadataSpatialTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/MetadataMapping/Enum.csdl (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/MetadataMapping/Enum.msl (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/MetadataMapping/Enum.ssdl (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/MetadataMapping/EnumOCMappingTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Migrations/BasicMigrationScenarios.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Migrations/CustomHistoryScenarios.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Migrations/TestHelpers/DatabaseProviderFixture.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Migrations/TestHelpers/DbMigratorExtensions.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Migrations/TestHelpers/DbTestCase.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Migrations/TestHelpers/InfoContext.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Migrations/TestHelpers/MigrationCompiler.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Migrations/TestHelpers/MigrationsTheoryAttribute.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Migrations/TestHelpers/MigrationsTheoryCommand.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Migrations/TestHelpers/TestDatabase.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Migrations/TestHelpers/VariantAttribute.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Migrations/TestModel/TestModels.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Migrations/UpgradeScenarios.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Objects/TransactionsModel.csdl (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Objects/TransactionsModel.msl (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Objects/TransactionsModel.ssdl (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Objects/TransactionsTests.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/ProductivityApi/DbContextTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/ProductivityApi/DbFunctionScenarios.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/ProductivityApi/PluralizationServiceTests.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/ProductivityApi/TemplateTests.cs (97%) create mode 100644 test/EntityFramework/FunctionalTests.Transitional/Properties/InternalsVisibleTo.cs rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Query/LinqToEntities/EnumTests.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Query/ModelDefinedFunctionTests.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Query/ProductModel.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/Query/QueryTestHelpers.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/AdventureWorksModelBuilder.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/AssemblyResourceLookup.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/ConnectionEventsTracker.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/ConstructionStrategies.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/CsdlToClrAssemblyConverter.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/DbContextExtensions.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/DbDatabaseMappingExtensions.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/DefaultConnectionFactoryResolver.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/DefaultFunctionalTestsConnectionFactory.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/DefaultPluralizationServiceResolver.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/DefaultUnitTestsConnectionFactory.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/DynamicAssembly.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/DynamicTypeDescriptor.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/ExceptionHelpers.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/ExceptionTestExtensions.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/FakePluralizationService.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/FunctionalTestBase.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/FunctionalTestsConfiguration.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/FunctionalTestsManifestTokenService.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/HashSetBasedDbSet.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/IOHelpers.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/ModelAssertions.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/ModelHelpers.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/MutableResolver.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/ObservableListSource`.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/ProviderRegistry.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/ResourceUtilities.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/StringResourceVerifier.cs (98%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/TestBase.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestHelpers/TypeAssertion`.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/Address.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/AdvancedPatternsInitializer.cs (98%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/AdvancedPatternsMasterContext.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/AdvancedPatternsModelFirstInitializer.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/Building.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/BuildingDetail.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/CurrentEmployee.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/Employee.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/MailRoom.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/Office.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/PastEmployee.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/SiteInfo.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/UnMappedOffice.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/UnMappedOfficeBase.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/UnMappedPersonBase.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/Whiteboard.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AdvancedPatternsModel/WorkOrder.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AllTypeKeysModel/AllTypeKeysContext.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AllTypeKeysModel/AllTypeKeysModelInitializer.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AllTypeKeysModel/BoolKeyEntity.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AllTypeKeysModel/ByteKeyEntity.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AllTypeKeysModel/CompositeKeyEntity.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AllTypeKeysModel/CompositeKeyEntityWithOrderingAnnotations.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AllTypeKeysModel/DateTimeKeyEntity.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AllTypeKeysModel/DateTimeOffsetKeyEntity.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AllTypeKeysModel/DecimalKeyEntity.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AllTypeKeysModel/DoubleKeyEntity.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AllTypeKeysModel/FloatKeyEntity.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AllTypeKeysModel/GuidKeyEntity.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AllTypeKeysModel/LongKeyEntity.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AllTypeKeysModel/ShortKeyEntity.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/AllTypeKeysModel/TimeSpanKeyEntity.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ArubaModel/ArubaAllTypes.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ArubaModel/ArubaBaseline.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ArubaModel/ArubaBug.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ArubaModel/ArubaConfig.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ArubaModel/ArubaContext.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ArubaModel/ArubaFailure.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ArubaModel/ArubaInitializer.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ArubaModel/ArubaMachineConfig.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ArubaModel/ArubaOwner.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ArubaModel/ArubaRun.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ArubaModel/ArubaTask.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ArubaModel/ArubaTaskInfo.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ArubaModel/ArubaTestFailure.cs (100%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ConcurrencyModel/Chassis.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ConcurrencyModel/ConcurrencyModelInitializer.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ConcurrencyModel/Driver.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ConcurrencyModel/Engine.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ConcurrencyModel/EngineSupplier.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ConcurrencyModel/F1Context.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ConcurrencyModel/Gearbox.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ConcurrencyModel/Location.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ConcurrencyModel/Sponsor.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ConcurrencyModel/SponsorDetails.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ConcurrencyModel/Team.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ConcurrencyModel/TestDriver.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/ConcurrencyModel/TitleSponsor.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleMigrationsModel/201112202056275_InitialCreate.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleMigrationsModel/201112202056275_InitialCreate.designer.cs (98%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleMigrationsModel/201112202056573_AddUrlToBlog.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleMigrationsModel/201112202056573_AddUrlToBlog.designer.cs (98%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleMigrationsModel/Blog.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleMigrationsModel/MigrateInitializerConfiguration.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleMigrationsModel/MigrateInitializerContext.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleModel/Blog.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleModel/Category.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleModel/EmptyContext.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleModel/ExtraEntity.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleModel/FeaturedProduct.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleModel/FuncyContexts.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleModel/LiveWriterContext.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleModel/Login.cs (95%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleModel/Product.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleModel/ProductBase.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleModel/SimpleModelContext.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleModel/SimpleModelContextWithNoData.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/SimpleModel/SimpleModelInitializer.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/AbstractType1.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/AbstractType1_1.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/Address.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/AddressType.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/BillOfMaterials.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ColoredProduct.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ConcreteType1_1_1.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ConcreteType1_2.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/Contact.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ContactCreditCard.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ContactType.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/CountryRegion.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/CountryRegionCurrency.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/CreditCard.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/Culture.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/Currency.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/CurrencyRate.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/Customer.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/CustomerAddress.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/CustomerDiscount.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/Department.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/DiscontinuedProduct.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/Document.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/Employee.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/EmployeeAddress.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/EmployeeDepartmentHistory.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/EmployeePayHistory.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/FixupCollection'.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/Illustration.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/Individual.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/JobCandidate.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/Location.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/Product.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ProductCategory.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ProductCostHistory.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ProductDescription.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ProductDocument.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ProductInventory.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ProductListPriceHistory.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ProductModel.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ProductModelIllustration.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ProductModelProductDescriptionCulture.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ProductPhoto.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ProductProductPhoto.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ProductReview.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ProductSubcategory.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ProductVendor.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/PurchaseOrderDetail.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/PurchaseOrderHeader.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/RowDetails.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/SalesOrderDetail.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/SalesOrderHeader.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/SalesPerson.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/SalesPersonQuotaHistory.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/SalesReason.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/SalesTaxRate.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/SalesTerritory.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/SalesTerritoryHistory.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ScrapReason.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/Shift.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ShipMethod.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/ShoppingCartItem.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/SpecialOffer.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/SpecialOfferProduct.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/StateProvince.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/Store.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/StoreContact.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/StyledProduct.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/TransactionHistory.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/TransactionHistoryArchive.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/UnitMeasure.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/User.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/Vendor.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/VendorAddress.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/VendorContact.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/WorkOrder.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/StoreModel/WorkOrderRouting.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/AddressMf.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/BuildingDetailMf.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/BuildingMf.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.Context.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.Context.tt (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.tt (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/CurrentEmployeeMf.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/EF.Utility.CS.ttinclude (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/EmployeeMf.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/MailRoomMf.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/OfficeMf.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/Partials/AddressMf.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/Partials/AdvancedPatternsModelFirstContext.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/Partials/BuildingMf.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/Partials/CurrentEmployeeMf.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/Partials/EmployeeMf.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/Partials/OfficeMf.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/Partials/PastEmployeeMf.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/Partials/SiteInfoMf.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/PastEmployeeMf.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/SiteInfoMf.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/WhiteboardMf.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsAdvancedPatterns/WorkOrderMf.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/BackOrderLine2Mm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/BackOrderLineMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/BarcodeDetailMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/BarcodeMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ComplaintMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ComputerDetailMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ComputerMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ConcurrencyInfoMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ContactDetailsMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.Context.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.Context.tt (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.tt (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/CustomerInfoMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/DimensionsMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/DiscontinuedProductMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/DriverMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/EF.Utility.CS.ttinclude (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/AuditInfoMm.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/CustomerMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/LicenseStateMm.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/LoginMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/PhoneMm.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/PhoneTypeMm.cs (96%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/IncorrectScanMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/LastLoginMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/LicenseMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/MessageMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/OrderLineMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/OrderMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/OrderNoteMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/OrderQualityCheckMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/PageViewMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/PasswordResetMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ProductDetailMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ProductMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ProductPageViewMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ProductPhotoMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ProductReviewMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ProductWebFeatureMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/RSATokenMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/ResolutionMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/SmartCardMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/SupplierInfoMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/SupplierLogoMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/SupplierMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/CsMonsterModel/SuspiciousActivityMm.cs (97%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/ProcessCsTemplate.bat (99%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/ProcessTemplates.bat (99%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/ProcessVbTemplate.bat (99%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/Schemas/AdvancedPatterns.edmx (98%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/Schemas/MonsterModel.csdl (98%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/Schemas/MonsterModel.msl (98%) rename test/EntityFramework/{FunctionalTests => FunctionalTests.Transitional}/TestModels/TemplateModels/Schemas/MonsterModel.ssdl (98%) create mode 100644 test/EntityFramework/FunctionalTests.Transitional/packages.config diff --git a/EF.msbuild b/EF.msbuild index 5b74c3f6..f3dc3426 100644 --- a/EF.msbuild +++ b/EF.msbuild @@ -17,6 +17,7 @@ + diff --git a/EF.xunit.targets b/EF.xunit.targets index a9127ffd..c24f2413 100644 --- a/EF.xunit.targets +++ b/EF.xunit.targets @@ -13,6 +13,7 @@ + diff --git a/EntityFramework.sln b/EntityFramework.sln index 556214ca..dc482030 100644 --- a/EntityFramework.sln +++ b/EntityFramework.sln @@ -70,6 +70,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityFramework.SqlServer", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityFramework.SqlServerCompact", "src\EntityFramework.SqlServerCompact\EntityFramework.SqlServerCompact.csproj", "{1EF9C524-7122-4677-B111-DD14BB2A9EA2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FunctionalTests.Transitional", "test\EntityFramework\FunctionalTests.Transitional\FunctionalTests.Transitional.csproj", "{3D65611F-E8FB-4A33-9196-7836969D6378}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -148,6 +150,14 @@ Global {1EF9C524-7122-4677-B111-DD14BB2A9EA2}.Release|Any CPU.Build.0 = Release|Any CPU {1EF9C524-7122-4677-B111-DD14BB2A9EA2}.ReleaseNet40|Any CPU.ActiveCfg = ReleaseNet40|Any CPU {1EF9C524-7122-4677-B111-DD14BB2A9EA2}.ReleaseNet40|Any CPU.Build.0 = ReleaseNet40|Any CPU + {3D65611F-E8FB-4A33-9196-7836969D6378}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D65611F-E8FB-4A33-9196-7836969D6378}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D65611F-E8FB-4A33-9196-7836969D6378}.DebugNet40|Any CPU.ActiveCfg = Debug|Any CPU + {3D65611F-E8FB-4A33-9196-7836969D6378}.DebugNet40|Any CPU.Build.0 = Debug|Any CPU + {3D65611F-E8FB-4A33-9196-7836969D6378}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D65611F-E8FB-4A33-9196-7836969D6378}.Release|Any CPU.Build.0 = Release|Any CPU + {3D65611F-E8FB-4A33-9196-7836969D6378}.ReleaseNet40|Any CPU.ActiveCfg = Release|Any CPU + {3D65611F-E8FB-4A33-9196-7836969D6378}.ReleaseNet40|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -162,5 +172,6 @@ Global {E8E91C5F-E54C-41B1-AE1B-62E047BF49D5} = {24A9C4D1-E189-4D3A-A2D7-36D3ED51D277} {23330EF8-2593-4B0A-A70F-12E6BE1F46C4} = {24A9C4D1-E189-4D3A-A2D7-36D3ED51D277} {CF1C27F8-D603-4960-BE99-BCF348545368} = {24A9C4D1-E189-4D3A-A2D7-36D3ED51D277} + {3D65611F-E8FB-4A33-9196-7836969D6378} = {24A9C4D1-E189-4D3A-A2D7-36D3ED51D277} EndGlobalSection EndGlobal diff --git a/packages/repositories.config b/packages/repositories.config index edc1a282..fc326803 100644 --- a/packages/repositories.config +++ b/packages/repositories.config @@ -1,6 +1,7 @@  + diff --git a/src/EntityFramework/Properties/InternalsVisibleTo.cs b/src/EntityFramework/Properties/InternalsVisibleTo.cs index 487bc1e8..d2d634aa 100644 --- a/src/EntityFramework/Properties/InternalsVisibleTo.cs +++ b/src/EntityFramework/Properties/InternalsVisibleTo.cs @@ -10,7 +10,7 @@ )] [assembly: InternalsVisibleTo( - "EntityFramework.FunctionalTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293" + "EntityFramework.FunctionalTests.Transitional, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293" )] // for Moq diff --git a/test/EntityFramework/FunctionalTests.Transitional/! DON'T ADD TESTS HERE/ReadMe.txt b/test/EntityFramework/FunctionalTests.Transitional/! DON'T ADD TESTS HERE/ReadMe.txt new file mode 100644 index 00000000..15145eb4 --- /dev/null +++ b/test/EntityFramework/FunctionalTests.Transitional/! DON'T ADD TESTS HERE/ReadMe.txt @@ -0,0 +1,2 @@ +This project is being used to quarantine files that depend on EntityFramework's InternalsVisibleTo attribute. +New tests should be added to the FunctionalTests project. diff --git a/test/EntityFramework/FunctionalTests.Transitional/App.config b/test/EntityFramework/FunctionalTests.Transitional/App.config new file mode 100644 index 00000000..758f29d5 --- /dev/null +++ b/test/EntityFramework/FunctionalTests.Transitional/App.config @@ -0,0 +1,44 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/CodeFirst/AdvancedMappingScenarioTests.cs b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/AdvancedMappingScenarioTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/CodeFirst/AdvancedMappingScenarioTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/CodeFirst/AdvancedMappingScenarioTests.cs index 782c56aa..63b7ec87 100644 --- a/test/EntityFramework/FunctionalTests/CodeFirst/AdvancedMappingScenarioTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/AdvancedMappingScenarioTests.cs @@ -1,517 +1,517 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests -{ - using System; - using System.Data.Entity; - using System.Data.Entity.Core; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.ModelConfiguration; - using System.Data.Entity.ModelConfiguration.Edm; - using System.Data.Entity.Resources; - using System.Linq; - using System.Linq.Expressions; - using FunctionalTests.Fixtures; - using FunctionalTests.Model; - using Xunit; - - public sealed class AdvancedMappingScenarioTests : TestBase - { - [Fact] - public void Sql_ce_should_get_explicit_max_lengths_for_string_and_binary_properties_by_convention() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildCeMapping(modelBuilder); - - databaseMapping.AssertValid(); - - databaseMapping.Assert(e => e.Id).DbEqual(4000, f => f.MaxLength); - databaseMapping.Assert(e => e.Id).DbEqual(false, f => f.IsMaxLength); - databaseMapping.Assert(e => e.Id).DbEqual("nvarchar", c => c.TypeName); - - databaseMapping.Assert(e => e.Prop1).DbEqual(4000, f => f.MaxLength); - databaseMapping.Assert(e => e.Prop1).DbEqual(false, f => f.IsMaxLength); - databaseMapping.Assert(e => e.Prop1).DbEqual("nvarchar", c => c.TypeName); - - databaseMapping.Assert(e => e.Prop2).DbEqual(4000, f => f.MaxLength); - databaseMapping.Assert(e => e.Prop2).DbEqual(false, f => f.IsMaxLength); - databaseMapping.Assert(e => e.Prop2).DbEqual("varbinary", c => c.TypeName); - } - - [Fact] - public void Sql_ce_should_get_explicit_max_lengths_for_fixed_length_string_and_fixed_length_binary_properties_by_convention() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Property(e => e.Id).IsFixedLength(); - modelBuilder.Entity().Property(e => e.Prop1).IsFixedLength(); - modelBuilder.Entity().Property(e => e.Prop2).IsFixedLength(); - - var databaseMapping = BuildCeMapping(modelBuilder); - - databaseMapping.AssertValid(); - - databaseMapping.Assert(e => e.Id).DbEqual(4000, f => f.MaxLength); - databaseMapping.Assert(e => e.Id).DbEqual(false, f => f.IsMaxLength); - databaseMapping.Assert(e => e.Id).DbEqual("nchar", c => c.TypeName); - - databaseMapping.Assert(e => e.Prop1).DbEqual(4000, f => f.MaxLength); - databaseMapping.Assert(e => e.Prop1).DbEqual(false, f => f.IsMaxLength); - databaseMapping.Assert(e => e.Prop1).DbEqual("nchar", c => c.TypeName); - - databaseMapping.Assert(e => e.Prop2).DbEqual(4000, f => f.MaxLength); - databaseMapping.Assert(e => e.Prop2).DbEqual(false, f => f.IsMaxLength); - databaseMapping.Assert(e => e.Prop2).DbEqual("binary", c => c.TypeName); - } - - [Fact] - public void Sql_should_get_implicit_max_lengths_for_string_and_binary_properties_by_convention() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - databaseMapping.Assert(e => e.Id).DbEqual(128, f => f.MaxLength); - databaseMapping.Assert(e => e.Id).DbEqual(false, f => f.IsMaxLength); - databaseMapping.Assert(e => e.Id).DbEqual("nvarchar", c => c.TypeName); - - databaseMapping.Assert(e => e.Prop1).DbEqual(null, f => f.MaxLength); - databaseMapping.Assert(e => e.Prop1).DbEqual(false, f => f.IsMaxLength); - databaseMapping.Assert(e => e.Prop1).DbEqual("nvarchar(max)", c => c.TypeName); - - databaseMapping.Assert(e => e.Prop2).DbEqual(null, f => f.MaxLength); - databaseMapping.Assert(e => e.Prop2).DbEqual(false, f => f.IsMaxLength); - databaseMapping.Assert(e => e.Prop2).DbEqual("varbinary(max)", c => c.TypeName); - } - - [Fact] - public void Sql_should_get_explicit_max_lengths_for_fixed_length_string_and_fixed_length_binary_properties_by_convention() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Property(e => e.Id).IsFixedLength(); - modelBuilder.Entity().Property(e => e.Prop1).IsFixedLength(); - modelBuilder.Entity().Property(e => e.Prop2).IsFixedLength(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - databaseMapping.Assert(e => e.Id).DbEqual(128, f => f.MaxLength); - databaseMapping.Assert(e => e.Id).DbEqual(false, f => f.IsMaxLength); - databaseMapping.Assert(e => e.Id).DbEqual("nchar", c => c.TypeName); - - databaseMapping.Assert(e => e.Prop1).DbEqual(128, f => f.MaxLength); - databaseMapping.Assert(e => e.Prop1).DbEqual(false, f => f.IsMaxLength); - databaseMapping.Assert(e => e.Prop1).DbEqual("nchar", c => c.TypeName); - - databaseMapping.Assert(e => e.Prop2).DbEqual(128, f => f.MaxLength); - databaseMapping.Assert(e => e.Prop2).DbEqual(false, f => f.IsMaxLength); - databaseMapping.Assert(e => e.Prop2).DbEqual("binary", c => c.TypeName); - } - - [Fact] - public void Can_have_configured_duplicate_column_and_by_convention_column_is_uniquified() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(e => e.Description).DbEqual( - "Description1", - c => c.Name); - databaseMapping.Assert(e => e.Details).DbEqual( - "Description", - c => c.Name); - } - - [Fact] - public void Can_have_configured_duplicate_column_and_by_convention_columns_are_uniquified_first() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().Property(e => e.Description).HasColumnName("Description"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(e => e.Description).DbEqual("Description", c => c.Name); - databaseMapping.Assert(e => e.Description).DbEqual("Description1", c => c.Name); - databaseMapping.Assert(e => e.Description).DbEqual("Description2", c => c.Name); - } - - [Fact] - public void Can_have_configured_duplicate_column_and_by_convention_columns_are_uniquified_second() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().Property(e => e.Description).HasColumnName("Description"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(e => e.Description).DbEqual("Description1", c => c.Name); - databaseMapping.Assert(e => e.Description).DbEqual("Description", c => c.Name); - databaseMapping.Assert(e => e.Description).DbEqual("Description2", c => c.Name); - } - - [Fact] - public void Can_have_configured_duplicate_column_and_by_convention_columns_are_uniquified_third() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().Property(e => e.Description).HasColumnName("Description"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(e => e.Description).DbEqual("Description1", c => c.Name); - databaseMapping.Assert(e => e.Description).DbEqual("Description2", c => c.Name); - databaseMapping.Assert(e => e.Description).DbEqual("Description", c => c.Name); - } - - [Fact] - public void Can_have_configured_duplicate_column_and_by_convention_columns_are_uniquified_complex() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Property(e => e.Complex.Description).HasColumnName("Description"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(c => c.Description).DbEqual("Description", c => c.Name); - databaseMapping.Assert(c => c.Description).DbEqual(false, c => c.Nullable); - databaseMapping.Assert(e => e.Description).DbEqual("Description1", c => c.Name); - } - - [Fact] - public void Can_have_configured_complex_column_override_column_name_clash() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Property(e => e.Complex.Description).HasColumnName("Description"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(c => c.Description).DbEqual(false, c => c.Nullable); - databaseMapping.Assert(c => c.Description).DbEqual("Description", c => c.Name); - databaseMapping.Assert(e => e.Description).DbEqual("Description1", c => c.Name); - } - - [Fact] - public void Can_have_configured_duplicate_column_and_by_convention_columns_are_uniquified_conflict() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().Property(e => e.Description).HasColumnName("Description"); - modelBuilder.Entity().Property(e => e.Description).HasColumnName("Description"); - - Assert.Throws(() => BuildMapping(modelBuilder)); - } - - [Fact] - public void Can_table_split_and_conflicting_columns_are_uniquified() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().ToTable("Product"); - modelBuilder.Entity().ToTable("Product"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Can_table_split_and_conflicting_columns_can_be_configured() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().ToTable("Product"); - modelBuilder.Entity().ToTable("Product"); - modelBuilder.Entity().Property(s => s.Name).HasColumnName("Unique"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(s => s.Name).DbEqual("Name", c => c.Name); - databaseMapping.Assert(s => s.Name).DbEqual("Unique", c => c.Name); - } - - [Fact] - public void Single_abstract_type_with_associations_throws_not_mappable_exception() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - Assert.Equal( - Strings.UnmappedAbstractType(typeof(SingleAbstract)), - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)).Message); - } - - [Fact] - public void Configured_decimal_key_gets_correct_facet_defaults() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey(d => d.Id); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(d => d.Id).FacetEqual((byte)18, f => f.Precision); - databaseMapping.Assert(d => d.Id).FacetEqual((byte)2, f => f.Scale); - } - - [Fact] - public void Decimal_key_with_custom_store_type_should_propagate_facets() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Property(p => p.Id).HasColumnType("money"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Throw_when_mapping_properties_expression_contains_assignments() - { - var modelBuilder = new DbModelBuilder(); - - Expression> propertiesExpression = so => new - { - Foo = so.LocationId - }; - - Assert.Equal( - Strings.InvalidComplexPropertiesExpression(propertiesExpression), - Assert.Throws( - () => - modelBuilder - .Entity() - .Map(emc => emc.Properties(propertiesExpression))) - .Message); - } - - [Fact] - public void Circular_delete_cascade_path_can_be_generated() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - Assert.Equal( - 3, - databaseMapping.Model - .AssociationTypes - .SelectMany(a => a.Members) - .Cast() - .Count(e => e.DeleteBehavior == OperationAction.Cascade)); - } - - [Fact] - public void Build_model_for_entity_splitting_difference_schemas() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - m => - { - m.Properties( - v1 => new - { - v1.VendorID, - v1.Name, - v1.PreferredVendorStatus, - v1.AccountNumber, - v1.ActiveFlag, - v1.CreditRating - }); - m.ToTable("Vendor", "vendors"); - }) - .Map( - m => - { - m.Properties( - v2 => new - { - v2.VendorID, - v2.ModifiedDate, - v2.PurchasingWebServiceURL - }); - m.ToTable("VendorDetails", "details"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "vendors")); - Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "details")); - } - - [Fact] - public void Build_model_for_mapping_to_duplicate_tables_different_schemas() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("tbl"); - modelBuilder.Entity().ToTable("tbl", "other"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "dbo")); - Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "other")); - - databaseMapping.Assert().DbEqual("tbl", t => t.Table); - databaseMapping.Assert().DbEqual("tbl", t => t.Table); - } - - [Fact] - public void Build_model_after_configuring_entity_set_name() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasEntitySetName("Foos"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.True(databaseMapping.Model.Containers.Single().EntitySets.Any(es => es.Name == "Foos")); - } - } - - namespace Fixtures - { - using System.Collections.Generic; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; - - public class StockOrder - { - public int Id { get; set; } - public int LocationId { get; set; } - public Location Location { get; set; } - public ICollection Organizations { get; set; } - } - - public class Organization - { - public int Id { get; set; } - public int StockOrderId { get; set; } - public StockOrder StockOrder { get; set; } - public ICollection Locations { get; set; } - } - - public class Location - { - public int Id { get; set; } - public ICollection StockOrders { get; set; } - public int OrganizationId { get; set; } - public Organization Organization { get; set; } - } - - public class DecimalKey - { - public decimal Id { get; set; } - public ICollection DecimalDependents { get; set; } - } - - public class DecimalDependent - { - public int Id { get; set; } - public decimal DecimalKeyId { get; set; } - } - - public abstract class SingleAbstract - { - public int Id { get; set; } - public DecimalDependent Nav { get; set; } - } - - public class SplitProduct - { - public int Id { get; set; } - public string Name { get; set; } - - [Required] - public SplitProductDetail Detail { get; set; } - } - - public class SplitProductDetail - { - [ForeignKey("Product")] - public int Id { get; set; } - - public string Name { get; set; } - - [Required] - public SplitProduct Product { get; set; } - } - - public class EntityWithConfiguredDuplicateColumn - { - public int Id { get; set; } - public string Description { get; set; } - - [Column("Description")] - public string Details { get; set; } - } - - public class EntityWithDescBase - { - public int Id { get; set; } - } - - public class EntityWithDescA : EntityWithDescBase - { - public string Description { get; set; } - public ComplexWithDesc Complex { get; set; } - } - - public class EntityWithDescB : EntityWithDescBase - { - public string Description { get; set; } - public ComplexWithDesc Complex { get; set; } - } - - public class EntityWithDescC : EntityWithDescBase - { - public string Description { get; set; } - public ComplexWithDesc Complex { get; set; } - } - - public class ComplexWithDesc - { - [Required] - public string Description { get; set; } - } - - public class MaxLengthProperties - { - public string Id { get; set; } - public string Prop1 { get; set; } - public byte[] Prop2 { get; set; } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests +{ + using System; + using System.Data.Entity; + using System.Data.Entity.Core; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.ModelConfiguration; + using System.Data.Entity.ModelConfiguration.Edm; + using System.Data.Entity.Resources; + using System.Linq; + using System.Linq.Expressions; + using FunctionalTests.Fixtures; + using FunctionalTests.Model; + using Xunit; + + public sealed class AdvancedMappingScenarioTests : TestBase + { + [Fact] + public void Sql_ce_should_get_explicit_max_lengths_for_string_and_binary_properties_by_convention() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildCeMapping(modelBuilder); + + databaseMapping.AssertValid(); + + databaseMapping.Assert(e => e.Id).DbEqual(4000, f => f.MaxLength); + databaseMapping.Assert(e => e.Id).DbEqual(false, f => f.IsMaxLength); + databaseMapping.Assert(e => e.Id).DbEqual("nvarchar", c => c.TypeName); + + databaseMapping.Assert(e => e.Prop1).DbEqual(4000, f => f.MaxLength); + databaseMapping.Assert(e => e.Prop1).DbEqual(false, f => f.IsMaxLength); + databaseMapping.Assert(e => e.Prop1).DbEqual("nvarchar", c => c.TypeName); + + databaseMapping.Assert(e => e.Prop2).DbEqual(4000, f => f.MaxLength); + databaseMapping.Assert(e => e.Prop2).DbEqual(false, f => f.IsMaxLength); + databaseMapping.Assert(e => e.Prop2).DbEqual("varbinary", c => c.TypeName); + } + + [Fact] + public void Sql_ce_should_get_explicit_max_lengths_for_fixed_length_string_and_fixed_length_binary_properties_by_convention() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Property(e => e.Id).IsFixedLength(); + modelBuilder.Entity().Property(e => e.Prop1).IsFixedLength(); + modelBuilder.Entity().Property(e => e.Prop2).IsFixedLength(); + + var databaseMapping = BuildCeMapping(modelBuilder); + + databaseMapping.AssertValid(); + + databaseMapping.Assert(e => e.Id).DbEqual(4000, f => f.MaxLength); + databaseMapping.Assert(e => e.Id).DbEqual(false, f => f.IsMaxLength); + databaseMapping.Assert(e => e.Id).DbEqual("nchar", c => c.TypeName); + + databaseMapping.Assert(e => e.Prop1).DbEqual(4000, f => f.MaxLength); + databaseMapping.Assert(e => e.Prop1).DbEqual(false, f => f.IsMaxLength); + databaseMapping.Assert(e => e.Prop1).DbEqual("nchar", c => c.TypeName); + + databaseMapping.Assert(e => e.Prop2).DbEqual(4000, f => f.MaxLength); + databaseMapping.Assert(e => e.Prop2).DbEqual(false, f => f.IsMaxLength); + databaseMapping.Assert(e => e.Prop2).DbEqual("binary", c => c.TypeName); + } + + [Fact] + public void Sql_should_get_implicit_max_lengths_for_string_and_binary_properties_by_convention() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + databaseMapping.Assert(e => e.Id).DbEqual(128, f => f.MaxLength); + databaseMapping.Assert(e => e.Id).DbEqual(false, f => f.IsMaxLength); + databaseMapping.Assert(e => e.Id).DbEqual("nvarchar", c => c.TypeName); + + databaseMapping.Assert(e => e.Prop1).DbEqual(null, f => f.MaxLength); + databaseMapping.Assert(e => e.Prop1).DbEqual(false, f => f.IsMaxLength); + databaseMapping.Assert(e => e.Prop1).DbEqual("nvarchar(max)", c => c.TypeName); + + databaseMapping.Assert(e => e.Prop2).DbEqual(null, f => f.MaxLength); + databaseMapping.Assert(e => e.Prop2).DbEqual(false, f => f.IsMaxLength); + databaseMapping.Assert(e => e.Prop2).DbEqual("varbinary(max)", c => c.TypeName); + } + + [Fact] + public void Sql_should_get_explicit_max_lengths_for_fixed_length_string_and_fixed_length_binary_properties_by_convention() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Property(e => e.Id).IsFixedLength(); + modelBuilder.Entity().Property(e => e.Prop1).IsFixedLength(); + modelBuilder.Entity().Property(e => e.Prop2).IsFixedLength(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + databaseMapping.Assert(e => e.Id).DbEqual(128, f => f.MaxLength); + databaseMapping.Assert(e => e.Id).DbEqual(false, f => f.IsMaxLength); + databaseMapping.Assert(e => e.Id).DbEqual("nchar", c => c.TypeName); + + databaseMapping.Assert(e => e.Prop1).DbEqual(128, f => f.MaxLength); + databaseMapping.Assert(e => e.Prop1).DbEqual(false, f => f.IsMaxLength); + databaseMapping.Assert(e => e.Prop1).DbEqual("nchar", c => c.TypeName); + + databaseMapping.Assert(e => e.Prop2).DbEqual(128, f => f.MaxLength); + databaseMapping.Assert(e => e.Prop2).DbEqual(false, f => f.IsMaxLength); + databaseMapping.Assert(e => e.Prop2).DbEqual("binary", c => c.TypeName); + } + + [Fact] + public void Can_have_configured_duplicate_column_and_by_convention_column_is_uniquified() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(e => e.Description).DbEqual( + "Description1", + c => c.Name); + databaseMapping.Assert(e => e.Details).DbEqual( + "Description", + c => c.Name); + } + + [Fact] + public void Can_have_configured_duplicate_column_and_by_convention_columns_are_uniquified_first() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().Property(e => e.Description).HasColumnName("Description"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(e => e.Description).DbEqual("Description", c => c.Name); + databaseMapping.Assert(e => e.Description).DbEqual("Description1", c => c.Name); + databaseMapping.Assert(e => e.Description).DbEqual("Description2", c => c.Name); + } + + [Fact] + public void Can_have_configured_duplicate_column_and_by_convention_columns_are_uniquified_second() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().Property(e => e.Description).HasColumnName("Description"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(e => e.Description).DbEqual("Description1", c => c.Name); + databaseMapping.Assert(e => e.Description).DbEqual("Description", c => c.Name); + databaseMapping.Assert(e => e.Description).DbEqual("Description2", c => c.Name); + } + + [Fact] + public void Can_have_configured_duplicate_column_and_by_convention_columns_are_uniquified_third() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().Property(e => e.Description).HasColumnName("Description"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(e => e.Description).DbEqual("Description1", c => c.Name); + databaseMapping.Assert(e => e.Description).DbEqual("Description2", c => c.Name); + databaseMapping.Assert(e => e.Description).DbEqual("Description", c => c.Name); + } + + [Fact] + public void Can_have_configured_duplicate_column_and_by_convention_columns_are_uniquified_complex() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Property(e => e.Complex.Description).HasColumnName("Description"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(c => c.Description).DbEqual("Description", c => c.Name); + databaseMapping.Assert(c => c.Description).DbEqual(false, c => c.Nullable); + databaseMapping.Assert(e => e.Description).DbEqual("Description1", c => c.Name); + } + + [Fact] + public void Can_have_configured_complex_column_override_column_name_clash() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Property(e => e.Complex.Description).HasColumnName("Description"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(c => c.Description).DbEqual(false, c => c.Nullable); + databaseMapping.Assert(c => c.Description).DbEqual("Description", c => c.Name); + databaseMapping.Assert(e => e.Description).DbEqual("Description1", c => c.Name); + } + + [Fact] + public void Can_have_configured_duplicate_column_and_by_convention_columns_are_uniquified_conflict() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().Property(e => e.Description).HasColumnName("Description"); + modelBuilder.Entity().Property(e => e.Description).HasColumnName("Description"); + + Assert.Throws(() => BuildMapping(modelBuilder)); + } + + [Fact] + public void Can_table_split_and_conflicting_columns_are_uniquified() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().ToTable("Product"); + modelBuilder.Entity().ToTable("Product"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Can_table_split_and_conflicting_columns_can_be_configured() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().ToTable("Product"); + modelBuilder.Entity().ToTable("Product"); + modelBuilder.Entity().Property(s => s.Name).HasColumnName("Unique"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(s => s.Name).DbEqual("Name", c => c.Name); + databaseMapping.Assert(s => s.Name).DbEqual("Unique", c => c.Name); + } + + [Fact] + public void Single_abstract_type_with_associations_throws_not_mappable_exception() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + Assert.Equal( + Strings.UnmappedAbstractType(typeof(SingleAbstract)), + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)).Message); + } + + [Fact] + public void Configured_decimal_key_gets_correct_facet_defaults() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey(d => d.Id); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(d => d.Id).FacetEqual((byte)18, f => f.Precision); + databaseMapping.Assert(d => d.Id).FacetEqual((byte)2, f => f.Scale); + } + + [Fact] + public void Decimal_key_with_custom_store_type_should_propagate_facets() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Property(p => p.Id).HasColumnType("money"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Throw_when_mapping_properties_expression_contains_assignments() + { + var modelBuilder = new DbModelBuilder(); + + Expression> propertiesExpression = so => new + { + Foo = so.LocationId + }; + + Assert.Equal( + Strings.InvalidComplexPropertiesExpression(propertiesExpression), + Assert.Throws( + () => + modelBuilder + .Entity() + .Map(emc => emc.Properties(propertiesExpression))) + .Message); + } + + [Fact] + public void Circular_delete_cascade_path_can_be_generated() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + Assert.Equal( + 3, + databaseMapping.Model + .AssociationTypes + .SelectMany(a => a.Members) + .Cast() + .Count(e => e.DeleteBehavior == OperationAction.Cascade)); + } + + [Fact] + public void Build_model_for_entity_splitting_difference_schemas() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + m => + { + m.Properties( + v1 => new + { + v1.VendorID, + v1.Name, + v1.PreferredVendorStatus, + v1.AccountNumber, + v1.ActiveFlag, + v1.CreditRating + }); + m.ToTable("Vendor", "vendors"); + }) + .Map( + m => + { + m.Properties( + v2 => new + { + v2.VendorID, + v2.ModifiedDate, + v2.PurchasingWebServiceURL + }); + m.ToTable("VendorDetails", "details"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "vendors")); + Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "details")); + } + + [Fact] + public void Build_model_for_mapping_to_duplicate_tables_different_schemas() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("tbl"); + modelBuilder.Entity().ToTable("tbl", "other"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "dbo")); + Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "other")); + + databaseMapping.Assert().DbEqual("tbl", t => t.Table); + databaseMapping.Assert().DbEqual("tbl", t => t.Table); + } + + [Fact] + public void Build_model_after_configuring_entity_set_name() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasEntitySetName("Foos"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.True(databaseMapping.Model.Containers.Single().EntitySets.Any(es => es.Name == "Foos")); + } + } + + namespace Fixtures + { + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + using System.ComponentModel.DataAnnotations.Schema; + + public class StockOrder + { + public int Id { get; set; } + public int LocationId { get; set; } + public Location Location { get; set; } + public ICollection Organizations { get; set; } + } + + public class Organization + { + public int Id { get; set; } + public int StockOrderId { get; set; } + public StockOrder StockOrder { get; set; } + public ICollection Locations { get; set; } + } + + public class Location + { + public int Id { get; set; } + public ICollection StockOrders { get; set; } + public int OrganizationId { get; set; } + public Organization Organization { get; set; } + } + + public class DecimalKey + { + public decimal Id { get; set; } + public ICollection DecimalDependents { get; set; } + } + + public class DecimalDependent + { + public int Id { get; set; } + public decimal DecimalKeyId { get; set; } + } + + public abstract class SingleAbstract + { + public int Id { get; set; } + public DecimalDependent Nav { get; set; } + } + + public class SplitProduct + { + public int Id { get; set; } + public string Name { get; set; } + + [Required] + public SplitProductDetail Detail { get; set; } + } + + public class SplitProductDetail + { + [ForeignKey("Product")] + public int Id { get; set; } + + public string Name { get; set; } + + [Required] + public SplitProduct Product { get; set; } + } + + public class EntityWithConfiguredDuplicateColumn + { + public int Id { get; set; } + public string Description { get; set; } + + [Column("Description")] + public string Details { get; set; } + } + + public class EntityWithDescBase + { + public int Id { get; set; } + } + + public class EntityWithDescA : EntityWithDescBase + { + public string Description { get; set; } + public ComplexWithDesc Complex { get; set; } + } + + public class EntityWithDescB : EntityWithDescBase + { + public string Description { get; set; } + public ComplexWithDesc Complex { get; set; } + } + + public class EntityWithDescC : EntityWithDescBase + { + public string Description { get; set; } + public ComplexWithDesc Complex { get; set; } + } + + public class ComplexWithDesc + { + [Required] + public string Description { get; set; } + } + + public class MaxLengthProperties + { + public string Id { get; set; } + public string Prop1 { get; set; } + public byte[] Prop2 { get; set; } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/CodeFirst/AssociationScenarioTests.cs b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/AssociationScenarioTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/CodeFirst/AssociationScenarioTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/CodeFirst/AssociationScenarioTests.cs index 57a4e45c..0a2ba077 100644 --- a/test/EntityFramework/FunctionalTests/CodeFirst/AssociationScenarioTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/AssociationScenarioTests.cs @@ -1,3529 +1,3529 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests -{ - using System; - using System.Collections.Generic; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; - using System.Data.Entity; - using System.Data.Entity.Core; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.ModelConfiguration; - using System.Data.Entity.ModelConfiguration.Conventions; - using System.Data.Entity.Utilities; - using System.Linq; - using FunctionalTests.Model; - using Xunit; - - public sealed class AssociationScenarioTests : TestBase - { - [Fact] - public void FK_attribute_with_inverse_property_should_create_fk_association() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - databaseMapping.Assert().HasForeignKey( - new[] { "DependentForeignKeyPropertyNotFromConvention1" }, "Principal_172949"); - } - - [Fact] - public void Required_on_dependent_nav_prop_with_foreign_key_attribute_on_fk() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey(e => e.DependentForeignKeyPropertyNotFromConvention1); - modelBuilder.Entity().HasKey(e => e.Key1); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var associationType = databaseMapping.Model.AssociationTypes.Single(); - - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, associationType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); - } - - [Fact] - public void Required_on_dependent_nav_prop_with_foreign_key_attribute_on_nav() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey(e => e.DependentForeignKeyPropertyNotFromConvention1); - modelBuilder.Entity().HasKey(e => e.Key1); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var associationType = databaseMapping.Model.AssociationTypes.Single(); - - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, associationType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); - } - - [Fact] - public void Required_on_principal_and_dependent_nav_prop_with_foreign_key_attribute_on_fk() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey(e => e.DependentForeignKeyPropertyNotFromConvention1); - modelBuilder.Entity().HasKey(e => e.Key1); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var associationType = databaseMapping.Model.AssociationTypes.Single(); - - Assert.Equal(RelationshipMultiplicity.One, associationType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); - } - - [Fact] - public void Should_not_detect_one_to_one_fk_that_is_not_the_dependent_pk() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().HasKey( - l => new - { - l.Key - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasForeignKey(new[] { "Order_Id" }, "Principal_181909"); - } - - [Fact] - public void Can_detect_overlapping_key_by_convention() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey( - o => new - { - o.OrderId, - o.CustomerId - }); - modelBuilder.Entity().HasKey( - l => new - { - l.OrderLineId, - l.CustomerId - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasForeignKey(new[] { "OrderId", "CustomerId" }, "Order_181909"); - } - - [Fact] - public void Can_detect_overlapping_key_by_convention_when_pk_covers_fk() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey( - o => new - { - o.OrderId, - o.CustomerId - }); - modelBuilder.Entity().HasKey( - l => new - { - l.OrderLineId, - l.CustomerId, - l.OrderId - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasForeignKey(new[] { "OrderId", "CustomerId" }, "Order_181909"); - } - - [Fact] - public void Can_detect_overlapping_key_by_convention_when_fk_covers_pk() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey( - o => new - { - o.OrderId, - o.CustomerId - }); - modelBuilder.Entity().HasKey( - l => new - { - l.OrderId - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasForeignKey(new[] { "OrderId", "CustomerId" }, "Order_181909"); - } - - [Fact] - public void Identifying_overlapping_key_is_not_discovered_by_convention() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey( - o => new - { - o.OrderId, - o.CustomerId - }); - modelBuilder.Entity().HasKey( - l => new - { - l.CustomerId, - l.OrderId - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasForeignKey( - new[] { "Order_OrderId", "Order_CustomerId" }, - "Order_181909"); - } - - [Fact] - public void Identifying_overlapping_key_is_not_discovered_by_convention_reverse_pk_ordering() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey( - o => new - { - o.OrderId, - o.CustomerId - }); - modelBuilder.Entity().HasKey( - l => new - { - l.OrderId, - l.CustomerId - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasForeignKey( - new[] { "Order_OrderId", "Order_CustomerId" }, - "Order_181909"); - } - - [Fact] - public void Can_map_ia_to_other_table_when_entity_splitting() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .Map( - mapping => - { - mapping.Properties(e => e.Key1); - mapping.ToTable("DependentSplit"); - }); - modelBuilder.Entity() - .Map( - mapping => - { - mapping.Properties(e => e.PrincipalNavigationKey1); - mapping.ToTable("Dependent_162348"); - }); - modelBuilder.Entity() - .HasOptional(e => e.PrincipalNavigation).WithMany().Map(m => m.ToTable("Dependent_162348")); - - modelBuilder.Entity().HasKey(e => e.Key1); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Configured_annotated_nullable_fk_should_be_non_nullable_when_association_end_required() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany( - e => e.DependentNavigation); - modelBuilder.Entity().HasKey(e => e.Key1); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(d => d.DependentForeignKeyPropertyNotFromConvention1).IsFalse(f => f.Nullable); - } - - [Fact] - public void Configured_required_end_should_result_in_required_dependent_keys_when_configured_identifying() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasOptional(p => p.DependentNavigation) - .WithRequired(d => d.PrincipalNavigation); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Configured_required_end_should_result_in_required_dependent_keys_by_convention() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasMany(p => p.DependentNavigation) - .WithRequired(d => d.PrincipalNavigation); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Configured_required_end_should_result_in_required_dependent_keys_when_configured() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasMany(p => p.DependentNavigation) - .WithRequired(d => d.PrincipalNavigation) - .HasForeignKey(d => d.PrincipalNavigationId); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Duplicate_table_name_resolution_when_many_to_many_mapping_should_not_uniquify_distinct() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasMany(e => e.Products) - .WithMany(e => e.Suppliers) - .Map(m => m.ToTable("SupplierManyToManyTableNaming")); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert("SupplierManyToManyTableNamings"); - databaseMapping.Assert("SupplierManyToManyTableNaming"); - } - - [Fact] - public void Duplicate_table_name_resolution_when_many_to_many_mapping_should_uniquify_collision() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasMany(e => e.Products) - .WithMany(e => e.Suppliers) - .Map(m => m.ToTable("SupplierManyToManyTableNamings")); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert("SupplierManyToManyTableNamings1"); - databaseMapping.Assert("SupplierManyToManyTableNamings"); - } - - [Fact] - public void Duplicate_table_name_resolution_when_many_to_many_mapping_should_throw_when_duplicate_configured() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .ToTable("Foo"); - modelBuilder.Entity() - .HasMany(e => e.Products) - .WithMany(e => e.Suppliers) - .Map(m => m.ToTable("Foo")); - - Assert.Throws(() => BuildMapping(modelBuilder)); - } - - [Fact] - public void Configure_partial_api_plus_annotation_optional_to_required_should_have_principal() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey(e => e.Key1); - modelBuilder.Entity().HasKey(e => e.PrincipalNavigationKey1); - modelBuilder.Entity().HasOptional(e => e.DependentNavigation); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasForeignKeyColumn("PrincipalNavigationKey1"); - } - - [Fact] - public void Should_be_able_to_mix_convention_and_configuration_when_multiple_associations() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(d => d.Principal1).WithMany(p => p.Dependents1); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - Assert.Equal(2, databaseMapping.Model.AssociationTypes.Count()); - } - - [Fact] - public void Configure_store_facets_for_many_to_many_self_ref() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey(e => e.Key1); - modelBuilder.Entity().Property(p => p.DerivedProperty1).HasColumnType("real"); - modelBuilder.Entity().Property(p => p.Key1).HasColumnType("numeric").HasPrecision( - 15, 5); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(d => d.Key1).DbEqual("numeric", c => c.TypeName); - } - - [Fact] - public void One_to_one_split_required_inverse_annotations_can_determine_principal() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey( - e => new - { - e.Key1, - e.Key2 - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Should_be_able_to_determine_column_order_when_annotations_on_abstract_type() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity() - .HasKey( - e => new - { - e.Key1, - e.Key2, - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void One_to_one_self_ref_with_inverse_annotation() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey(e => e.Key1); - modelBuilder.Entity().Property(p => p.DependentSelfRefInverseKey1).HasColumnType( - "smallint"); - modelBuilder.Entity().Property(p => p.DerivedProperty1).HasColumnType( - "nvarchar(max)").IsUnicode(); - modelBuilder.Entity().Property(p => p.Key1).HasColumnType("smallint"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Foreign_key_and_inverse_on_derived_abstract_class() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey(p => p.Key1); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void One_to_one_self_ref_with_foreign_key_on_key_properties() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasKey( - d => new - { - d.Key1, - d.DependentForeignKeyPropertyNotFromConvention1 - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert() - .HasNoForeignKeyColumns(); - } - - [Fact] - public void Test_fk_wierd_ordering() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasKey( - d => new - { - d.Id1, - d.Id2 - }); - - modelBuilder.Entity() - .HasKey( - d => new - { - d.Fk1, - d.Fk2 - }) - .HasRequired(d => d.PrincipalNavigation) - .WithOptional(); - - modelBuilder.Entity() - .HasKey( - d => new - { - d.Fk1, - d.Fk2 - }) - .HasRequired(d => d.PrincipalNavigation) - .WithOptional(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert() - .HasForeignKey(new[] { "Fk2", "Fk1" }, "PrincipalWeirdKeyOrders"); - databaseMapping.Assert() - .HasForeignKey(new[] { "Fk1", "Fk2" }, "PrincipalWeirdKeyOrders"); - } - - [Fact] - public void Foreign_key_annotation_on_pk_should_change_principal_end_kind_to_required_with_required_annotation_unidirectional() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey( - d => d.DependentForeignKeyPropertyNotFromConvention1); - modelBuilder.Entity().HasKey(d => d.Key1); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var associationType = databaseMapping.Model.AssociationTypes.Single(); - - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, associationType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); - databaseMapping.Assert() - .HasForeignKey(new[] { "DependentForeignKeyPropertyNotFromConvention1" }, "PrincipalNoPrincipalNavs"); - } - - [Fact] - public void Foreign_key_annotation_on_pk_should_change_principal_end_kind_required_to_optional_unidirectional() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey( - d => d.DependentForeignKeyPropertyNotFromConvention1); - modelBuilder.Entity().HasKey(d => d.Key1); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var associationType = databaseMapping.Model.AssociationTypes.Single(); - - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, associationType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); - - databaseMapping.Assert() - .HasForeignKey(new[] { "DependentForeignKeyPropertyNotFromConvention1" }, "PrincipalNoPrincipalNavs"); - } - - [Fact] - public void Foreign_key_annotation_on_pk_should_change_principal_end_kind_required_to_optional_bidirectional() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasKey( - d => - new - { - d.DependentForeignKeyPropertyNotFromConvention2, - d.DependentForeignKeyPropertyNotFromConvention1 - }); - modelBuilder.Entity().HasKey( - d => new - { - d.Key2, - d.Key1 - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var associationType = databaseMapping.Model.AssociationTypes.Single(); - - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, associationType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); - databaseMapping.Assert() - .HasForeignKey( - new[] - { - "DependentForeignKeyPropertyNotFromConvention2", - "DependentForeignKeyPropertyNotFromConvention1" - }, - "PrincipalPrincipalNavOptionals"); - } - - [Fact] - public void Foreign_key_annotation_on_pk_should_change_principal_end_kind_required_to_required_bidirectional() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey( - d => d.DependentForeignKeyPropertyNotFromConvention1); - modelBuilder.Entity().HasKey(d => d.Key1); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var associationType = databaseMapping.Model.AssociationTypes.Single(); - - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, associationType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); - databaseMapping.Assert() - .HasForeignKey( - new[] { "DependentForeignKeyPropertyNotFromConvention1" }, - "PrincipalPrincipalNavRequireds"); - } - - [Fact] - public void Foreign_key_annotation_on_pk_should_change_principal_end_kind_required_to_required_bidirectional_required_dependentn() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey( - d => d.DependentForeignKeyPropertyNotFromConvention1); - modelBuilder.Entity().HasKey(d => d.Key1); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var associationType = databaseMapping.Model.AssociationTypes.Single(); - - Assert.Equal(RelationshipMultiplicity.One, associationType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); - databaseMapping.Assert() - .HasForeignKey( - new[] { "DependentForeignKeyPropertyNotFromConvention1" }, - "PrincipalPrincipalNavRequiredDependents"); - } - - [Fact] - public void One_to_one_byte_key_inverse_and_fk_annotations() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey(p => p.Key1); - modelBuilder.Entity().HasKey(d => d.DependentForeignKeyPropertyNotFromConvention1); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Self_ref_inherited_should_not_cascade_on_delete() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal( - OperationAction.None, - databaseMapping.Model.AssociationTypes.Single().SourceEnd.DeleteBehavior); - - Assert.Equal( - OperationAction.None, - databaseMapping.Model.AssociationTypes.Single().TargetEnd.DeleteBehavior); - } - - [Fact] - public void Annotated_fk_composite_can_use_column_or_api_for_fk_ordering() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey( - p => new - { - p.Id2, - p.Id1 - }); - modelBuilder.Entity() - .Property(c => c.TheFk1).HasColumnOrder(2); - modelBuilder.Entity() - .Property(c => c.TheFk2).HasColumnOrder(1); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var fkConstraint - = databaseMapping.Database.EntityTypes - .Single(t => t.Name == "CompositeAnnotatedDependent") - .ForeignKeyBuilders - .Single(); - - Assert.True(new[] { "TheFk2", "TheFk1" }.SequenceEqual(fkConstraint.DependentColumns.Select(c => c.Name))); - - var tempQualifier1 = databaseMapping.Database; - DebugCheck.NotNull(tempQualifier1); - fkConstraint - = tempQualifier1.EntityTypes - .Single(t => t.Name == "CompositePartiallyAnnotatedDependent") - .ForeignKeyBuilders - .Single(); - - Assert.True(new[] { "TheFk2", "TheFk1" }.SequenceEqual(fkConstraint.DependentColumns.Select(c => c.Name))); - } - - [Fact] - public void Annotated_fk_composite_should_throw_when_no_ordering_defined() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey( - p => new - { - p.Id2, - p.Id1 - }); - modelBuilder.Entity(); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ForeignKeyAttributeConvention_OrderRequired", typeof(CompositePartiallyAnnotatedDependent)); - } - - [Fact] - public void Annotated_fk_one_to_one_should_use_annotation_to_determine_principal() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey(p => p.AnId); - modelBuilder.Entity().HasKey(ad => ad.AnotherId); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasForeignKeyColumn("AnotherId"); - } - - [Fact] - public void Annotated_fk_should_throw_when_invalid_nav_prop_specified() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage( - "ForeignKeyAttributeConvention_InvalidNavigationProperty", - "Id", typeof(AnnotatedDependentWrong), - "Wrong"); - } - - [Fact] - public void Generated_many_to_many_fk_columns_should_have_correct_store_type() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Property(p => p.Id).HasColumnType("bigint"); - modelBuilder.Entity().Property(t => t.Id).HasColumnType("bigint"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var table = databaseMapping.Database.EntityTypes.Single(t => t.Name == "TagProductA"); - - Assert.Equal("bigint", table.Properties.Single(c => c.Name == "Tag_Id").TypeName); - Assert.Equal("bigint", table.Properties.Single(c => c.Name == "ProductA_Id").TypeName); - } - - [Fact] - public void Generated_ia_fk_columns_should_have_correct_store_type() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasKey( - t => new - { - t.AnotherId1, - t.AnotherId2 - }) - .HasRequired(t => t.NavOne); - - modelBuilder - .Entity() - .HasKey(o => o.AnId) - .HasOptional(o => o.NavToOne); - modelBuilder - .Entity() - .Property(o => o.AnId) - .HasColumnType("bigint"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var table = databaseMapping.Database.EntityTypes.Single(t => t.Name == "ToOne"); - - Assert.Equal("bigint", table.Properties.Single(c => c.Name == "NavOne_AnId").TypeName); - } - - [Fact] - public void Generated_fk_columns_should_have_correct_store_type() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasOptional(si => si.Detail) - .WithRequired(sid => sid.Item); - - modelBuilder - .Entity() - .Property(si => si.SomeItemId) - .HasColumnType("bigint"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - databaseMapping.Assert(sid => sid.Id).DbEqual("bigint", c => c.TypeName); - } - - [Fact] - public void Generated_fk_columns_should_throw_with_misconfigured_store_type() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasOptional(si => si.Detail) - .WithRequired(sid => sid.Item); - modelBuilder - .Entity() - .Property(si => si.SomeItemId) - .HasColumnType("bigint"); - - modelBuilder - .Entity() - .Property(sid => sid.Id) - .HasColumnType("nvarchar"); - - Assert.Throws(() => BuildMapping(modelBuilder)); - } - - [Fact] - public void Unconfigured_fk_one_to_one_should_throw_with_unknown_principal() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnableToDeterminePrincipal", typeof(Dependent).ToString(), typeof(Principal).ToString()); - } - - [Fact] - public void Half_specified_one_to_one_relationships_should_throw_when_no_principal_specified() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasOptional(s => s.Detail); - modelBuilder - .Entity() - .HasOptional(d => d.Item); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnableToDeterminePrincipal", typeof(SomeItem).ToString(), typeof(SomeItemDetail).ToString()); - } - - [Fact] - public void Half_specified_one_to_one_relationships_should_not_throw_when_principal_specified() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasOptional(s => s.Detail); - modelBuilder - .Entity() - .HasRequired(d => d.Item); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); - } - - [Fact] - public void Half_specified_relationships_can_be_inversed_by_convention() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasMany(p => p.Tags); - modelBuilder - .Entity() - .HasMany(t => t.Products); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); - } - - [Fact] - public void Full_and_half_specified_relationships_can_be_inversed() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasMany(p => p.Tags) - .WithMany(t => t.Products); - modelBuilder - .Entity() - .HasMany(t => t.Products); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); - } - - [Fact] - public void Full_and_half_specified_relationships_can_be_uninversed() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasMany(p => p.Tags) - .WithMany(); - modelBuilder - .Entity() - .HasMany(t => t.Products); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(2, databaseMapping.Model.AssociationTypes.Count()); - } - - [Fact] - // Regression test for Dev11 Bug 98120 - public void Half_specified_optional_relationship_overrides_fully_specified_one() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(e => e.Detail).WithOptional(e => e.Item); - modelBuilder.Entity().HasOptional(e => e.Detail); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnableToDeterminePrincipal", typeof(SomeItem), typeof(SomeItemDetail)); - } - - [Fact] - // Regression test for Dev11 Bug 98118 - public void Half_specified_required_relationship_overrides_fully_specified_one() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(e => e.Detail).WithRequired(e => e.Item); - modelBuilder.Entity().HasRequired(e => e.Detail); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - var association = databaseMapping.Model.AssociationTypes.Single(); - Assert.Equal("SomeItem", association.SourceEnd.GetEntityType().Name); - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, association.SourceEnd.RelationshipMultiplicity); - Assert.Equal("SomeItem", association.Constraint.ToRole.GetEntityType().Name); - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, association.Constraint.ToRole.RelationshipMultiplicity); - } - - [Fact] - public void Half_specified_many_relationship_overrides_fully_specified_one() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().HasMany(s => s.Products).WithRequired(p => p.ProductSubcategory); - modelBuilder.Entity().HasMany(s => s.Products); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - databaseMapping.AssertValid(); - - var association = databaseMapping.Model.AssociationTypes.Single(); - Assert.Equal("ProductSubcategory", association.SourceEnd.GetEntityType().Name); - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, association.SourceEnd.RelationshipMultiplicity); - Assert.Equal("Product", association.Constraint.ToRole.GetEntityType().Name); - Assert.Equal(RelationshipMultiplicity.Many, association.Constraint.ToRole.RelationshipMultiplicity); - } - - [Fact] - public void Unconfigured_one_to_one_should_throw_with_unknown_principal() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey(o => o.AnId); - modelBuilder.Entity().HasKey( - o => new - { - o.AnotherId1, - o.AnotherId2 - }); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnableToDeterminePrincipal", typeof(ToOne), typeof(One)); - } - - [Fact] - public void Configured_one_to_one_should_make_ia_when_keys_incompatible() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasKey(o => o.AnId); - modelBuilder - .Entity() - .HasKey( - t => new - { - t.AnotherId1, - t.AnotherId2 - }) - .HasRequired(t => t.NavOne); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasForeignKeyColumn("NavOne_AnId"); - } - - [Fact] - // Regression test for Dev11 Bug 98118 - public void Self_ref_many_to_optional_should_find_FK() - { - var modelBuilder = new DbModelBuilder(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); - databaseMapping.Assert().HasForeignKeyColumn("ParentId"); - } - - [Fact] - public void Unconfigured_self_ref_one_to_one_should_throw_with_unknown_principal() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnableToDeterminePrincipal", typeof(SelfRefToOne), typeof(SelfRefToOne)); - } - - [Fact] - public void Self_ref_one_to_one_should_generate_ia_by_default() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(s => s.SelfOne); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasForeignKeyColumn("SelfOne_Id"); - } - - [Fact] - public void Build_model_for_ia_with_entity_splitting() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .Map( - c => - { - c.ToTable("SomeItemDetail"); - c.Properties(s => s.Id); - }) - .Map( - c => - { - c.ToTable("SplitTable"); - c.Properties(s => s.Id); - }); - - modelBuilder.Entity() - .HasOptional(s => s.Detail) - .WithRequired(sd => sd.Item) - .Map(c => c.ToTable("SplitTable")); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert("SplitTable").HasColumn("Item_SomeItemId"); - } - - [Fact] - public void Build_model_for_self_referencing_required_to_required_dependent_ia_with_configuration() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasRequired(s => s.Self) - .WithRequiredDependent() - .Map(c => c.MapKey("TheKey")); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.Assert().HasColumn("TheKey"); - } - - [Fact] - public void Build_model_for_self_referencing_required_to_required_principal_ia_with_configuration() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasRequired(s => s.Self) - .WithRequiredPrincipal() - .Map(c => c.MapKey("TheKey")); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasColumn("TheKey"); - } - - [Fact] - public void Build_model_for_self_referencing_optional_to_many_ia_with_configured_key_column() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasOptional(i => i.ParentItem) - .WithMany(i => i.ChildrenItems) - .Map(c => c.MapKey("ParentItemId")); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasColumn("ParentItemId"); - } - - [Fact] - public void Build_model_for_self_referencing_optional_to_many_ia_with_configured_composite_key_column() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasKey( - i => new - { - i.Id, - i.Name - }) - .HasOptional(i => i.ParentItem) - .WithMany(i => i.ChildrenItems) - .Map(c => c.MapKey("TheId", "TheName")); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasColumn("TheId"); - databaseMapping.Assert().HasColumn("TheName"); - } - - [Fact] - public void Build_model_for_self_referencing_configured_many_to_many() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasMany(p => p.Children) - .WithMany(p => p.Parents) - .Map( - m => - { - m.MapLeftKey("ParentId"); - m.MapRightKey("ChildId"); - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert("PersonPersons").HasColumns("ParentId", "ChildId"); - } - - [Fact] - public void Self_referencing_many_to_many_should_not_cascade_by_convention() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasMany(p => p.Children) - .WithMany(p => p.Parents); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var joinTable = databaseMapping.Database.EntityTypes.Single(t => t.Name == "PersonPerson"); - - Assert.Equal(2, joinTable.ForeignKeyBuilders.Count()); - - Assert.True(joinTable.ForeignKeyBuilders.All(fk => fk.DeleteAction == OperationAction.None)); - } - - [Fact] - public void Many_to_many_mapping_configuration_correct_ends_configured() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity() - .HasMany(p => p.Tags) - .WithMany(t => t.Products) - .Map( - mc => - { - mc.MapLeftKey("ProductId"); - mc.MapRightKey("TagId"); - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert("ProductATags").HasColumns("ProductId", "TagId"); - } - - [Fact] - public void Many_to_many_mapping_configuration_correct_ends_configured_several_times_last_wins() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity() - .HasMany(p => p.Tags) - .WithMany(t => t.Products) - .Map( - mc => - { - mc.MapLeftKey("BadId"); - mc.MapRightKey("BadId"); - mc.MapLeftKey("ProductId"); - mc.MapRightKey("TagId"); - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert("ProductATags").HasColumns("ProductId", "TagId"); - } - - [Fact] - public void Many_to_many_should_generate_cascading_fks_by_convention() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity() - .HasMany(p => p.Tags) - .WithMany(t => t.Products) - .Map( - mc => - { - mc.MapLeftKey("ProductId"); - mc.MapRightKey("TagId"); - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var joinTable = databaseMapping.Database.EntityTypes.Single(t => t.Name == "ProductATag"); - - Assert.Equal(2, joinTable.ForeignKeyBuilders.Count()); - - Assert.True(joinTable.ForeignKeyBuilders.All(fk => fk.DeleteAction == OperationAction.Cascade)); - } - - [Fact] - public void Many_to_many_mapping_configuration_correct_ends_configured_reverse() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity() - .HasMany(t => t.Products) - .WithMany(p => p.Tags) - .Map( - mc => - { - mc.MapLeftKey("TagId"); - mc.MapRightKey("ProductId"); - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert("TagProductAs").HasColumns("TagId", "ProductId"); - } - - [Fact] - public void Many_to_many_mapping_configuration_repeated_key_throws() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity() - .HasMany(p => p.Tags) - .WithMany(t => t.Products) - .Map( - mc => - { - mc.MapLeftKey("ProductId"); - mc.MapRightKey("ProductId"); - }); - - Assert.Throws(() => BuildMapping(modelBuilder)); - } - - [Fact] - public void Build_model_for_many_to_many_association_with_conflicting_table_name_in_different_schema() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity() - .HasMany(s => s.SalesReasons) - .WithMany(r => r.SalesOrderHeaders) - .Map(m => m.ToTable("Products", "schema")); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping - .Assert("Products", "schema") - .HasColumns("SalesOrderHeader_SalesOrderID", "SalesReason_SalesReasonID"); - } - - [Fact] - public void Build_model_for_circular_associations_with_fk_discovery() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasMany(a => a.Photos) - .WithRequired(p => p.Album); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(2, databaseMapping.Model.Containers.Single().AssociationSets.Count()); - var tempQualifier1 = databaseMapping.Database; - DebugCheck.NotNull(tempQualifier1); - Assert.Equal(2, tempQualifier1.EntityTypes.ElementAt(0).Properties.Count()); - - Assert.Equal(2, databaseMapping.Database.EntityTypes.ElementAt(1).Properties.Count()); - } - - [Fact] - public void Invalid_number_of_foreign_keys_specified_should_throw() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity() - .HasRequired(s => s.ProductCategory) - .WithMany(c => c.ProductSubcategories) - .HasForeignKey( - s => new - { - s.ProductCategoryID, - s.Name - }); - - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Configuring_nonnavigation_property_should_throw() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.ComplexType().Ignore(d => d.Item); - modelBuilder.Entity().HasRequired(e => e.Detail).WithMany(); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("NavigationPropertyNotFound", "Detail", "SomeItem"); - } - - [Fact] - public void Configuring_nonmapped_property_should_throw() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Ignore(e => e.Detail); - modelBuilder.Entity().HasRequired(e => e.Detail).WithMany(); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("NavigationPropertyNotFound", "Detail", "SomeItem"); - } - - [Fact] - public void Build_model_for_a_simple_one_to_many_association() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Discover_inverse_navigation_properties_using_annotation() - { - var modelBuilder = new AdventureWorksModelBuilder(); - modelBuilder.Conventions.Remove(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); - } - - [Fact] - public void Discover_foreign_key_properties_using_annotation() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.NotNull(databaseMapping.Model.AssociationTypes.Single().Constraint); - } - - [Fact] - public void Build_model_for_a_simple_one_to_many_association_cascading_delete() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_a_simple_self_referencing_association() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_simple_optional_to_many_independent_association() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_simple_required_to_many_independent_association() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasRequired(b => b.Product).WithMany(p => p.BillOfMaterials); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_simple_many_to_many_association() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_many_to_many_association_with_mapping_configuration() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .HasMany(s => s.SalesReasons) - .WithMany(r => r.SalesOrderHeaders) - .Map( - m => m.ToTable("MappingTable") - .MapLeftKey("TheOrder") - .MapRightKey("TheReason")); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert("MappingTable").HasColumns("TheOrder", "TheReason"); - databaseMapping.Assert("MappingTable").HasForeignKey(new[] { "TheOrder" }, "SalesOrderHeaders"); - databaseMapping.Assert("MappingTable").HasForeignKey(new[] { "TheReason" }, "SalesReasons"); - } - - [Fact] - public void Build_model_for_many_to_many_association_with_conflicting_table_name() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity() - .HasMany(s => s.SalesReasons) - .WithMany(r => r.SalesOrderHeaders) - .Map(m => m.ToTable("Products")); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert("Products").HasColumns("SalesOrderHeader_SalesOrderID", "SalesReason_SalesReasonID"); - } - - [Fact] - public void Build_model_for_simple_optional_to_required_bidirectional_association() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity() - .HasKey(cd => cd.CustomerID) - .HasRequired(cd => cd.Customer); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_simple_optional_to_required_unidirectional_association() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .HasOptional(c => c.CustomerDiscount) - .WithRequired(); - - modelBuilder.Entity() - .HasKey(cd => cd.CustomerID) - .Ignore(cd => cd.Customer); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_self_referencing_many_to_many_association() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.Database.EntityTypes.Count()); - } - - [Fact] - public void Inverse_navigation_property_from_base_should_throw() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity() - .HasRequired(d => d.DerivedPrincipalNavigation) - .WithRequiredDependent(p => p.DerivedDependentNavigation); - - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Configure_unidirectional_association_with_navigation_property_from_unmapped_base() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(d => d.PrincipalNavigation).WithRequiredDependent(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void FK_from_base_should_throw() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Ignore(); - modelBuilder.Entity().Ignore(d => d.PrincipalNavigation); - modelBuilder.Entity() - .HasRequired(d => d.DerivedPrincipalNavigation) - .WithMany(p => p.DerivedDependentNavigations) - .HasForeignKey(d => d.PrincipalNavigationId); - - Assert.Throws( - () => - modelBuilder.BuildAndValidate( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ForeignKeyPropertyNotFound", "PrincipalNavigationId", "DerivedDependent"); - } - - [Fact] - public void PK_as_FK_with_many_to_one_should_throw() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Ignore(); - modelBuilder.Entity() - .HasRequired(d => d.DerivedPrincipalNavigation) - .WithMany(p => p.DerivedDependentNavigations) - .HasForeignKey(d => d.Id); - - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Map_FK_From_Principal_Side_And_Table_Split_FK_Into_First_Table() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .HasKey(p => p.ProductID); - - modelBuilder.Entity() - .Ignore(p => p.SpecialOffer); - - modelBuilder.Entity() - .HasMany(o => o.SpecialOfferProducts) - .WithRequired() - .HasForeignKey(p => p.SpecialOfferID); - - modelBuilder.Entity() - .Map( - m => - { - m.Properties( - p => - new - { - p.ProductID, - p.rowguid, - p.SpecialOfferID // FK in table 1 - }); - m.ToTable("ProductOne"); - }) - .Map( - m => - { - m.Properties( - p => - new - { - p.ProductID, - p.ModifiedDate, - }); - m.ToTable("ProductTwo"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(3, databaseMapping.Database.EntityTypes.Count()); - - databaseMapping.Assert("ProductOne") - .HasColumns("ProductID", "SpecialOfferID", "rowguid") - .HasForeignKeyColumn("SpecialOfferID"); - - databaseMapping.Assert("ProductTwo") - .HasColumns("ProductID", "ModifiedDate") - .HasNoForeignKeyColumn("SpecialOfferID"); - } - - [Fact] - public void Map_FK_From_Principal_Side_And_Table_Split_FK_Into_Second_Table() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .HasKey(p => p.ProductID); - - modelBuilder.Entity() - .Ignore(p => p.SpecialOffer); - - modelBuilder.Entity() - .HasMany(o => o.SpecialOfferProducts) - .WithRequired() - .HasForeignKey(p => p.SpecialOfferID); - - modelBuilder.Entity() - .Map( - m => - { - m.Properties( - p => - new - { - p.ProductID, - p.rowguid - }); - m.ToTable("ProductOne"); - }) - .Map( - m => - { - m.Properties( - p => - new - { - p.ProductID, - p.ModifiedDate, - p.SpecialOfferID // FK in table 2 - }); - m.ToTable("ProductTwo"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(3, databaseMapping.Database.EntityTypes.Count()); - - databaseMapping.Assert("ProductOne") - .HasColumns("ProductID", "rowguid") - .HasNoForeignKeyColumn("SpecialOfferID"); - - databaseMapping.Assert("ProductTwo") - .HasColumns("ProductID", "SpecialOfferID", "ModifiedDate") - .HasForeignKeyColumn("SpecialOfferID"); - } - - [Fact] - // DevDiv2 165131 - public void Map_IA_to_Pluralized_Table() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasKey(e => e.CustomerID); - modelBuilder.Entity() - .HasKey(e => e.CustomerID) - .HasRequired(cd => cd.Customer) - .WithRequiredPrincipal(c => c.CustomerDiscount) - .Map(m => m.ToTable("Customers")); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Customers"); - databaseMapping.Assert().HasForeignKeyColumn("CustomerDiscount_CustomerID"); - } - - [Fact] - public void Map_IA_To_First_Split_Table() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .HasKey(p => p.ProductID) - .Map( - m => - { - m.Properties( - p => - new - { - p.ProductID, - p.rowguid - }); - m.ToTable("ProductOne"); - }) - .Map( - m => - { - m.Properties( - p => - new - { - p.ProductID, - p.ModifiedDate, - p.SpecialOfferID - }); - m.ToTable("ProductTwo"); - }); - - modelBuilder.Entity() - .HasKey(o => o.SpecialOfferID) - .HasMany(o => o.SpecialOfferProducts) - .WithRequired(p => p.SpecialOffer) - .Map(mc => mc.MapKey("TheFK")); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(3, databaseMapping.Database.EntityTypes.Count()); - - databaseMapping.Assert("ProductOne") - .HasColumns("ProductID", "rowguid", "TheFK") - .HasForeignKeyColumn("TheFK"); - databaseMapping.Assert("ProductTwo") - .HasColumns("ProductID", "SpecialOfferID", "ModifiedDate") - .HasNoForeignKeyColumn("TheFK"); - } - - [Fact] - public void Map_IA_Column_Names() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .HasKey(p => p.ProductID); - - modelBuilder.Entity() - .HasKey(o => o.SpecialOfferID) - .HasMany(o => o.SpecialOfferProducts) - .WithRequired(p => p.SpecialOffer) - .Map(mc => mc.MapKey("TheFK")); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.Database.EntityTypes.Count()); - - databaseMapping.Assert() - .HasColumns("ProductID", "SpecialOfferID", "rowguid", "ModifiedDate", "TheFK") - .HasForeignKeyColumn("TheFK"); - } - - [Fact] - public void Map_IA_column_names_several_times_last_wins() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .HasKey(p => p.ProductID); - - modelBuilder.Entity() - .HasKey(o => o.SpecialOfferID) - .HasMany(o => o.SpecialOfferProducts) - .WithRequired(p => p.SpecialOffer) - .Map( - mc => - { - mc.MapKey("BadFK"); - mc.ToTable("BadTable"); - mc.MapKey("TheFK"); - mc.ToTable("SpecialOfferProducts"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.Database.EntityTypes.Count()); - - databaseMapping.Assert() - .HasColumns("ProductID", "SpecialOfferID", "rowguid", "ModifiedDate", "TheFK") - .HasForeignKeyColumn("TheFK"); - } - - [Fact] - public void Mapping_IA_column_name_to_existing_one_throws() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .HasKey(p => p.ProductID); - - modelBuilder.Entity() - .HasKey(o => o.SpecialOfferID) - .HasMany(o => o.SpecialOfferProducts) - .WithRequired(p => p.SpecialOffer) - .Map(mc => mc.MapKey("SpecialOfferID")); - - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Can_turn_cascade_delete_off_for_IA_association() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Ignore(d => d.CDPrinId); - modelBuilder.Entity().HasMany(p => p.CDDeps).WithRequired(d => d.CDPrin).WillCascadeOnDelete(false); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var associationSet = databaseMapping.Model.Containers.Single().AssociationSets[0]; - - Assert.Equal(OperationAction.None, associationSet.ElementType.SourceEnd.DeleteBehavior); - Assert.Equal(OperationAction.None, associationSet.ElementType.TargetEnd.DeleteBehavior); - } - - [Fact] - public void Can_turn_cascade_delete_on_for_IA_association() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().Ignore(d => d.CDPrinId); - modelBuilder.Entity().HasMany(p => p.CDDeps).WithRequired(d => d.CDPrin).WillCascadeOnDelete(true); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; - Assert.Equal(OperationAction.Cascade, aset.ElementType.SourceEnd.DeleteBehavior); - Assert.Equal(OperationAction.None, aset.ElementType.TargetEnd.DeleteBehavior); - } - - [Fact] - public void Can_turn_cascade_delete_off_for_non_nullable_FK_association() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasMany(p => p.CDDeps).WithRequired(d => d.CDPrin).HasForeignKey( - d => d.CDPrinId).WillCascadeOnDelete(false); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; - Assert.Equal(OperationAction.None, aset.ElementType.SourceEnd.DeleteBehavior); - Assert.Equal(OperationAction.None, aset.ElementType.TargetEnd.DeleteBehavior); - } - - [Fact] - public void Can_turn_cascade_delete_on_for_non_nullable_FK_association() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().HasMany(p => p.CDDeps).WithRequired(d => d.CDPrin).HasForeignKey( - d => d.CDPrinId).WillCascadeOnDelete(true); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; - Assert.Equal(OperationAction.Cascade, aset.ElementType.SourceEnd.DeleteBehavior); - Assert.Equal(OperationAction.None, aset.ElementType.TargetEnd.DeleteBehavior); - } - - [Fact] - public void Can_set_optional_to_optional_dependent_relationships_and_you_get_an_IA() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(p => p.Item).WithOptionalDependent(p => p.Detail); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; - Assert.Null(aset.ElementType.Constraint); - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.TargetEnd.RelationshipMultiplicity); - databaseMapping.Assert().HasForeignKeyColumn("Item_SomeItemId"); // IA FK - Assert.Equal(1, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); - } - - [Fact] - public void Default_ia_fk_column_names_should_incorporate_nav_prop_on_dependent() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasOptional(s => s.Detail) - .WithRequired(d => d.Item) - .Map(_ => { }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasForeignKeyColumn("Item_SomeItemId"); - } - - [Fact] - public void Can_set_optional_to_optional_principal_relationships_and_you_get_an_IA() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(d => d.Detail).WithOptionalPrincipal(p => p.Item); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; - Assert.Null(aset.ElementType.Constraint); - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.TargetEnd.RelationshipMultiplicity); - databaseMapping.Assert().HasForeignKeyColumn("Item_SomeItemId"); // IA FK - Assert.Equal(1, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); - } - - [Fact] - public void Can_set_required_to_required_dependent_relationships_and_you_get_an_FK() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(p => p.Item).WithRequiredDependent(p => p.Detail); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; - Assert.NotNull(aset.ElementType.Constraint); - Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.TargetEnd.RelationshipMultiplicity); - databaseMapping.Assert().HasForeignKeyColumn("Id"); // FK - Assert.Equal(0, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); - } - - [Fact] - public void Can_set_required_to_required_principal_relationships_and_you_get_an_FK() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(d => d.Detail).WithRequiredPrincipal(p => p.Item); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; - Assert.NotNull(aset.ElementType.Constraint); - Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.TargetEnd.RelationshipMultiplicity); - databaseMapping.Assert().HasForeignKeyColumn("Id"); // FK - Assert.Equal(0, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); - } - - [Fact] - public void Can_set_required_to_optional_relationship_and_you_get_an_FK_with_correct_dependent_end() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(d => d.Item).WithOptional(p => p.Detail); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; - Assert.NotNull(aset.ElementType.Constraint); - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.TargetEnd.RelationshipMultiplicity); - databaseMapping.Assert().HasForeignKeyColumn("Id"); // FK - Assert.Equal(0, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); - } - - [Fact] - public void Can_set_optional_to_required_relationship_and_you_get_an_FK_with_correct_dependent_end() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(d => d.Detail).WithRequired(p => p.Item); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; - Assert.NotNull(aset.ElementType.Constraint); - Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.TargetEnd.RelationshipMultiplicity); - databaseMapping.Assert().HasForeignKeyColumn("Id"); // FK - Assert.Equal(0, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); - } - - [Fact] - public void Ignore_FK_property_and_you_get_an_IA() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasMany(p => p.CDDeps).WithRequired(d => d.CDPrin); - modelBuilder.Entity().Ignore(d => d.CDPrinId); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; - Assert.Null(aset.ElementType.Constraint); - Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.Many, aset.ElementType.TargetEnd.RelationshipMultiplicity); - databaseMapping.Assert().HasForeignKeyColumn("CDPrin_CDPrinId"); // AI FK - Assert.Equal(1, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); - } - - #region Configuration from both sides tests - - [Fact] - public void Redundant_many_to_many_mapping_configuration_with_left_and_right_keys_switched_should_not_throw() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasMany(p => p.Tags) - .WithMany(t => t.Products) - .Map( - mc => - { - mc.MapLeftKey("ProductId"); - mc.MapRightKey("TagId"); - mc.ToTable("ProductTags"); - }); - - modelBuilder.Entity() - .HasMany(t => t.Products) - .WithMany(p => p.Tags) - .Map( - mc => - { - mc.MapLeftKey("TagId"); - mc.MapRightKey("ProductId"); - mc.ToTable("ProductTags"); - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Redundant_many_to_many_mapping_configuration_should_not_throw() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasMany(p => p.Tags) - .WithMany(t => t.Products) - .Map( - mc => - { - mc.MapLeftKey("TagId"); - mc.MapRightKey("ProductId"); - mc.ToTable("ProductTags"); - }); - - modelBuilder.Entity() - .HasMany(t => t.Products) - .WithMany(p => p.Tags) - .Map( - mc => - { - mc.MapLeftKey("TagId"); - mc.MapRightKey("ProductId"); - mc.ToTable("ProductTags"); - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Inconsistent_redundant_many_to_many_mapping_configuration_should_throw() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasMany(p => p.Tags) - .WithMany(t => t.Products) - .Map( - mc => - { - mc.MapLeftKey("ProductCode"); - mc.MapRightKey("TagId"); - mc.ToTable("ProductTags"); - }); - - modelBuilder.Entity() - .HasMany(t => t.Products) - .WithMany(p => p.Tags) - .Map( - mc => - { - mc.MapLeftKey("TagId"); - mc.MapRightKey("ProductId"); - mc.ToTable("ProductTags"); - }); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ConflictingMapping", "Products", "FunctionalTests.Tag"); - } - - [Fact] - public void Conflicting_multiplicity_throws_optional_to_one_and_one_to_one_dependent() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(d => d.Detail).WithRequired(p => p.Item); - modelBuilder.Entity().HasRequired(d => d.Item).WithRequiredDependent(p => p.Detail); - - Assert.Throws( - () => - modelBuilder.Build( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ConflictingMultiplicities", "Detail", "FunctionalTests.SomeItem"); - } - - [Fact] - public void Conflicting_multiplicity_throws_optional_to_one_and_one_to_one_principal() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(d => d.Detail).WithRequired(p => p.Item); - modelBuilder.Entity().HasRequired(d => d.Item).WithRequiredPrincipal(p => p.Detail); - - Assert.Throws( - () => - modelBuilder.Build( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ConflictingMultiplicities", "Detail", "FunctionalTests.SomeItem"); - } - - [Fact] - public void Conflicting_multiplicity_throws_optional_to_one_and_optional_to_one() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(d => d.Detail).WithRequired(p => p.Item); - modelBuilder.Entity().HasOptional(d => d.Item).WithRequired(p => p.Detail); - - Assert.Throws( - () => - modelBuilder.Build( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ConflictingMultiplicities", "Item", "FunctionalTests.SomeItemDetail"); - } - - [Fact] - public void Conflicting_multiplicity_throws_optional_to_one_and_optional_to_optional_dependent() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(d => d.Detail).WithRequired(p => p.Item); - modelBuilder.Entity().HasOptional(d => d.Item).WithOptionalDependent(p => p.Detail); - - Assert.Throws( - () => - modelBuilder.Build( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ConflictingMultiplicities", "Item", "FunctionalTests.SomeItemDetail"); - } - - [Fact] - public void Conflicting_multiplicity_throws_optional_to_one_and_optional_to_optional_principal() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(d => d.Detail).WithRequired(p => p.Item); - modelBuilder.Entity().HasOptional(d => d.Item).WithOptionalPrincipal(p => p.Detail); - - Assert.Throws( - () => - modelBuilder.Build( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ConflictingMultiplicities", "Item", "FunctionalTests.SomeItemDetail"); - } - - [Fact] - public void Conflicting_multiplicity_throws_optional_to_optional_principal_and_optional_to_optional_principal() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(d => d.Detail).WithOptionalPrincipal(p => p.Item); - modelBuilder.Entity().HasOptional(d => d.Item).WithOptionalPrincipal(p => p.Detail); - - Assert.Throws( - () => - modelBuilder.Build( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ConflictingConstraint", "Item", "FunctionalTests.SomeItemDetail"); - } - - [Fact] - public void Conflicting_multiplicity_throws_optional_to_optional_dependent_and_optional_to_optional_dependent() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(d => d.Detail).WithOptionalDependent(p => p.Item); - modelBuilder.Entity().HasOptional(d => d.Item).WithOptionalDependent(p => p.Detail); - - Assert.Throws( - () => - modelBuilder.Build( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ConflictingConstraint", "Item", "FunctionalTests.SomeItemDetail"); - } - - [Fact] - public void Conflicting_multiplicity_throws_optional_to_optional_dependent_and_one_to_one_dependent() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(d => d.Detail).WithOptionalDependent(p => p.Item); - modelBuilder.Entity().HasRequired(d => d.Item).WithRequiredDependent(p => p.Detail); - - Assert.Throws( - () => - modelBuilder.Build( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ConflictingMultiplicities", "Item", "FunctionalTests.SomeItemDetail"); - } - - [Fact] - public void Conflicting_multiplicity_throws_optional_to_optional_dependent_and_one_to_one_principal() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(d => d.Detail).WithOptionalDependent(p => p.Item); - modelBuilder.Entity().HasRequired(d => d.Item).WithRequiredPrincipal(p => p.Detail); - - Assert.Throws( - () => - modelBuilder.Build( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ConflictingMultiplicities", "Item", "FunctionalTests.SomeItemDetail"); - } - - [Fact] - public void Conflicting_multiplicity_throws_one_to_one_principal_and_one_to_one_principal() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(d => d.Detail).WithRequiredPrincipal(p => p.Item); - modelBuilder.Entity().HasRequired(d => d.Item).WithRequiredPrincipal(p => p.Detail); - - Assert.Throws( - () => - modelBuilder.Build( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ConflictingConstraint", "Item", "FunctionalTests.SomeItemDetail"); - } - - [Fact] - public void Conflicting_multiplicity_throws_one_to_one_dependent_and_one_to_one_dependent() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(d => d.Detail).WithRequiredDependent(p => p.Item); - modelBuilder.Entity().HasRequired(d => d.Item).WithRequiredDependent(p => p.Detail); - - Assert.Throws( - () => - modelBuilder.Build( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ConflictingConstraint", "Item", "FunctionalTests.SomeItemDetail"); - } - - [Fact] - public void Conflicting_multiplicity_throws_one_to_many_and_many_to_optional() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(s => s.ProductCategory).WithMany( - c => c.ProductSubcategories); - modelBuilder.Entity().HasMany(c => c.ProductSubcategories).WithOptional( - s => s.ProductCategory); - - Assert.Throws( - () => - modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)). - ValidateMessage("ConflictingMultiplicities", "ProductCategory", "FunctionalTests.Model.ProductSubcategory"); - } - - // Dev11 330745 - [Fact] - public void Using_invalid_mapping_from_two_ends_without_nav_prop_when_nav_prop_exists_should_throw_but_not_NullReferenceException() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasOptional(d => d.Detail) - .WithRequired(p => p.Item); - - modelBuilder - .Entity() - .HasRequired(d => d.Item) - .WithRequiredPrincipal(); // <- There is an inverse nav-prop, but pretending that there isn't. - - Assert.Throws( - () => - modelBuilder.Build( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ConflictingMultiplicities", "Item", "FunctionalTests.SomeItemDetail"); - } - - [Fact] - public void Redundant_optional_to_optional_configuration_should_not_throw() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(d => d.Detail).WithOptionalPrincipal(p => p.Item); - modelBuilder.Entity().HasOptional(d => d.Item).WithOptionalDependent(p => p.Detail); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; - Assert.Null(aset.ElementType.Constraint); - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.TargetEnd.RelationshipMultiplicity); - databaseMapping.Assert().HasForeignKeyColumn("Item_SomeItemId"); // IA FK - Assert.Equal(1, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); - } - - [Fact] - public void Redundant_one_to_one_configuration_should_not_throw() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(d => d.Detail).WithRequiredDependent(p => p.Item); - modelBuilder.Entity().HasRequired(d => d.Item).WithRequiredPrincipal(p => p.Detail); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; - Assert.NotNull(aset.ElementType.Constraint); - Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.SourceEnd.RelationshipMultiplicity); - Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.TargetEnd.RelationshipMultiplicity); - databaseMapping.Assert().HasForeignKeyColumn("SomeItemId"); // FK - Assert.Equal(0, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); - } - - [Fact] - public void Conflicting_cascade_delete_throws() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(d => d.Detail).WithRequired(p => p.Item).WillCascadeOnDelete( - true); - modelBuilder.Entity().HasRequired(d => d.Item).WithOptional(p => p.Detail). - WillCascadeOnDelete(false); - - Assert.Throws( - () => - modelBuilder.Build( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ConflictingCascadeDeleteOperation", "Item", "FunctionalTests.SomeItemDetail"); - } - - [Fact] - public void Conflicting_FK_throws() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(s => s.ProductCategory).WithMany( - c => c.ProductSubcategories).HasForeignKey(s => s.ProductCategoryID); - modelBuilder.Entity().HasMany(c => c.ProductSubcategories).WithRequired( - s => s.ProductCategory).HasForeignKey(s => s.ProductSubcategoryID); - - Assert.Throws( - () => - modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)). - ValidateMessage("ConflictingConstraint", "ProductSubcategories", "FunctionalTests.Model.ProductCategory"); - } - - [Fact] - public void Conflicting_FK_vs_IA_configuration_throws() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(s => s.ProductCategory).WithMany( - c => c.ProductSubcategories).HasForeignKey(c => c.ProductSubcategoryID); - modelBuilder.Entity().HasMany(c => c.ProductSubcategories).WithRequired( - s => s.ProductCategory).Map(_ => { }); - - Assert.Throws( - () => - modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)). - ValidateMessage("ConflictingConstraint", "ProductSubcategories", "FunctionalTests.Model.ProductCategory"); - } - - [Fact] - public void Conflicting_IA_column_name_configuration_throws() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(s => s.ProductCategory).WithMany( - c => c.ProductSubcategories).Map(c => c.MapKey("Key1")); - modelBuilder.Entity().HasMany(c => c.ProductSubcategories).WithRequired( - s => s.ProductCategory).Map(c => c.MapKey("Key2")); - - Assert.Throws( - () => - modelBuilder.Build( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ConflictingMapping", "ProductSubcategories", "FunctionalTests.Model.ProductCategory"); - } - - #endregion - - [Fact] - // Regression test for Dev11 Bug 8383 "Identity convention should not be applied when PK is an FK." - public void Setting_required_to_optional_relationship_gives_you_a_PK_FK_that_is_not_identity() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(d => d.Item).WithOptional(p => p.Detail); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert().HasForeignKeyColumn("Id"); - databaseMapping.Assert(d => d.Id) - .DbEqual(true, c => c.IsPrimaryKeyColumn) - .DbEqual(StoreGeneratedPattern.None, c => c.StoreGeneratedPattern); - } - - [Fact] - // Regression test for Dev11 Bug 8383 "Identity convention should not be applied when PK is an FK." - public void Setting_optional_to_required_relationship_gives_you_a_PK_FK_that_is_not_identity() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(p => p.Detail).WithRequired(d => d.Item); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert().HasForeignKeyColumn("Id"); - databaseMapping.Assert(d => d.Id) - .DbEqual(true, c => c.IsPrimaryKeyColumn) - .DbEqual(StoreGeneratedPattern.None, c => c.StoreGeneratedPattern); - } - - // Dev11 345384 - [Fact] - public void Identity_key_is_created_by_convention_when_table_splitting_is_specified_with_fluent_API() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().ToTable("SharedTable"); - modelBuilder.Entity().ToTable("SharedTable"); - modelBuilder.Entity().HasRequired(d => d.BackRef).WithRequiredPrincipal(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert(d => d.Id) - .DbEqual(true, c => c.IsPrimaryKeyColumn) - .DbEqual(StoreGeneratedPattern.Identity, c => c.StoreGeneratedPattern); - databaseMapping.Assert(d => d.Id) - .DbEqual(true, c => c.IsPrimaryKeyColumn) - .DbEqual(StoreGeneratedPattern.Identity, c => c.StoreGeneratedPattern); - } - - // Dev11 345384 - [Fact] - public void Identity_key_is_created_by_convention_when_table_splitting_is_specified_with_attributes() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(d => d.BackRef).WithRequiredPrincipal(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert(d => d.Id) - .DbEqual(true, c => c.IsPrimaryKeyColumn) - .DbEqual(StoreGeneratedPattern.Identity, c => c.StoreGeneratedPattern); - databaseMapping.Assert(d => d.Id) - .DbEqual(true, c => c.IsPrimaryKeyColumn) - .DbEqual(StoreGeneratedPattern.Identity, c => c.StoreGeneratedPattern); - } - - [Fact] - public void Setting_IA_FK_name_also_changes_condition_column_name() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasKey(e => e.Key1); - modelBuilder.Entity().Map(mapping => mapping.ToTable("Dependent")); - modelBuilder.Entity().HasOptional(e => e.PrincipalNavigation).WithMany( - e => e.DependentNavigation) - .Map(m => m.MapKey("IndependentColumn1")); - modelBuilder.Entity().Map(mapping => mapping.ToTable("BaseDependent")); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert() - .HasColumn("IndependentColumn1"); - Assert.Equal( - "IndependentColumn1", - databaseMapping.EntityContainerMappings[0].AssociationSetMappings.ElementAt(0).ColumnConditions.ElementAt(0).ColumnProperty - .Name); - } - - // Dev11 287430 - [Fact] - public void Data_annotations_should_not_be_applied_to_many_to_many_mapping_when_association_is_fully_configured_with_fluent_API() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - modelBuilder - .Entity() - .HasMany(m => m.Persons) - .WithMany(p => p.Roles) - .Map( - m => m.ToTable("person_role", "domain") - .MapLeftKey("role_identifier") - .MapRightKey("person_identifier")); - - var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); - var databaseMapping = model.DatabaseMapping; - - databaseMapping.AssertValid(); - databaseMapping.Assert("person_role", "domain").HasColumns("person_identifier", "role_identifier"); - databaseMapping.Assert("person_role", "domain").HasForeignKey(new[] { "role_identifier" }, "role"); - databaseMapping.Assert("person_role", "domain").HasForeignKey(new[] { "person_identifier" }, "person"); - } - - [Fact] - public void Bug_46199_Sequence_contains_more_than_one_element_exception_thrown_at_navigation_property_configuration() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasOptional(p => p.Mother).WithMany().Map(t => t.MapKey("MotherId")); - modelBuilder.Entity().HasOptional(p => p.Father).WithMany().Map(t => t.MapKey("FatherId")); - modelBuilder.Entity().HasOptional(p => p.Birth).WithOptionalDependent().Map(t => t.MapKey("BirthdayId")); - modelBuilder.Entity().HasOptional(p => p.Death).WithOptionalDependent().Map(t => t.MapKey("DeathdayId")); - modelBuilder.Entity().HasRequired(e => e.WeddingDay).WithOptional().Map(t => t.MapKey("WeddingDayId")); - modelBuilder.Entity().HasRequired(e => e.Wife).WithMany().Map(t => t.MapKey("WifeId")); - modelBuilder.Entity().HasRequired(e => e.Husband).WithMany().Map(t => t.MapKey("HusbandId")); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void ForeignKey_annotation_is_allowed_for_one_to_one_PK_to_PK_mapping_Dev11_437725() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasRequired(r => r.Detail) - .WithRequiredPrincipal(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasForeignKey( - new[] { "OneToOneResultId" }, "OneToOneResults"); - } - } - - #region Fixtures - - public class CDPrin - { - public int CDPrinId { get; set; } - public List CDDeps { get; set; } - } - - public class CDDep - { - public int Id { get; set; } - public int CDPrinId { get; set; } - public CDPrin CDPrin { get; set; } - } - - public class SomeItem - { - public int SomeItemId { get; set; } - public SomeItemDetail Detail { get; set; } - } - - public class SomeItemDetail - { - public int Id { get; set; } - public SomeItem Item { get; set; } - } - - public class Album - { - public int Id { get; set; } - public virtual Photo Thumbnail { get; set; } - public int? ThumbnailId { get; set; } - public virtual ICollection Photos { get; set; } - } - - public class Photo - { - public int Id { get; set; } - public int AlbumId { get; set; } - public virtual Album Album { get; set; } - } - - public class ProductA - { - public int Id { get; set; } - public string Name { get; set; } - public ICollection Tags { get; set; } - } - - public class Tag - { - public int Id { get; set; } - public string Name { get; set; } - public ICollection Products { get; set; } - } - - public class Item - { - public int Id { get; set; } - public int Name { get; set; } - public virtual Item ParentItem { get; set; } - public virtual ICollection ChildrenItems { get; set; } - } - - public class Person - { - public int Id { get; set; } - public ICollection Children { get; set; } - public ICollection Parents { get; set; } - } - - public class SelfRef - { - public int Id { get; set; } - public SelfRef Self { get; set; } - } - - public class TreeNode - { - public int Id { get; set; } - public int? ParentId { get; set; } - public TreeNode Parent { get; set; } - public ICollection Children { get; set; } - } - - public class One - { - public int AnId { get; set; } - public ToOne NavToOne { get; set; } - } - - public class ToOne - { - public string AnotherId1 { get; set; } - public string AnotherId2 { get; set; } - public One NavOne { get; set; } - } - - public class SelfRefToOne - { - public int Id { get; set; } - public SelfRefToOne SelfOne { get; set; } - public SelfRefToOne SelfTwo { get; set; } - } - - public class Principal - { - public int Id { get; set; } - public Dependent DependentNavigation { get; set; } - } - - public class Dependent - { - public int Id { get; set; } - public Principal PrincipalNavigation { get; set; } - } - - public class PrincipalWithAnnotatedDependent - { - public string AnId { get; set; } - public AnnotatedDependent Dependent { get; set; } - } - - public class AnnotatedDependent - { - [ForeignKey("Principal")] - public string AnotherId { get; set; } - - public PrincipalWithAnnotatedDependent Principal { get; set; } - } - - public class AnnotatedDependentWrong - { - [ForeignKey("Wrong")] - public string Id { get; set; } - - public PrincipalWithAnnotatedDependent Principal { get; set; } - } - - public class PrincipalWithCompositeAnnotatedDependent - { - public int Id1 { get; set; } - public string Id2 { get; set; } - public ICollection Dependents { get; set; } - public ICollection Dependents2 { get; set; } - } - - public class CompositeAnnotatedDependent - { - public int Id { get; set; } - - [ForeignKey("Principal")] - [Column(Order = 2)] - public int TheFk1 { get; set; } - - [ForeignKey("Principal")] - [Column(Order = 1)] - public string TheFk2 { get; set; } - - public PrincipalWithCompositeAnnotatedDependent Principal { get; set; } - } - - public class CompositePartiallyAnnotatedDependent - { - public int Id { get; set; } - - [ForeignKey("Principal")] - public int TheFk1 { get; set; } - - [ForeignKey("Principal")] - public string TheFk2 { get; set; } - - public PrincipalWithCompositeAnnotatedDependent Principal { get; set; } - } - - public class PrincipalBase - { - public int Id { get; set; } - public DerivedDependent DerivedDependentNavigation { get; set; } - } - - public class DerivedPrincipal : PrincipalBase - { - public ICollection DerivedDependentNavigations { get; set; } - } - - public class DependentBase - { - public int Id { get; set; } - public int PrincipalNavigationId { get; set; } - public PrincipalBase PrincipalNavigation { get; set; } - } - - public class DerivedDependent : DependentBase - { - public DerivedPrincipal DerivedPrincipalNavigation { get; set; } - } - - public class SelfRefInheritedBase - { - public string Id { get; set; } - - [Required] - public SelfRefInheritedDerived Derived { get; set; } - } - - public class SelfRefInheritedDerived : SelfRefInheritedBase - { - public ICollection Bases { get; set; } - } - - public class DependentNoPrincipalNavRequired - { - [ForeignKey("PrincipalNavigation")] - public Guid DependentForeignKeyPropertyNotFromConvention1 { get; set; } - - [Required] - public PrincipalNoPrincipalNav PrincipalNavigation { get; set; } - } - - public class DependentNoPrincipalNavOptional - { - [ForeignKey("PrincipalNavigation")] - public Guid DependentForeignKeyPropertyNotFromConvention1 { get; set; } - - public PrincipalNoPrincipalNav PrincipalNavigation { get; set; } - } - - public class PrincipalNoPrincipalNav - { - public Guid? Key1 { get; set; } - } - - public class DependentPrincipalNavOptional - { - [ForeignKey("PrincipalNavigation")] - public int DependentForeignKeyPropertyNotFromConvention1 { get; set; } - - [ForeignKey("PrincipalNavigation")] - public Guid DependentForeignKeyPropertyNotFromConvention2 { get; set; } - - public PrincipalPrincipalNavOptional PrincipalNavigation { get; set; } - } - - public class PrincipalPrincipalNavOptional - { - public int? Key1 { get; set; } - public Guid? Key2 { get; set; } - public DependentPrincipalNavOptional DependentNavigation { get; set; } - } - - public class DependentPrincipalNavRequired - { - [ForeignKey("PrincipalNavigation")] - public Guid DependentForeignKeyPropertyNotFromConvention1 { get; set; } - - [Required] - public PrincipalPrincipalNavRequired PrincipalNavigation { get; set; } - } - - public class PrincipalPrincipalNavRequired - { - public Guid? Key1 { get; set; } - public DependentPrincipalNavRequired DependentNavigation { get; set; } - } - - public class DependentPrincipalNavRequiredDependent - { - [ForeignKey("PrincipalNavigation")] - public Guid DependentForeignKeyPropertyNotFromConvention1 { get; set; } - - public PrincipalPrincipalNavRequiredDependent PrincipalNavigation { get; set; } - } - - public class PrincipalPrincipalNavRequiredDependent - { - public Guid? Key1 { get; set; } - - [Required] - public DependentPrincipalNavRequiredDependent DependentNavigation { get; set; } - } - - public class PrincipalByteKey - { - public byte[] Key1 { get; set; } - - [ForeignKey("DependentForeignKeyPropertyNotFromConvention1")] - public DependentByteKey DependentNavigation { get; set; } - } - - public class DependentByteKey - { - public byte[] DependentForeignKeyPropertyNotFromConvention1 { get; set; } - - [InverseProperty("DependentNavigation")] - [Required] - public PrincipalByteKey PrincipalNavigation { get; set; } - } - - public class DependentSelfRef - { - [ForeignKey("PrincipalNavigation")] - [Column(Order = 1)] - public DateTimeOffset Key1 { get; set; } - - [ForeignKey("PrincipalNavigation")] - [Column(Order = 2)] - public DateTimeOffset DependentForeignKeyPropertyNotFromConvention1 { get; set; } - - [Required] - public DerivedDependentSelfRef PrincipalNavigation { get; set; } - } - - public class DerivedDependentSelfRef : DependentSelfRef - { - public byte[] DerivedProperty1 { get; set; } - } - - public class DependentWeirdKeyOrder - { - public int Fk1 { get; set; } - public int Fk2 { get; set; } - - [ForeignKey("Fk2,Fk1")] - public PrincipalWeirdKeyOrder PrincipalNavigation { get; set; } - } - - public class DependentWeirdKeyOrder2 - { - public int Fk1 { get; set; } - public int Fk2 { get; set; } - - [ForeignKey("Fk1,Fk2")] - public PrincipalWeirdKeyOrder PrincipalNavigation { get; set; } - } - - public class PrincipalWeirdKeyOrder - { - public int Id1 { get; set; } - public int Id2 { get; set; } - } - - public class BaseDependentAbstractKeyOrder - { - public decimal BaseProperty { get; set; } - public int Id { get; set; } - } - - public abstract class DependentAbstractKeyOrder : BaseDependentAbstractKeyOrder - { - [ForeignKey("PrincipalNavigation")] - [Column(Order = 1)] - public decimal? DependentForeignKeyPropertyNotFromConvention1 { get; set; } - - [ForeignKey("PrincipalNavigation")] - [Column(Order = 2)] - public decimal? DependentForeignKeyPropertyNotFromConvention2 { get; set; } - - public PrincipalAbstractKeyOrder PrincipalNavigation { get; set; } - } - - public class BasePrincipalAbstractKeyOrder - { - public string BaseProperty { get; set; } - public decimal Key1 { get; set; } - public decimal Key2 { get; set; } - } - - public abstract class PrincipalAbstractKeyOrder : BasePrincipalAbstractKeyOrder - { - } - - public class DerivedPrincipalKeyOrder : PrincipalAbstractKeyOrder - { - } - - public class DerivedDependentKeyOrder : DependentAbstractKeyOrder - { - public byte DerivedProperty1 { get; set; } - } - - public abstract class DependentSelfRefInverse - { - public short Key1 { get; set; } - public short DependentSelfRefInverseKey1 { get; set; } - - public DependentSelfRefInverse DependentNavigation { get; set; } - - [InverseProperty("DependentNavigation")] - [Required] - public DependentSelfRefInverse PrincipalNavigation { get; set; } - } - - public class DerivedDependentSelfRefInverse : DependentSelfRefInverse - { - public string DerivedProperty1 { get; set; } - } - - public class BaseDependentFkAbstract - { - public DateTime? BaseProperty { get; set; } - public int Id { get; set; } - } - - public abstract class DependentFkAbstract : BaseDependentFkAbstract - { - public int? DependentForeignKeyPropertyNotFromConvention1 { get; set; } - - [InverseProperty("DependentNavigation")] - [ForeignKey("DependentForeignKeyPropertyNotFromConvention1")] - public PrincipalFkAbstract PrincipalNavigation { get; set; } - } - - public class DerivedDependentFkAbstract : DependentFkAbstract - { - public string DerivedProperty1 { get; set; } - } - - public class PrincipalFkAbstract - { - public int? Key1 { get; set; } - - [InverseProperty("PrincipalNavigation")] - public ICollection DependentNavigation { get; set; } - - public PrincipalFkAbstract() - { - DependentNavigation = new List(); - } - } - - public class DerivedPrincipalFkAbstract : PrincipalFkAbstract - { - public byte[] DerivedProperty1 { get; set; } - } - - public class Dependent144843 - { - public int Id { get; set; } - - public Principal144843 Principal1 { get; set; } - public int Principal1Id { get; set; } - } - - public class Principal144843 - { - public int Id { get; set; } - public ICollection Dependents1 { get; set; } - public Dependent144843 Dependent { get; set; } - } - - public abstract class DependentManyToManySelf - { - public decimal? Key1 { get; set; } - } - - public class DerivedDependentManyToManySelf : DependentManyToManySelf - { - public float DerivedProperty1 { get; set; } - } - - public class DependentSelfRefInverseRequired - { - public string Key1 { get; set; } - public string Key2 { get; set; } - - [InverseProperty("PrincipalNavigation")] - public DependentSelfRefInverseRequired DependentNavigation { get; set; } - - [Required] - public DependentSelfRefInverseRequired PrincipalNavigation { get; set; } - } - - public class Principal144934 - { - public string Key1 { get; set; } - - [InverseProperty("PrincipalNavigation")] - public Dependent144934 DependentNavigation { get; set; } - } - - public class Dependent144934 - { - public string PrincipalNavigationKey1 { get; set; } - - [Required] - public Principal144934 PrincipalNavigation { get; set; } - } - - public class ProductManyToManyTableNaming - { - public int Id { get; set; } - public string Name { get; set; } - public ICollection Suppliers { get; set; } - } - - public class SupplierManyToManyTableNaming - { - public int Id { get; set; } - public string Name { get; set; } - public ICollection Products { get; set; } - } - - public class DependentWithNullableFk - { - public int Id { get; set; } - public string PrincipalNavigationId { get; set; } - public PrincipalWithNullableFk PrincipalNavigation { get; set; } - } - - public class PrincipalWithNullableFk - { - public string Id { get; set; } - public ICollection DependentNavigation { get; set; } - } - - public class DependentWithNullableFkIdentifying - { - public int? Id { get; set; } - public PrincipalWithNullableFkIdentifying PrincipalNavigation { get; set; } - } - - public class PrincipalWithNullableFkIdentifying - { - public int? Id { get; set; } - public DependentWithNullableFkIdentifying DependentNavigation { get; set; } - } - - // Association from base to derived type - - public class Repro150565_Dependent : Repro150565_BaseDependent - { - public decimal? BaseDependentKey1 { get; set; } - public Repro150565_BaseDependent PrincipalNavigation { get; set; } - } - - public class Repro150565_BaseDependent - { - public Guid BaseProperty { get; set; } - public decimal? Key1 { get; set; } - public ICollection DependentNavigation { get; set; } - } - - public class Dependent_6927 - { - public string DependentForeignKeyPropertyNotFromConvention1 { get; set; } - public int Id { get; set; } - - [ForeignKey("DependentForeignKeyPropertyNotFromConvention1")] - public Principal_6927 PrincipalNavigation { get; set; } - } - - public class Principal_6927 - { - public string Key1 { get; set; } - public ICollection DependentNavigation { get; set; } - } - - public class Dependent_162348 - { - public short Key1 { get; set; } - public short? PrincipalNavigationKey1 { get; set; } - public Dependent_162348 PrincipalNavigation { get; set; } - } - - public class Order_181909 - { - public int OrderId { get; set; } - public int CustomerId { get; set; } - public virtual ICollection Lines { get; set; } - } - - public class OrderLine_181909 - { - public int OrderLineId { get; set; } - public int CustomerId { get; set; } - public int OrderId { get; set; } - public virtual Order_181909 Order { get; set; } - public string Description { get; set; } - public decimal Quantity { get; set; } - } - - public class Principal_181909 - { - public int Id { get; set; } - public virtual Dependent_181909 Order { get; set; } - } - - public class Dependent_181909 - { - public string Key { get; set; } - public int Principal_181909Id { get; set; } - - [Required] - public virtual Principal_181909 Order { get; set; } - } - - public class Principal_159001 - { - public int Key1 { get; set; } - } - - public class Dependent_159001a - { - [ForeignKey("PrincipalNavigation")] - public int DependentForeignKeyPropertyNotFromConvention1 { get; set; } - - [Required] - public Principal_159001 PrincipalNavigation { get; set; } - } - - public class Dependent_159001b - { - public int DependentForeignKeyPropertyNotFromConvention1 { get; set; } - - [Required] - [ForeignKey("DependentForeignKeyPropertyNotFromConvention1")] - public Principal_159001 PrincipalNavigation { get; set; } - } - - public class PrincipalWithNav_159001a - { - public int Key1 { get; set; } - - [Required] - public DependentWithNav_159001a DependentNavigation { get; set; } - } - - public class DependentWithNav_159001a - { - [ForeignKey("PrincipalNavigation")] - public int DependentForeignKeyPropertyNotFromConvention1 { get; set; } - - [Required] - public PrincipalWithNav_159001a PrincipalNavigation { get; set; } - } - - public class Dependent_172949 - { - public int Id { get; set; } - - [ForeignKey("PrincipalNavigation")] - public short DependentForeignKeyPropertyNotFromConvention1 { get; set; } - - public Principal_172949 PrincipalNavigation { get; set; } - } - - public class Principal_172949 - { - public short? Id { get; set; } - - [InverseProperty("PrincipalNavigation")] - public ICollection DependentNavigation { get; set; } - } - - public class TableSharing1 - { - public int Id { get; set; } - public int Name { get; set; } - } - - public class TableSharing2 - { - public int Id { get; set; } - public byte[] Picture { get; set; } - public TableSharing1 BackRef { get; set; } - } - - [Table("SharedTable")] - public class TableSharing1A - { - public int Id { get; set; } - public int Name { get; set; } - } - - [Table("SharedTable")] - public class TableSharing2A - { - public int Id { get; set; } - public byte[] Picture { get; set; } - public TableSharing1A BackRef { get; set; } - } - - public class OneToOneResult - { - public int OneToOneResultId { get; set; } - - [ForeignKey("OneToOneResultId")] - public virtual OneToOneResultDetail Detail { get; set; } - } - - public class OneToOneResultDetail - { - [Key] - public int OneToOneResultId { get; set; } - - public DateTime DataDate { get; set; } - } - - #endregion - - #region Model for Dev11 287430 - - [Table("person", Schema = "domain")] - public class Person287430 - { - [Key] - [Column("identifier", TypeName = "nvarchar")] - [StringLength(36, MinimumLength = 36)] - public string Identifier { get; private set; } - - [InverseProperty("Persons")] - public virtual ICollection Roles { get; set; } - } - - [Table("role", Schema = "domain")] - public class Role287430 - { - [Key] - [Column("identifier", TypeName = "nvarchar")] - [StringLength(36, MinimumLength = 36)] - public string Identifier { get; set; } - - [InverseProperty("Roles")] - public virtual ICollection Persons { get; set; } - } - - #endregion - - public class APerson - { - [Key] - public int Id { get; set; } - - [Required] - [DataType(DataType.Text)] - [Display(Name = "Full Name")] - public string Name { get; set; } - - [DataType(DataType.Text)] - [Display(Name = "Biography")] - public string Bio { get; set; } - - public Event Birth { get; set; } - public Event Death { get; set; } - - public APerson Mother { get; set; } - public APerson Father { get; set; } - - public GenderType Gender { get; set; } - } - - public class Event - { - [Key] - public int Id { get; set; } - - [Required] - [DataType(DataType.Date)] - public DateTime Date { get; set; } - - [DataType(DataType.Text)] - public string Location { get; set; } - } - - public enum GenderType - { - Male, - Female - } - - public class Marriage - { - [Key] - public int Id { get; set; } - - [Required] - public Person Husband { get; set; } - - [Required] - public Person Wife { get; set; } - - [Required] - public Event WeddingDay { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests +{ + using System; + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + using System.ComponentModel.DataAnnotations.Schema; + using System.Data.Entity; + using System.Data.Entity.Core; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.ModelConfiguration; + using System.Data.Entity.ModelConfiguration.Conventions; + using System.Data.Entity.Utilities; + using System.Linq; + using FunctionalTests.Model; + using Xunit; + + public sealed class AssociationScenarioTests : TestBase + { + [Fact] + public void FK_attribute_with_inverse_property_should_create_fk_association() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + databaseMapping.Assert().HasForeignKey( + new[] { "DependentForeignKeyPropertyNotFromConvention1" }, "Principal_172949"); + } + + [Fact] + public void Required_on_dependent_nav_prop_with_foreign_key_attribute_on_fk() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey(e => e.DependentForeignKeyPropertyNotFromConvention1); + modelBuilder.Entity().HasKey(e => e.Key1); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var associationType = databaseMapping.Model.AssociationTypes.Single(); + + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, associationType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); + } + + [Fact] + public void Required_on_dependent_nav_prop_with_foreign_key_attribute_on_nav() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey(e => e.DependentForeignKeyPropertyNotFromConvention1); + modelBuilder.Entity().HasKey(e => e.Key1); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var associationType = databaseMapping.Model.AssociationTypes.Single(); + + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, associationType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); + } + + [Fact] + public void Required_on_principal_and_dependent_nav_prop_with_foreign_key_attribute_on_fk() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey(e => e.DependentForeignKeyPropertyNotFromConvention1); + modelBuilder.Entity().HasKey(e => e.Key1); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var associationType = databaseMapping.Model.AssociationTypes.Single(); + + Assert.Equal(RelationshipMultiplicity.One, associationType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); + } + + [Fact] + public void Should_not_detect_one_to_one_fk_that_is_not_the_dependent_pk() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().HasKey( + l => new + { + l.Key + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasForeignKey(new[] { "Order_Id" }, "Principal_181909"); + } + + [Fact] + public void Can_detect_overlapping_key_by_convention() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey( + o => new + { + o.OrderId, + o.CustomerId + }); + modelBuilder.Entity().HasKey( + l => new + { + l.OrderLineId, + l.CustomerId + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasForeignKey(new[] { "OrderId", "CustomerId" }, "Order_181909"); + } + + [Fact] + public void Can_detect_overlapping_key_by_convention_when_pk_covers_fk() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey( + o => new + { + o.OrderId, + o.CustomerId + }); + modelBuilder.Entity().HasKey( + l => new + { + l.OrderLineId, + l.CustomerId, + l.OrderId + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasForeignKey(new[] { "OrderId", "CustomerId" }, "Order_181909"); + } + + [Fact] + public void Can_detect_overlapping_key_by_convention_when_fk_covers_pk() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey( + o => new + { + o.OrderId, + o.CustomerId + }); + modelBuilder.Entity().HasKey( + l => new + { + l.OrderId + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasForeignKey(new[] { "OrderId", "CustomerId" }, "Order_181909"); + } + + [Fact] + public void Identifying_overlapping_key_is_not_discovered_by_convention() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey( + o => new + { + o.OrderId, + o.CustomerId + }); + modelBuilder.Entity().HasKey( + l => new + { + l.CustomerId, + l.OrderId + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasForeignKey( + new[] { "Order_OrderId", "Order_CustomerId" }, + "Order_181909"); + } + + [Fact] + public void Identifying_overlapping_key_is_not_discovered_by_convention_reverse_pk_ordering() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey( + o => new + { + o.OrderId, + o.CustomerId + }); + modelBuilder.Entity().HasKey( + l => new + { + l.OrderId, + l.CustomerId + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasForeignKey( + new[] { "Order_OrderId", "Order_CustomerId" }, + "Order_181909"); + } + + [Fact] + public void Can_map_ia_to_other_table_when_entity_splitting() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .Map( + mapping => + { + mapping.Properties(e => e.Key1); + mapping.ToTable("DependentSplit"); + }); + modelBuilder.Entity() + .Map( + mapping => + { + mapping.Properties(e => e.PrincipalNavigationKey1); + mapping.ToTable("Dependent_162348"); + }); + modelBuilder.Entity() + .HasOptional(e => e.PrincipalNavigation).WithMany().Map(m => m.ToTable("Dependent_162348")); + + modelBuilder.Entity().HasKey(e => e.Key1); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Configured_annotated_nullable_fk_should_be_non_nullable_when_association_end_required() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany( + e => e.DependentNavigation); + modelBuilder.Entity().HasKey(e => e.Key1); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(d => d.DependentForeignKeyPropertyNotFromConvention1).IsFalse(f => f.Nullable); + } + + [Fact] + public void Configured_required_end_should_result_in_required_dependent_keys_when_configured_identifying() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasOptional(p => p.DependentNavigation) + .WithRequired(d => d.PrincipalNavigation); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Configured_required_end_should_result_in_required_dependent_keys_by_convention() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasMany(p => p.DependentNavigation) + .WithRequired(d => d.PrincipalNavigation); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Configured_required_end_should_result_in_required_dependent_keys_when_configured() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasMany(p => p.DependentNavigation) + .WithRequired(d => d.PrincipalNavigation) + .HasForeignKey(d => d.PrincipalNavigationId); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Duplicate_table_name_resolution_when_many_to_many_mapping_should_not_uniquify_distinct() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasMany(e => e.Products) + .WithMany(e => e.Suppliers) + .Map(m => m.ToTable("SupplierManyToManyTableNaming")); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert("SupplierManyToManyTableNamings"); + databaseMapping.Assert("SupplierManyToManyTableNaming"); + } + + [Fact] + public void Duplicate_table_name_resolution_when_many_to_many_mapping_should_uniquify_collision() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasMany(e => e.Products) + .WithMany(e => e.Suppliers) + .Map(m => m.ToTable("SupplierManyToManyTableNamings")); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert("SupplierManyToManyTableNamings1"); + databaseMapping.Assert("SupplierManyToManyTableNamings"); + } + + [Fact] + public void Duplicate_table_name_resolution_when_many_to_many_mapping_should_throw_when_duplicate_configured() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .ToTable("Foo"); + modelBuilder.Entity() + .HasMany(e => e.Products) + .WithMany(e => e.Suppliers) + .Map(m => m.ToTable("Foo")); + + Assert.Throws(() => BuildMapping(modelBuilder)); + } + + [Fact] + public void Configure_partial_api_plus_annotation_optional_to_required_should_have_principal() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey(e => e.Key1); + modelBuilder.Entity().HasKey(e => e.PrincipalNavigationKey1); + modelBuilder.Entity().HasOptional(e => e.DependentNavigation); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasForeignKeyColumn("PrincipalNavigationKey1"); + } + + [Fact] + public void Should_be_able_to_mix_convention_and_configuration_when_multiple_associations() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(d => d.Principal1).WithMany(p => p.Dependents1); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + Assert.Equal(2, databaseMapping.Model.AssociationTypes.Count()); + } + + [Fact] + public void Configure_store_facets_for_many_to_many_self_ref() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey(e => e.Key1); + modelBuilder.Entity().Property(p => p.DerivedProperty1).HasColumnType("real"); + modelBuilder.Entity().Property(p => p.Key1).HasColumnType("numeric").HasPrecision( + 15, 5); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(d => d.Key1).DbEqual("numeric", c => c.TypeName); + } + + [Fact] + public void One_to_one_split_required_inverse_annotations_can_determine_principal() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey( + e => new + { + e.Key1, + e.Key2 + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Should_be_able_to_determine_column_order_when_annotations_on_abstract_type() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity() + .HasKey( + e => new + { + e.Key1, + e.Key2, + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void One_to_one_self_ref_with_inverse_annotation() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey(e => e.Key1); + modelBuilder.Entity().Property(p => p.DependentSelfRefInverseKey1).HasColumnType( + "smallint"); + modelBuilder.Entity().Property(p => p.DerivedProperty1).HasColumnType( + "nvarchar(max)").IsUnicode(); + modelBuilder.Entity().Property(p => p.Key1).HasColumnType("smallint"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Foreign_key_and_inverse_on_derived_abstract_class() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey(p => p.Key1); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void One_to_one_self_ref_with_foreign_key_on_key_properties() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasKey( + d => new + { + d.Key1, + d.DependentForeignKeyPropertyNotFromConvention1 + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert() + .HasNoForeignKeyColumns(); + } + + [Fact] + public void Test_fk_wierd_ordering() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasKey( + d => new + { + d.Id1, + d.Id2 + }); + + modelBuilder.Entity() + .HasKey( + d => new + { + d.Fk1, + d.Fk2 + }) + .HasRequired(d => d.PrincipalNavigation) + .WithOptional(); + + modelBuilder.Entity() + .HasKey( + d => new + { + d.Fk1, + d.Fk2 + }) + .HasRequired(d => d.PrincipalNavigation) + .WithOptional(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert() + .HasForeignKey(new[] { "Fk2", "Fk1" }, "PrincipalWeirdKeyOrders"); + databaseMapping.Assert() + .HasForeignKey(new[] { "Fk1", "Fk2" }, "PrincipalWeirdKeyOrders"); + } + + [Fact] + public void Foreign_key_annotation_on_pk_should_change_principal_end_kind_to_required_with_required_annotation_unidirectional() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey( + d => d.DependentForeignKeyPropertyNotFromConvention1); + modelBuilder.Entity().HasKey(d => d.Key1); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var associationType = databaseMapping.Model.AssociationTypes.Single(); + + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, associationType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); + databaseMapping.Assert() + .HasForeignKey(new[] { "DependentForeignKeyPropertyNotFromConvention1" }, "PrincipalNoPrincipalNavs"); + } + + [Fact] + public void Foreign_key_annotation_on_pk_should_change_principal_end_kind_required_to_optional_unidirectional() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey( + d => d.DependentForeignKeyPropertyNotFromConvention1); + modelBuilder.Entity().HasKey(d => d.Key1); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var associationType = databaseMapping.Model.AssociationTypes.Single(); + + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, associationType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); + + databaseMapping.Assert() + .HasForeignKey(new[] { "DependentForeignKeyPropertyNotFromConvention1" }, "PrincipalNoPrincipalNavs"); + } + + [Fact] + public void Foreign_key_annotation_on_pk_should_change_principal_end_kind_required_to_optional_bidirectional() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasKey( + d => + new + { + d.DependentForeignKeyPropertyNotFromConvention2, + d.DependentForeignKeyPropertyNotFromConvention1 + }); + modelBuilder.Entity().HasKey( + d => new + { + d.Key2, + d.Key1 + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var associationType = databaseMapping.Model.AssociationTypes.Single(); + + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, associationType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); + databaseMapping.Assert() + .HasForeignKey( + new[] + { + "DependentForeignKeyPropertyNotFromConvention2", + "DependentForeignKeyPropertyNotFromConvention1" + }, + "PrincipalPrincipalNavOptionals"); + } + + [Fact] + public void Foreign_key_annotation_on_pk_should_change_principal_end_kind_required_to_required_bidirectional() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey( + d => d.DependentForeignKeyPropertyNotFromConvention1); + modelBuilder.Entity().HasKey(d => d.Key1); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var associationType = databaseMapping.Model.AssociationTypes.Single(); + + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, associationType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); + databaseMapping.Assert() + .HasForeignKey( + new[] { "DependentForeignKeyPropertyNotFromConvention1" }, + "PrincipalPrincipalNavRequireds"); + } + + [Fact] + public void Foreign_key_annotation_on_pk_should_change_principal_end_kind_required_to_required_bidirectional_required_dependentn() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey( + d => d.DependentForeignKeyPropertyNotFromConvention1); + modelBuilder.Entity().HasKey(d => d.Key1); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var associationType = databaseMapping.Model.AssociationTypes.Single(); + + Assert.Equal(RelationshipMultiplicity.One, associationType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.One, associationType.TargetEnd.RelationshipMultiplicity); + databaseMapping.Assert() + .HasForeignKey( + new[] { "DependentForeignKeyPropertyNotFromConvention1" }, + "PrincipalPrincipalNavRequiredDependents"); + } + + [Fact] + public void One_to_one_byte_key_inverse_and_fk_annotations() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey(p => p.Key1); + modelBuilder.Entity().HasKey(d => d.DependentForeignKeyPropertyNotFromConvention1); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Self_ref_inherited_should_not_cascade_on_delete() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal( + OperationAction.None, + databaseMapping.Model.AssociationTypes.Single().SourceEnd.DeleteBehavior); + + Assert.Equal( + OperationAction.None, + databaseMapping.Model.AssociationTypes.Single().TargetEnd.DeleteBehavior); + } + + [Fact] + public void Annotated_fk_composite_can_use_column_or_api_for_fk_ordering() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey( + p => new + { + p.Id2, + p.Id1 + }); + modelBuilder.Entity() + .Property(c => c.TheFk1).HasColumnOrder(2); + modelBuilder.Entity() + .Property(c => c.TheFk2).HasColumnOrder(1); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var fkConstraint + = databaseMapping.Database.EntityTypes + .Single(t => t.Name == "CompositeAnnotatedDependent") + .ForeignKeyBuilders + .Single(); + + Assert.True(new[] { "TheFk2", "TheFk1" }.SequenceEqual(fkConstraint.DependentColumns.Select(c => c.Name))); + + var tempQualifier1 = databaseMapping.Database; + DebugCheck.NotNull(tempQualifier1); + fkConstraint + = tempQualifier1.EntityTypes + .Single(t => t.Name == "CompositePartiallyAnnotatedDependent") + .ForeignKeyBuilders + .Single(); + + Assert.True(new[] { "TheFk2", "TheFk1" }.SequenceEqual(fkConstraint.DependentColumns.Select(c => c.Name))); + } + + [Fact] + public void Annotated_fk_composite_should_throw_when_no_ordering_defined() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey( + p => new + { + p.Id2, + p.Id1 + }); + modelBuilder.Entity(); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ForeignKeyAttributeConvention_OrderRequired", typeof(CompositePartiallyAnnotatedDependent)); + } + + [Fact] + public void Annotated_fk_one_to_one_should_use_annotation_to_determine_principal() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey(p => p.AnId); + modelBuilder.Entity().HasKey(ad => ad.AnotherId); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasForeignKeyColumn("AnotherId"); + } + + [Fact] + public void Annotated_fk_should_throw_when_invalid_nav_prop_specified() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage( + "ForeignKeyAttributeConvention_InvalidNavigationProperty", + "Id", typeof(AnnotatedDependentWrong), + "Wrong"); + } + + [Fact] + public void Generated_many_to_many_fk_columns_should_have_correct_store_type() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Property(p => p.Id).HasColumnType("bigint"); + modelBuilder.Entity().Property(t => t.Id).HasColumnType("bigint"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var table = databaseMapping.Database.EntityTypes.Single(t => t.Name == "TagProductA"); + + Assert.Equal("bigint", table.Properties.Single(c => c.Name == "Tag_Id").TypeName); + Assert.Equal("bigint", table.Properties.Single(c => c.Name == "ProductA_Id").TypeName); + } + + [Fact] + public void Generated_ia_fk_columns_should_have_correct_store_type() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasKey( + t => new + { + t.AnotherId1, + t.AnotherId2 + }) + .HasRequired(t => t.NavOne); + + modelBuilder + .Entity() + .HasKey(o => o.AnId) + .HasOptional(o => o.NavToOne); + modelBuilder + .Entity() + .Property(o => o.AnId) + .HasColumnType("bigint"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var table = databaseMapping.Database.EntityTypes.Single(t => t.Name == "ToOne"); + + Assert.Equal("bigint", table.Properties.Single(c => c.Name == "NavOne_AnId").TypeName); + } + + [Fact] + public void Generated_fk_columns_should_have_correct_store_type() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasOptional(si => si.Detail) + .WithRequired(sid => sid.Item); + + modelBuilder + .Entity() + .Property(si => si.SomeItemId) + .HasColumnType("bigint"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + databaseMapping.Assert(sid => sid.Id).DbEqual("bigint", c => c.TypeName); + } + + [Fact] + public void Generated_fk_columns_should_throw_with_misconfigured_store_type() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasOptional(si => si.Detail) + .WithRequired(sid => sid.Item); + modelBuilder + .Entity() + .Property(si => si.SomeItemId) + .HasColumnType("bigint"); + + modelBuilder + .Entity() + .Property(sid => sid.Id) + .HasColumnType("nvarchar"); + + Assert.Throws(() => BuildMapping(modelBuilder)); + } + + [Fact] + public void Unconfigured_fk_one_to_one_should_throw_with_unknown_principal() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnableToDeterminePrincipal", typeof(Dependent).ToString(), typeof(Principal).ToString()); + } + + [Fact] + public void Half_specified_one_to_one_relationships_should_throw_when_no_principal_specified() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasOptional(s => s.Detail); + modelBuilder + .Entity() + .HasOptional(d => d.Item); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnableToDeterminePrincipal", typeof(SomeItem).ToString(), typeof(SomeItemDetail).ToString()); + } + + [Fact] + public void Half_specified_one_to_one_relationships_should_not_throw_when_principal_specified() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasOptional(s => s.Detail); + modelBuilder + .Entity() + .HasRequired(d => d.Item); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); + } + + [Fact] + public void Half_specified_relationships_can_be_inversed_by_convention() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasMany(p => p.Tags); + modelBuilder + .Entity() + .HasMany(t => t.Products); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); + } + + [Fact] + public void Full_and_half_specified_relationships_can_be_inversed() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasMany(p => p.Tags) + .WithMany(t => t.Products); + modelBuilder + .Entity() + .HasMany(t => t.Products); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); + } + + [Fact] + public void Full_and_half_specified_relationships_can_be_uninversed() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasMany(p => p.Tags) + .WithMany(); + modelBuilder + .Entity() + .HasMany(t => t.Products); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(2, databaseMapping.Model.AssociationTypes.Count()); + } + + [Fact] + // Regression test for Dev11 Bug 98120 + public void Half_specified_optional_relationship_overrides_fully_specified_one() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(e => e.Detail).WithOptional(e => e.Item); + modelBuilder.Entity().HasOptional(e => e.Detail); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnableToDeterminePrincipal", typeof(SomeItem), typeof(SomeItemDetail)); + } + + [Fact] + // Regression test for Dev11 Bug 98118 + public void Half_specified_required_relationship_overrides_fully_specified_one() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(e => e.Detail).WithRequired(e => e.Item); + modelBuilder.Entity().HasRequired(e => e.Detail); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + var association = databaseMapping.Model.AssociationTypes.Single(); + Assert.Equal("SomeItem", association.SourceEnd.GetEntityType().Name); + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, association.SourceEnd.RelationshipMultiplicity); + Assert.Equal("SomeItem", association.Constraint.ToRole.GetEntityType().Name); + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, association.Constraint.ToRole.RelationshipMultiplicity); + } + + [Fact] + public void Half_specified_many_relationship_overrides_fully_specified_one() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().HasMany(s => s.Products).WithRequired(p => p.ProductSubcategory); + modelBuilder.Entity().HasMany(s => s.Products); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + databaseMapping.AssertValid(); + + var association = databaseMapping.Model.AssociationTypes.Single(); + Assert.Equal("ProductSubcategory", association.SourceEnd.GetEntityType().Name); + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, association.SourceEnd.RelationshipMultiplicity); + Assert.Equal("Product", association.Constraint.ToRole.GetEntityType().Name); + Assert.Equal(RelationshipMultiplicity.Many, association.Constraint.ToRole.RelationshipMultiplicity); + } + + [Fact] + public void Unconfigured_one_to_one_should_throw_with_unknown_principal() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey(o => o.AnId); + modelBuilder.Entity().HasKey( + o => new + { + o.AnotherId1, + o.AnotherId2 + }); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnableToDeterminePrincipal", typeof(ToOne), typeof(One)); + } + + [Fact] + public void Configured_one_to_one_should_make_ia_when_keys_incompatible() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasKey(o => o.AnId); + modelBuilder + .Entity() + .HasKey( + t => new + { + t.AnotherId1, + t.AnotherId2 + }) + .HasRequired(t => t.NavOne); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasForeignKeyColumn("NavOne_AnId"); + } + + [Fact] + // Regression test for Dev11 Bug 98118 + public void Self_ref_many_to_optional_should_find_FK() + { + var modelBuilder = new DbModelBuilder(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); + databaseMapping.Assert().HasForeignKeyColumn("ParentId"); + } + + [Fact] + public void Unconfigured_self_ref_one_to_one_should_throw_with_unknown_principal() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnableToDeterminePrincipal", typeof(SelfRefToOne), typeof(SelfRefToOne)); + } + + [Fact] + public void Self_ref_one_to_one_should_generate_ia_by_default() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(s => s.SelfOne); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasForeignKeyColumn("SelfOne_Id"); + } + + [Fact] + public void Build_model_for_ia_with_entity_splitting() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .Map( + c => + { + c.ToTable("SomeItemDetail"); + c.Properties(s => s.Id); + }) + .Map( + c => + { + c.ToTable("SplitTable"); + c.Properties(s => s.Id); + }); + + modelBuilder.Entity() + .HasOptional(s => s.Detail) + .WithRequired(sd => sd.Item) + .Map(c => c.ToTable("SplitTable")); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert("SplitTable").HasColumn("Item_SomeItemId"); + } + + [Fact] + public void Build_model_for_self_referencing_required_to_required_dependent_ia_with_configuration() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasRequired(s => s.Self) + .WithRequiredDependent() + .Map(c => c.MapKey("TheKey")); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.Assert().HasColumn("TheKey"); + } + + [Fact] + public void Build_model_for_self_referencing_required_to_required_principal_ia_with_configuration() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasRequired(s => s.Self) + .WithRequiredPrincipal() + .Map(c => c.MapKey("TheKey")); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasColumn("TheKey"); + } + + [Fact] + public void Build_model_for_self_referencing_optional_to_many_ia_with_configured_key_column() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasOptional(i => i.ParentItem) + .WithMany(i => i.ChildrenItems) + .Map(c => c.MapKey("ParentItemId")); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasColumn("ParentItemId"); + } + + [Fact] + public void Build_model_for_self_referencing_optional_to_many_ia_with_configured_composite_key_column() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasKey( + i => new + { + i.Id, + i.Name + }) + .HasOptional(i => i.ParentItem) + .WithMany(i => i.ChildrenItems) + .Map(c => c.MapKey("TheId", "TheName")); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasColumn("TheId"); + databaseMapping.Assert().HasColumn("TheName"); + } + + [Fact] + public void Build_model_for_self_referencing_configured_many_to_many() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasMany(p => p.Children) + .WithMany(p => p.Parents) + .Map( + m => + { + m.MapLeftKey("ParentId"); + m.MapRightKey("ChildId"); + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert("PersonPersons").HasColumns("ParentId", "ChildId"); + } + + [Fact] + public void Self_referencing_many_to_many_should_not_cascade_by_convention() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasMany(p => p.Children) + .WithMany(p => p.Parents); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var joinTable = databaseMapping.Database.EntityTypes.Single(t => t.Name == "PersonPerson"); + + Assert.Equal(2, joinTable.ForeignKeyBuilders.Count()); + + Assert.True(joinTable.ForeignKeyBuilders.All(fk => fk.DeleteAction == OperationAction.None)); + } + + [Fact] + public void Many_to_many_mapping_configuration_correct_ends_configured() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity() + .HasMany(p => p.Tags) + .WithMany(t => t.Products) + .Map( + mc => + { + mc.MapLeftKey("ProductId"); + mc.MapRightKey("TagId"); + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert("ProductATags").HasColumns("ProductId", "TagId"); + } + + [Fact] + public void Many_to_many_mapping_configuration_correct_ends_configured_several_times_last_wins() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity() + .HasMany(p => p.Tags) + .WithMany(t => t.Products) + .Map( + mc => + { + mc.MapLeftKey("BadId"); + mc.MapRightKey("BadId"); + mc.MapLeftKey("ProductId"); + mc.MapRightKey("TagId"); + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert("ProductATags").HasColumns("ProductId", "TagId"); + } + + [Fact] + public void Many_to_many_should_generate_cascading_fks_by_convention() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity() + .HasMany(p => p.Tags) + .WithMany(t => t.Products) + .Map( + mc => + { + mc.MapLeftKey("ProductId"); + mc.MapRightKey("TagId"); + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var joinTable = databaseMapping.Database.EntityTypes.Single(t => t.Name == "ProductATag"); + + Assert.Equal(2, joinTable.ForeignKeyBuilders.Count()); + + Assert.True(joinTable.ForeignKeyBuilders.All(fk => fk.DeleteAction == OperationAction.Cascade)); + } + + [Fact] + public void Many_to_many_mapping_configuration_correct_ends_configured_reverse() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity() + .HasMany(t => t.Products) + .WithMany(p => p.Tags) + .Map( + mc => + { + mc.MapLeftKey("TagId"); + mc.MapRightKey("ProductId"); + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert("TagProductAs").HasColumns("TagId", "ProductId"); + } + + [Fact] + public void Many_to_many_mapping_configuration_repeated_key_throws() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity() + .HasMany(p => p.Tags) + .WithMany(t => t.Products) + .Map( + mc => + { + mc.MapLeftKey("ProductId"); + mc.MapRightKey("ProductId"); + }); + + Assert.Throws(() => BuildMapping(modelBuilder)); + } + + [Fact] + public void Build_model_for_many_to_many_association_with_conflicting_table_name_in_different_schema() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity() + .HasMany(s => s.SalesReasons) + .WithMany(r => r.SalesOrderHeaders) + .Map(m => m.ToTable("Products", "schema")); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping + .Assert("Products", "schema") + .HasColumns("SalesOrderHeader_SalesOrderID", "SalesReason_SalesReasonID"); + } + + [Fact] + public void Build_model_for_circular_associations_with_fk_discovery() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasMany(a => a.Photos) + .WithRequired(p => p.Album); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(2, databaseMapping.Model.Containers.Single().AssociationSets.Count()); + var tempQualifier1 = databaseMapping.Database; + DebugCheck.NotNull(tempQualifier1); + Assert.Equal(2, tempQualifier1.EntityTypes.ElementAt(0).Properties.Count()); + + Assert.Equal(2, databaseMapping.Database.EntityTypes.ElementAt(1).Properties.Count()); + } + + [Fact] + public void Invalid_number_of_foreign_keys_specified_should_throw() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity() + .HasRequired(s => s.ProductCategory) + .WithMany(c => c.ProductSubcategories) + .HasForeignKey( + s => new + { + s.ProductCategoryID, + s.Name + }); + + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Configuring_nonnavigation_property_should_throw() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.ComplexType().Ignore(d => d.Item); + modelBuilder.Entity().HasRequired(e => e.Detail).WithMany(); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("NavigationPropertyNotFound", "Detail", "SomeItem"); + } + + [Fact] + public void Configuring_nonmapped_property_should_throw() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Ignore(e => e.Detail); + modelBuilder.Entity().HasRequired(e => e.Detail).WithMany(); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("NavigationPropertyNotFound", "Detail", "SomeItem"); + } + + [Fact] + public void Build_model_for_a_simple_one_to_many_association() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Discover_inverse_navigation_properties_using_annotation() + { + var modelBuilder = new AdventureWorksModelBuilder(); + modelBuilder.Conventions.Remove(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); + } + + [Fact] + public void Discover_foreign_key_properties_using_annotation() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.NotNull(databaseMapping.Model.AssociationTypes.Single().Constraint); + } + + [Fact] + public void Build_model_for_a_simple_one_to_many_association_cascading_delete() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_a_simple_self_referencing_association() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_simple_optional_to_many_independent_association() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_simple_required_to_many_independent_association() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasRequired(b => b.Product).WithMany(p => p.BillOfMaterials); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_simple_many_to_many_association() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_many_to_many_association_with_mapping_configuration() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .HasMany(s => s.SalesReasons) + .WithMany(r => r.SalesOrderHeaders) + .Map( + m => m.ToTable("MappingTable") + .MapLeftKey("TheOrder") + .MapRightKey("TheReason")); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert("MappingTable").HasColumns("TheOrder", "TheReason"); + databaseMapping.Assert("MappingTable").HasForeignKey(new[] { "TheOrder" }, "SalesOrderHeaders"); + databaseMapping.Assert("MappingTable").HasForeignKey(new[] { "TheReason" }, "SalesReasons"); + } + + [Fact] + public void Build_model_for_many_to_many_association_with_conflicting_table_name() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity() + .HasMany(s => s.SalesReasons) + .WithMany(r => r.SalesOrderHeaders) + .Map(m => m.ToTable("Products")); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert("Products").HasColumns("SalesOrderHeader_SalesOrderID", "SalesReason_SalesReasonID"); + } + + [Fact] + public void Build_model_for_simple_optional_to_required_bidirectional_association() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity() + .HasKey(cd => cd.CustomerID) + .HasRequired(cd => cd.Customer); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_simple_optional_to_required_unidirectional_association() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .HasOptional(c => c.CustomerDiscount) + .WithRequired(); + + modelBuilder.Entity() + .HasKey(cd => cd.CustomerID) + .Ignore(cd => cd.Customer); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_self_referencing_many_to_many_association() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.Database.EntityTypes.Count()); + } + + [Fact] + public void Inverse_navigation_property_from_base_should_throw() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity() + .HasRequired(d => d.DerivedPrincipalNavigation) + .WithRequiredDependent(p => p.DerivedDependentNavigation); + + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Configure_unidirectional_association_with_navigation_property_from_unmapped_base() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(d => d.PrincipalNavigation).WithRequiredDependent(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void FK_from_base_should_throw() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Ignore(); + modelBuilder.Entity().Ignore(d => d.PrincipalNavigation); + modelBuilder.Entity() + .HasRequired(d => d.DerivedPrincipalNavigation) + .WithMany(p => p.DerivedDependentNavigations) + .HasForeignKey(d => d.PrincipalNavigationId); + + Assert.Throws( + () => + modelBuilder.BuildAndValidate( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ForeignKeyPropertyNotFound", "PrincipalNavigationId", "DerivedDependent"); + } + + [Fact] + public void PK_as_FK_with_many_to_one_should_throw() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Ignore(); + modelBuilder.Entity() + .HasRequired(d => d.DerivedPrincipalNavigation) + .WithMany(p => p.DerivedDependentNavigations) + .HasForeignKey(d => d.Id); + + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Map_FK_From_Principal_Side_And_Table_Split_FK_Into_First_Table() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .HasKey(p => p.ProductID); + + modelBuilder.Entity() + .Ignore(p => p.SpecialOffer); + + modelBuilder.Entity() + .HasMany(o => o.SpecialOfferProducts) + .WithRequired() + .HasForeignKey(p => p.SpecialOfferID); + + modelBuilder.Entity() + .Map( + m => + { + m.Properties( + p => + new + { + p.ProductID, + p.rowguid, + p.SpecialOfferID // FK in table 1 + }); + m.ToTable("ProductOne"); + }) + .Map( + m => + { + m.Properties( + p => + new + { + p.ProductID, + p.ModifiedDate, + }); + m.ToTable("ProductTwo"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(3, databaseMapping.Database.EntityTypes.Count()); + + databaseMapping.Assert("ProductOne") + .HasColumns("ProductID", "SpecialOfferID", "rowguid") + .HasForeignKeyColumn("SpecialOfferID"); + + databaseMapping.Assert("ProductTwo") + .HasColumns("ProductID", "ModifiedDate") + .HasNoForeignKeyColumn("SpecialOfferID"); + } + + [Fact] + public void Map_FK_From_Principal_Side_And_Table_Split_FK_Into_Second_Table() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .HasKey(p => p.ProductID); + + modelBuilder.Entity() + .Ignore(p => p.SpecialOffer); + + modelBuilder.Entity() + .HasMany(o => o.SpecialOfferProducts) + .WithRequired() + .HasForeignKey(p => p.SpecialOfferID); + + modelBuilder.Entity() + .Map( + m => + { + m.Properties( + p => + new + { + p.ProductID, + p.rowguid + }); + m.ToTable("ProductOne"); + }) + .Map( + m => + { + m.Properties( + p => + new + { + p.ProductID, + p.ModifiedDate, + p.SpecialOfferID // FK in table 2 + }); + m.ToTable("ProductTwo"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(3, databaseMapping.Database.EntityTypes.Count()); + + databaseMapping.Assert("ProductOne") + .HasColumns("ProductID", "rowguid") + .HasNoForeignKeyColumn("SpecialOfferID"); + + databaseMapping.Assert("ProductTwo") + .HasColumns("ProductID", "SpecialOfferID", "ModifiedDate") + .HasForeignKeyColumn("SpecialOfferID"); + } + + [Fact] + // DevDiv2 165131 + public void Map_IA_to_Pluralized_Table() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasKey(e => e.CustomerID); + modelBuilder.Entity() + .HasKey(e => e.CustomerID) + .HasRequired(cd => cd.Customer) + .WithRequiredPrincipal(c => c.CustomerDiscount) + .Map(m => m.ToTable("Customers")); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Customers"); + databaseMapping.Assert().HasForeignKeyColumn("CustomerDiscount_CustomerID"); + } + + [Fact] + public void Map_IA_To_First_Split_Table() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .HasKey(p => p.ProductID) + .Map( + m => + { + m.Properties( + p => + new + { + p.ProductID, + p.rowguid + }); + m.ToTable("ProductOne"); + }) + .Map( + m => + { + m.Properties( + p => + new + { + p.ProductID, + p.ModifiedDate, + p.SpecialOfferID + }); + m.ToTable("ProductTwo"); + }); + + modelBuilder.Entity() + .HasKey(o => o.SpecialOfferID) + .HasMany(o => o.SpecialOfferProducts) + .WithRequired(p => p.SpecialOffer) + .Map(mc => mc.MapKey("TheFK")); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(3, databaseMapping.Database.EntityTypes.Count()); + + databaseMapping.Assert("ProductOne") + .HasColumns("ProductID", "rowguid", "TheFK") + .HasForeignKeyColumn("TheFK"); + databaseMapping.Assert("ProductTwo") + .HasColumns("ProductID", "SpecialOfferID", "ModifiedDate") + .HasNoForeignKeyColumn("TheFK"); + } + + [Fact] + public void Map_IA_Column_Names() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .HasKey(p => p.ProductID); + + modelBuilder.Entity() + .HasKey(o => o.SpecialOfferID) + .HasMany(o => o.SpecialOfferProducts) + .WithRequired(p => p.SpecialOffer) + .Map(mc => mc.MapKey("TheFK")); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.Database.EntityTypes.Count()); + + databaseMapping.Assert() + .HasColumns("ProductID", "SpecialOfferID", "rowguid", "ModifiedDate", "TheFK") + .HasForeignKeyColumn("TheFK"); + } + + [Fact] + public void Map_IA_column_names_several_times_last_wins() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .HasKey(p => p.ProductID); + + modelBuilder.Entity() + .HasKey(o => o.SpecialOfferID) + .HasMany(o => o.SpecialOfferProducts) + .WithRequired(p => p.SpecialOffer) + .Map( + mc => + { + mc.MapKey("BadFK"); + mc.ToTable("BadTable"); + mc.MapKey("TheFK"); + mc.ToTable("SpecialOfferProducts"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.Database.EntityTypes.Count()); + + databaseMapping.Assert() + .HasColumns("ProductID", "SpecialOfferID", "rowguid", "ModifiedDate", "TheFK") + .HasForeignKeyColumn("TheFK"); + } + + [Fact] + public void Mapping_IA_column_name_to_existing_one_throws() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .HasKey(p => p.ProductID); + + modelBuilder.Entity() + .HasKey(o => o.SpecialOfferID) + .HasMany(o => o.SpecialOfferProducts) + .WithRequired(p => p.SpecialOffer) + .Map(mc => mc.MapKey("SpecialOfferID")); + + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Can_turn_cascade_delete_off_for_IA_association() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Ignore(d => d.CDPrinId); + modelBuilder.Entity().HasMany(p => p.CDDeps).WithRequired(d => d.CDPrin).WillCascadeOnDelete(false); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var associationSet = databaseMapping.Model.Containers.Single().AssociationSets[0]; + + Assert.Equal(OperationAction.None, associationSet.ElementType.SourceEnd.DeleteBehavior); + Assert.Equal(OperationAction.None, associationSet.ElementType.TargetEnd.DeleteBehavior); + } + + [Fact] + public void Can_turn_cascade_delete_on_for_IA_association() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().Ignore(d => d.CDPrinId); + modelBuilder.Entity().HasMany(p => p.CDDeps).WithRequired(d => d.CDPrin).WillCascadeOnDelete(true); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; + Assert.Equal(OperationAction.Cascade, aset.ElementType.SourceEnd.DeleteBehavior); + Assert.Equal(OperationAction.None, aset.ElementType.TargetEnd.DeleteBehavior); + } + + [Fact] + public void Can_turn_cascade_delete_off_for_non_nullable_FK_association() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasMany(p => p.CDDeps).WithRequired(d => d.CDPrin).HasForeignKey( + d => d.CDPrinId).WillCascadeOnDelete(false); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; + Assert.Equal(OperationAction.None, aset.ElementType.SourceEnd.DeleteBehavior); + Assert.Equal(OperationAction.None, aset.ElementType.TargetEnd.DeleteBehavior); + } + + [Fact] + public void Can_turn_cascade_delete_on_for_non_nullable_FK_association() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().HasMany(p => p.CDDeps).WithRequired(d => d.CDPrin).HasForeignKey( + d => d.CDPrinId).WillCascadeOnDelete(true); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; + Assert.Equal(OperationAction.Cascade, aset.ElementType.SourceEnd.DeleteBehavior); + Assert.Equal(OperationAction.None, aset.ElementType.TargetEnd.DeleteBehavior); + } + + [Fact] + public void Can_set_optional_to_optional_dependent_relationships_and_you_get_an_IA() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(p => p.Item).WithOptionalDependent(p => p.Detail); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; + Assert.Null(aset.ElementType.Constraint); + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.TargetEnd.RelationshipMultiplicity); + databaseMapping.Assert().HasForeignKeyColumn("Item_SomeItemId"); // IA FK + Assert.Equal(1, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); + } + + [Fact] + public void Default_ia_fk_column_names_should_incorporate_nav_prop_on_dependent() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasOptional(s => s.Detail) + .WithRequired(d => d.Item) + .Map(_ => { }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasForeignKeyColumn("Item_SomeItemId"); + } + + [Fact] + public void Can_set_optional_to_optional_principal_relationships_and_you_get_an_IA() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(d => d.Detail).WithOptionalPrincipal(p => p.Item); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; + Assert.Null(aset.ElementType.Constraint); + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.TargetEnd.RelationshipMultiplicity); + databaseMapping.Assert().HasForeignKeyColumn("Item_SomeItemId"); // IA FK + Assert.Equal(1, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); + } + + [Fact] + public void Can_set_required_to_required_dependent_relationships_and_you_get_an_FK() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(p => p.Item).WithRequiredDependent(p => p.Detail); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; + Assert.NotNull(aset.ElementType.Constraint); + Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.TargetEnd.RelationshipMultiplicity); + databaseMapping.Assert().HasForeignKeyColumn("Id"); // FK + Assert.Equal(0, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); + } + + [Fact] + public void Can_set_required_to_required_principal_relationships_and_you_get_an_FK() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(d => d.Detail).WithRequiredPrincipal(p => p.Item); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; + Assert.NotNull(aset.ElementType.Constraint); + Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.TargetEnd.RelationshipMultiplicity); + databaseMapping.Assert().HasForeignKeyColumn("Id"); // FK + Assert.Equal(0, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); + } + + [Fact] + public void Can_set_required_to_optional_relationship_and_you_get_an_FK_with_correct_dependent_end() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(d => d.Item).WithOptional(p => p.Detail); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; + Assert.NotNull(aset.ElementType.Constraint); + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.TargetEnd.RelationshipMultiplicity); + databaseMapping.Assert().HasForeignKeyColumn("Id"); // FK + Assert.Equal(0, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); + } + + [Fact] + public void Can_set_optional_to_required_relationship_and_you_get_an_FK_with_correct_dependent_end() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(d => d.Detail).WithRequired(p => p.Item); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; + Assert.NotNull(aset.ElementType.Constraint); + Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.TargetEnd.RelationshipMultiplicity); + databaseMapping.Assert().HasForeignKeyColumn("Id"); // FK + Assert.Equal(0, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); + } + + [Fact] + public void Ignore_FK_property_and_you_get_an_IA() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasMany(p => p.CDDeps).WithRequired(d => d.CDPrin); + modelBuilder.Entity().Ignore(d => d.CDPrinId); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; + Assert.Null(aset.ElementType.Constraint); + Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.Many, aset.ElementType.TargetEnd.RelationshipMultiplicity); + databaseMapping.Assert().HasForeignKeyColumn("CDPrin_CDPrinId"); // AI FK + Assert.Equal(1, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); + } + + #region Configuration from both sides tests + + [Fact] + public void Redundant_many_to_many_mapping_configuration_with_left_and_right_keys_switched_should_not_throw() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasMany(p => p.Tags) + .WithMany(t => t.Products) + .Map( + mc => + { + mc.MapLeftKey("ProductId"); + mc.MapRightKey("TagId"); + mc.ToTable("ProductTags"); + }); + + modelBuilder.Entity() + .HasMany(t => t.Products) + .WithMany(p => p.Tags) + .Map( + mc => + { + mc.MapLeftKey("TagId"); + mc.MapRightKey("ProductId"); + mc.ToTable("ProductTags"); + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Redundant_many_to_many_mapping_configuration_should_not_throw() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasMany(p => p.Tags) + .WithMany(t => t.Products) + .Map( + mc => + { + mc.MapLeftKey("TagId"); + mc.MapRightKey("ProductId"); + mc.ToTable("ProductTags"); + }); + + modelBuilder.Entity() + .HasMany(t => t.Products) + .WithMany(p => p.Tags) + .Map( + mc => + { + mc.MapLeftKey("TagId"); + mc.MapRightKey("ProductId"); + mc.ToTable("ProductTags"); + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Inconsistent_redundant_many_to_many_mapping_configuration_should_throw() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasMany(p => p.Tags) + .WithMany(t => t.Products) + .Map( + mc => + { + mc.MapLeftKey("ProductCode"); + mc.MapRightKey("TagId"); + mc.ToTable("ProductTags"); + }); + + modelBuilder.Entity() + .HasMany(t => t.Products) + .WithMany(p => p.Tags) + .Map( + mc => + { + mc.MapLeftKey("TagId"); + mc.MapRightKey("ProductId"); + mc.ToTable("ProductTags"); + }); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ConflictingMapping", "Products", "FunctionalTests.Tag"); + } + + [Fact] + public void Conflicting_multiplicity_throws_optional_to_one_and_one_to_one_dependent() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(d => d.Detail).WithRequired(p => p.Item); + modelBuilder.Entity().HasRequired(d => d.Item).WithRequiredDependent(p => p.Detail); + + Assert.Throws( + () => + modelBuilder.Build( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ConflictingMultiplicities", "Detail", "FunctionalTests.SomeItem"); + } + + [Fact] + public void Conflicting_multiplicity_throws_optional_to_one_and_one_to_one_principal() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(d => d.Detail).WithRequired(p => p.Item); + modelBuilder.Entity().HasRequired(d => d.Item).WithRequiredPrincipal(p => p.Detail); + + Assert.Throws( + () => + modelBuilder.Build( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ConflictingMultiplicities", "Detail", "FunctionalTests.SomeItem"); + } + + [Fact] + public void Conflicting_multiplicity_throws_optional_to_one_and_optional_to_one() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(d => d.Detail).WithRequired(p => p.Item); + modelBuilder.Entity().HasOptional(d => d.Item).WithRequired(p => p.Detail); + + Assert.Throws( + () => + modelBuilder.Build( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ConflictingMultiplicities", "Item", "FunctionalTests.SomeItemDetail"); + } + + [Fact] + public void Conflicting_multiplicity_throws_optional_to_one_and_optional_to_optional_dependent() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(d => d.Detail).WithRequired(p => p.Item); + modelBuilder.Entity().HasOptional(d => d.Item).WithOptionalDependent(p => p.Detail); + + Assert.Throws( + () => + modelBuilder.Build( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ConflictingMultiplicities", "Item", "FunctionalTests.SomeItemDetail"); + } + + [Fact] + public void Conflicting_multiplicity_throws_optional_to_one_and_optional_to_optional_principal() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(d => d.Detail).WithRequired(p => p.Item); + modelBuilder.Entity().HasOptional(d => d.Item).WithOptionalPrincipal(p => p.Detail); + + Assert.Throws( + () => + modelBuilder.Build( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ConflictingMultiplicities", "Item", "FunctionalTests.SomeItemDetail"); + } + + [Fact] + public void Conflicting_multiplicity_throws_optional_to_optional_principal_and_optional_to_optional_principal() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(d => d.Detail).WithOptionalPrincipal(p => p.Item); + modelBuilder.Entity().HasOptional(d => d.Item).WithOptionalPrincipal(p => p.Detail); + + Assert.Throws( + () => + modelBuilder.Build( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ConflictingConstraint", "Item", "FunctionalTests.SomeItemDetail"); + } + + [Fact] + public void Conflicting_multiplicity_throws_optional_to_optional_dependent_and_optional_to_optional_dependent() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(d => d.Detail).WithOptionalDependent(p => p.Item); + modelBuilder.Entity().HasOptional(d => d.Item).WithOptionalDependent(p => p.Detail); + + Assert.Throws( + () => + modelBuilder.Build( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ConflictingConstraint", "Item", "FunctionalTests.SomeItemDetail"); + } + + [Fact] + public void Conflicting_multiplicity_throws_optional_to_optional_dependent_and_one_to_one_dependent() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(d => d.Detail).WithOptionalDependent(p => p.Item); + modelBuilder.Entity().HasRequired(d => d.Item).WithRequiredDependent(p => p.Detail); + + Assert.Throws( + () => + modelBuilder.Build( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ConflictingMultiplicities", "Item", "FunctionalTests.SomeItemDetail"); + } + + [Fact] + public void Conflicting_multiplicity_throws_optional_to_optional_dependent_and_one_to_one_principal() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(d => d.Detail).WithOptionalDependent(p => p.Item); + modelBuilder.Entity().HasRequired(d => d.Item).WithRequiredPrincipal(p => p.Detail); + + Assert.Throws( + () => + modelBuilder.Build( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ConflictingMultiplicities", "Item", "FunctionalTests.SomeItemDetail"); + } + + [Fact] + public void Conflicting_multiplicity_throws_one_to_one_principal_and_one_to_one_principal() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(d => d.Detail).WithRequiredPrincipal(p => p.Item); + modelBuilder.Entity().HasRequired(d => d.Item).WithRequiredPrincipal(p => p.Detail); + + Assert.Throws( + () => + modelBuilder.Build( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ConflictingConstraint", "Item", "FunctionalTests.SomeItemDetail"); + } + + [Fact] + public void Conflicting_multiplicity_throws_one_to_one_dependent_and_one_to_one_dependent() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(d => d.Detail).WithRequiredDependent(p => p.Item); + modelBuilder.Entity().HasRequired(d => d.Item).WithRequiredDependent(p => p.Detail); + + Assert.Throws( + () => + modelBuilder.Build( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ConflictingConstraint", "Item", "FunctionalTests.SomeItemDetail"); + } + + [Fact] + public void Conflicting_multiplicity_throws_one_to_many_and_many_to_optional() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(s => s.ProductCategory).WithMany( + c => c.ProductSubcategories); + modelBuilder.Entity().HasMany(c => c.ProductSubcategories).WithOptional( + s => s.ProductCategory); + + Assert.Throws( + () => + modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)). + ValidateMessage("ConflictingMultiplicities", "ProductCategory", "FunctionalTests.Model.ProductSubcategory"); + } + + // Dev11 330745 + [Fact] + public void Using_invalid_mapping_from_two_ends_without_nav_prop_when_nav_prop_exists_should_throw_but_not_NullReferenceException() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasOptional(d => d.Detail) + .WithRequired(p => p.Item); + + modelBuilder + .Entity() + .HasRequired(d => d.Item) + .WithRequiredPrincipal(); // <- There is an inverse nav-prop, but pretending that there isn't. + + Assert.Throws( + () => + modelBuilder.Build( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ConflictingMultiplicities", "Item", "FunctionalTests.SomeItemDetail"); + } + + [Fact] + public void Redundant_optional_to_optional_configuration_should_not_throw() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(d => d.Detail).WithOptionalPrincipal(p => p.Item); + modelBuilder.Entity().HasOptional(d => d.Item).WithOptionalDependent(p => p.Detail); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; + Assert.Null(aset.ElementType.Constraint); + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, aset.ElementType.TargetEnd.RelationshipMultiplicity); + databaseMapping.Assert().HasForeignKeyColumn("Item_SomeItemId"); // IA FK + Assert.Equal(1, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); + } + + [Fact] + public void Redundant_one_to_one_configuration_should_not_throw() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(d => d.Detail).WithRequiredDependent(p => p.Item); + modelBuilder.Entity().HasRequired(d => d.Item).WithRequiredPrincipal(p => p.Detail); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + var aset = databaseMapping.Model.Containers.Single().AssociationSets[0]; + Assert.NotNull(aset.ElementType.Constraint); + Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.SourceEnd.RelationshipMultiplicity); + Assert.Equal(RelationshipMultiplicity.One, aset.ElementType.TargetEnd.RelationshipMultiplicity); + databaseMapping.Assert().HasForeignKeyColumn("SomeItemId"); // FK + Assert.Equal(0, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); + } + + [Fact] + public void Conflicting_cascade_delete_throws() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(d => d.Detail).WithRequired(p => p.Item).WillCascadeOnDelete( + true); + modelBuilder.Entity().HasRequired(d => d.Item).WithOptional(p => p.Detail). + WillCascadeOnDelete(false); + + Assert.Throws( + () => + modelBuilder.Build( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ConflictingCascadeDeleteOperation", "Item", "FunctionalTests.SomeItemDetail"); + } + + [Fact] + public void Conflicting_FK_throws() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(s => s.ProductCategory).WithMany( + c => c.ProductSubcategories).HasForeignKey(s => s.ProductCategoryID); + modelBuilder.Entity().HasMany(c => c.ProductSubcategories).WithRequired( + s => s.ProductCategory).HasForeignKey(s => s.ProductSubcategoryID); + + Assert.Throws( + () => + modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)). + ValidateMessage("ConflictingConstraint", "ProductSubcategories", "FunctionalTests.Model.ProductCategory"); + } + + [Fact] + public void Conflicting_FK_vs_IA_configuration_throws() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(s => s.ProductCategory).WithMany( + c => c.ProductSubcategories).HasForeignKey(c => c.ProductSubcategoryID); + modelBuilder.Entity().HasMany(c => c.ProductSubcategories).WithRequired( + s => s.ProductCategory).Map(_ => { }); + + Assert.Throws( + () => + modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)). + ValidateMessage("ConflictingConstraint", "ProductSubcategories", "FunctionalTests.Model.ProductCategory"); + } + + [Fact] + public void Conflicting_IA_column_name_configuration_throws() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(s => s.ProductCategory).WithMany( + c => c.ProductSubcategories).Map(c => c.MapKey("Key1")); + modelBuilder.Entity().HasMany(c => c.ProductSubcategories).WithRequired( + s => s.ProductCategory).Map(c => c.MapKey("Key2")); + + Assert.Throws( + () => + modelBuilder.Build( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ConflictingMapping", "ProductSubcategories", "FunctionalTests.Model.ProductCategory"); + } + + #endregion + + [Fact] + // Regression test for Dev11 Bug 8383 "Identity convention should not be applied when PK is an FK." + public void Setting_required_to_optional_relationship_gives_you_a_PK_FK_that_is_not_identity() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(d => d.Item).WithOptional(p => p.Detail); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert().HasForeignKeyColumn("Id"); + databaseMapping.Assert(d => d.Id) + .DbEqual(true, c => c.IsPrimaryKeyColumn) + .DbEqual(StoreGeneratedPattern.None, c => c.StoreGeneratedPattern); + } + + [Fact] + // Regression test for Dev11 Bug 8383 "Identity convention should not be applied when PK is an FK." + public void Setting_optional_to_required_relationship_gives_you_a_PK_FK_that_is_not_identity() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(p => p.Detail).WithRequired(d => d.Item); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert().HasForeignKeyColumn("Id"); + databaseMapping.Assert(d => d.Id) + .DbEqual(true, c => c.IsPrimaryKeyColumn) + .DbEqual(StoreGeneratedPattern.None, c => c.StoreGeneratedPattern); + } + + // Dev11 345384 + [Fact] + public void Identity_key_is_created_by_convention_when_table_splitting_is_specified_with_fluent_API() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().ToTable("SharedTable"); + modelBuilder.Entity().ToTable("SharedTable"); + modelBuilder.Entity().HasRequired(d => d.BackRef).WithRequiredPrincipal(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert(d => d.Id) + .DbEqual(true, c => c.IsPrimaryKeyColumn) + .DbEqual(StoreGeneratedPattern.Identity, c => c.StoreGeneratedPattern); + databaseMapping.Assert(d => d.Id) + .DbEqual(true, c => c.IsPrimaryKeyColumn) + .DbEqual(StoreGeneratedPattern.Identity, c => c.StoreGeneratedPattern); + } + + // Dev11 345384 + [Fact] + public void Identity_key_is_created_by_convention_when_table_splitting_is_specified_with_attributes() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(d => d.BackRef).WithRequiredPrincipal(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert(d => d.Id) + .DbEqual(true, c => c.IsPrimaryKeyColumn) + .DbEqual(StoreGeneratedPattern.Identity, c => c.StoreGeneratedPattern); + databaseMapping.Assert(d => d.Id) + .DbEqual(true, c => c.IsPrimaryKeyColumn) + .DbEqual(StoreGeneratedPattern.Identity, c => c.StoreGeneratedPattern); + } + + [Fact] + public void Setting_IA_FK_name_also_changes_condition_column_name() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasKey(e => e.Key1); + modelBuilder.Entity().Map(mapping => mapping.ToTable("Dependent")); + modelBuilder.Entity().HasOptional(e => e.PrincipalNavigation).WithMany( + e => e.DependentNavigation) + .Map(m => m.MapKey("IndependentColumn1")); + modelBuilder.Entity().Map(mapping => mapping.ToTable("BaseDependent")); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert() + .HasColumn("IndependentColumn1"); + Assert.Equal( + "IndependentColumn1", + databaseMapping.EntityContainerMappings[0].AssociationSetMappings.ElementAt(0).ColumnConditions.ElementAt(0).ColumnProperty + .Name); + } + + // Dev11 287430 + [Fact] + public void Data_annotations_should_not_be_applied_to_many_to_many_mapping_when_association_is_fully_configured_with_fluent_API() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + modelBuilder + .Entity() + .HasMany(m => m.Persons) + .WithMany(p => p.Roles) + .Map( + m => m.ToTable("person_role", "domain") + .MapLeftKey("role_identifier") + .MapRightKey("person_identifier")); + + var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); + var databaseMapping = model.DatabaseMapping; + + databaseMapping.AssertValid(); + databaseMapping.Assert("person_role", "domain").HasColumns("person_identifier", "role_identifier"); + databaseMapping.Assert("person_role", "domain").HasForeignKey(new[] { "role_identifier" }, "role"); + databaseMapping.Assert("person_role", "domain").HasForeignKey(new[] { "person_identifier" }, "person"); + } + + [Fact] + public void Bug_46199_Sequence_contains_more_than_one_element_exception_thrown_at_navigation_property_configuration() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasOptional(p => p.Mother).WithMany().Map(t => t.MapKey("MotherId")); + modelBuilder.Entity().HasOptional(p => p.Father).WithMany().Map(t => t.MapKey("FatherId")); + modelBuilder.Entity().HasOptional(p => p.Birth).WithOptionalDependent().Map(t => t.MapKey("BirthdayId")); + modelBuilder.Entity().HasOptional(p => p.Death).WithOptionalDependent().Map(t => t.MapKey("DeathdayId")); + modelBuilder.Entity().HasRequired(e => e.WeddingDay).WithOptional().Map(t => t.MapKey("WeddingDayId")); + modelBuilder.Entity().HasRequired(e => e.Wife).WithMany().Map(t => t.MapKey("WifeId")); + modelBuilder.Entity().HasRequired(e => e.Husband).WithMany().Map(t => t.MapKey("HusbandId")); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void ForeignKey_annotation_is_allowed_for_one_to_one_PK_to_PK_mapping_Dev11_437725() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasRequired(r => r.Detail) + .WithRequiredPrincipal(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasForeignKey( + new[] { "OneToOneResultId" }, "OneToOneResults"); + } + } + + #region Fixtures + + public class CDPrin + { + public int CDPrinId { get; set; } + public List CDDeps { get; set; } + } + + public class CDDep + { + public int Id { get; set; } + public int CDPrinId { get; set; } + public CDPrin CDPrin { get; set; } + } + + public class SomeItem + { + public int SomeItemId { get; set; } + public SomeItemDetail Detail { get; set; } + } + + public class SomeItemDetail + { + public int Id { get; set; } + public SomeItem Item { get; set; } + } + + public class Album + { + public int Id { get; set; } + public virtual Photo Thumbnail { get; set; } + public int? ThumbnailId { get; set; } + public virtual ICollection Photos { get; set; } + } + + public class Photo + { + public int Id { get; set; } + public int AlbumId { get; set; } + public virtual Album Album { get; set; } + } + + public class ProductA + { + public int Id { get; set; } + public string Name { get; set; } + public ICollection Tags { get; set; } + } + + public class Tag + { + public int Id { get; set; } + public string Name { get; set; } + public ICollection Products { get; set; } + } + + public class Item + { + public int Id { get; set; } + public int Name { get; set; } + public virtual Item ParentItem { get; set; } + public virtual ICollection ChildrenItems { get; set; } + } + + public class Person + { + public int Id { get; set; } + public ICollection Children { get; set; } + public ICollection Parents { get; set; } + } + + public class SelfRef + { + public int Id { get; set; } + public SelfRef Self { get; set; } + } + + public class TreeNode + { + public int Id { get; set; } + public int? ParentId { get; set; } + public TreeNode Parent { get; set; } + public ICollection Children { get; set; } + } + + public class One + { + public int AnId { get; set; } + public ToOne NavToOne { get; set; } + } + + public class ToOne + { + public string AnotherId1 { get; set; } + public string AnotherId2 { get; set; } + public One NavOne { get; set; } + } + + public class SelfRefToOne + { + public int Id { get; set; } + public SelfRefToOne SelfOne { get; set; } + public SelfRefToOne SelfTwo { get; set; } + } + + public class Principal + { + public int Id { get; set; } + public Dependent DependentNavigation { get; set; } + } + + public class Dependent + { + public int Id { get; set; } + public Principal PrincipalNavigation { get; set; } + } + + public class PrincipalWithAnnotatedDependent + { + public string AnId { get; set; } + public AnnotatedDependent Dependent { get; set; } + } + + public class AnnotatedDependent + { + [ForeignKey("Principal")] + public string AnotherId { get; set; } + + public PrincipalWithAnnotatedDependent Principal { get; set; } + } + + public class AnnotatedDependentWrong + { + [ForeignKey("Wrong")] + public string Id { get; set; } + + public PrincipalWithAnnotatedDependent Principal { get; set; } + } + + public class PrincipalWithCompositeAnnotatedDependent + { + public int Id1 { get; set; } + public string Id2 { get; set; } + public ICollection Dependents { get; set; } + public ICollection Dependents2 { get; set; } + } + + public class CompositeAnnotatedDependent + { + public int Id { get; set; } + + [ForeignKey("Principal")] + [Column(Order = 2)] + public int TheFk1 { get; set; } + + [ForeignKey("Principal")] + [Column(Order = 1)] + public string TheFk2 { get; set; } + + public PrincipalWithCompositeAnnotatedDependent Principal { get; set; } + } + + public class CompositePartiallyAnnotatedDependent + { + public int Id { get; set; } + + [ForeignKey("Principal")] + public int TheFk1 { get; set; } + + [ForeignKey("Principal")] + public string TheFk2 { get; set; } + + public PrincipalWithCompositeAnnotatedDependent Principal { get; set; } + } + + public class PrincipalBase + { + public int Id { get; set; } + public DerivedDependent DerivedDependentNavigation { get; set; } + } + + public class DerivedPrincipal : PrincipalBase + { + public ICollection DerivedDependentNavigations { get; set; } + } + + public class DependentBase + { + public int Id { get; set; } + public int PrincipalNavigationId { get; set; } + public PrincipalBase PrincipalNavigation { get; set; } + } + + public class DerivedDependent : DependentBase + { + public DerivedPrincipal DerivedPrincipalNavigation { get; set; } + } + + public class SelfRefInheritedBase + { + public string Id { get; set; } + + [Required] + public SelfRefInheritedDerived Derived { get; set; } + } + + public class SelfRefInheritedDerived : SelfRefInheritedBase + { + public ICollection Bases { get; set; } + } + + public class DependentNoPrincipalNavRequired + { + [ForeignKey("PrincipalNavigation")] + public Guid DependentForeignKeyPropertyNotFromConvention1 { get; set; } + + [Required] + public PrincipalNoPrincipalNav PrincipalNavigation { get; set; } + } + + public class DependentNoPrincipalNavOptional + { + [ForeignKey("PrincipalNavigation")] + public Guid DependentForeignKeyPropertyNotFromConvention1 { get; set; } + + public PrincipalNoPrincipalNav PrincipalNavigation { get; set; } + } + + public class PrincipalNoPrincipalNav + { + public Guid? Key1 { get; set; } + } + + public class DependentPrincipalNavOptional + { + [ForeignKey("PrincipalNavigation")] + public int DependentForeignKeyPropertyNotFromConvention1 { get; set; } + + [ForeignKey("PrincipalNavigation")] + public Guid DependentForeignKeyPropertyNotFromConvention2 { get; set; } + + public PrincipalPrincipalNavOptional PrincipalNavigation { get; set; } + } + + public class PrincipalPrincipalNavOptional + { + public int? Key1 { get; set; } + public Guid? Key2 { get; set; } + public DependentPrincipalNavOptional DependentNavigation { get; set; } + } + + public class DependentPrincipalNavRequired + { + [ForeignKey("PrincipalNavigation")] + public Guid DependentForeignKeyPropertyNotFromConvention1 { get; set; } + + [Required] + public PrincipalPrincipalNavRequired PrincipalNavigation { get; set; } + } + + public class PrincipalPrincipalNavRequired + { + public Guid? Key1 { get; set; } + public DependentPrincipalNavRequired DependentNavigation { get; set; } + } + + public class DependentPrincipalNavRequiredDependent + { + [ForeignKey("PrincipalNavigation")] + public Guid DependentForeignKeyPropertyNotFromConvention1 { get; set; } + + public PrincipalPrincipalNavRequiredDependent PrincipalNavigation { get; set; } + } + + public class PrincipalPrincipalNavRequiredDependent + { + public Guid? Key1 { get; set; } + + [Required] + public DependentPrincipalNavRequiredDependent DependentNavigation { get; set; } + } + + public class PrincipalByteKey + { + public byte[] Key1 { get; set; } + + [ForeignKey("DependentForeignKeyPropertyNotFromConvention1")] + public DependentByteKey DependentNavigation { get; set; } + } + + public class DependentByteKey + { + public byte[] DependentForeignKeyPropertyNotFromConvention1 { get; set; } + + [InverseProperty("DependentNavigation")] + [Required] + public PrincipalByteKey PrincipalNavigation { get; set; } + } + + public class DependentSelfRef + { + [ForeignKey("PrincipalNavigation")] + [Column(Order = 1)] + public DateTimeOffset Key1 { get; set; } + + [ForeignKey("PrincipalNavigation")] + [Column(Order = 2)] + public DateTimeOffset DependentForeignKeyPropertyNotFromConvention1 { get; set; } + + [Required] + public DerivedDependentSelfRef PrincipalNavigation { get; set; } + } + + public class DerivedDependentSelfRef : DependentSelfRef + { + public byte[] DerivedProperty1 { get; set; } + } + + public class DependentWeirdKeyOrder + { + public int Fk1 { get; set; } + public int Fk2 { get; set; } + + [ForeignKey("Fk2,Fk1")] + public PrincipalWeirdKeyOrder PrincipalNavigation { get; set; } + } + + public class DependentWeirdKeyOrder2 + { + public int Fk1 { get; set; } + public int Fk2 { get; set; } + + [ForeignKey("Fk1,Fk2")] + public PrincipalWeirdKeyOrder PrincipalNavigation { get; set; } + } + + public class PrincipalWeirdKeyOrder + { + public int Id1 { get; set; } + public int Id2 { get; set; } + } + + public class BaseDependentAbstractKeyOrder + { + public decimal BaseProperty { get; set; } + public int Id { get; set; } + } + + public abstract class DependentAbstractKeyOrder : BaseDependentAbstractKeyOrder + { + [ForeignKey("PrincipalNavigation")] + [Column(Order = 1)] + public decimal? DependentForeignKeyPropertyNotFromConvention1 { get; set; } + + [ForeignKey("PrincipalNavigation")] + [Column(Order = 2)] + public decimal? DependentForeignKeyPropertyNotFromConvention2 { get; set; } + + public PrincipalAbstractKeyOrder PrincipalNavigation { get; set; } + } + + public class BasePrincipalAbstractKeyOrder + { + public string BaseProperty { get; set; } + public decimal Key1 { get; set; } + public decimal Key2 { get; set; } + } + + public abstract class PrincipalAbstractKeyOrder : BasePrincipalAbstractKeyOrder + { + } + + public class DerivedPrincipalKeyOrder : PrincipalAbstractKeyOrder + { + } + + public class DerivedDependentKeyOrder : DependentAbstractKeyOrder + { + public byte DerivedProperty1 { get; set; } + } + + public abstract class DependentSelfRefInverse + { + public short Key1 { get; set; } + public short DependentSelfRefInverseKey1 { get; set; } + + public DependentSelfRefInverse DependentNavigation { get; set; } + + [InverseProperty("DependentNavigation")] + [Required] + public DependentSelfRefInverse PrincipalNavigation { get; set; } + } + + public class DerivedDependentSelfRefInverse : DependentSelfRefInverse + { + public string DerivedProperty1 { get; set; } + } + + public class BaseDependentFkAbstract + { + public DateTime? BaseProperty { get; set; } + public int Id { get; set; } + } + + public abstract class DependentFkAbstract : BaseDependentFkAbstract + { + public int? DependentForeignKeyPropertyNotFromConvention1 { get; set; } + + [InverseProperty("DependentNavigation")] + [ForeignKey("DependentForeignKeyPropertyNotFromConvention1")] + public PrincipalFkAbstract PrincipalNavigation { get; set; } + } + + public class DerivedDependentFkAbstract : DependentFkAbstract + { + public string DerivedProperty1 { get; set; } + } + + public class PrincipalFkAbstract + { + public int? Key1 { get; set; } + + [InverseProperty("PrincipalNavigation")] + public ICollection DependentNavigation { get; set; } + + public PrincipalFkAbstract() + { + DependentNavigation = new List(); + } + } + + public class DerivedPrincipalFkAbstract : PrincipalFkAbstract + { + public byte[] DerivedProperty1 { get; set; } + } + + public class Dependent144843 + { + public int Id { get; set; } + + public Principal144843 Principal1 { get; set; } + public int Principal1Id { get; set; } + } + + public class Principal144843 + { + public int Id { get; set; } + public ICollection Dependents1 { get; set; } + public Dependent144843 Dependent { get; set; } + } + + public abstract class DependentManyToManySelf + { + public decimal? Key1 { get; set; } + } + + public class DerivedDependentManyToManySelf : DependentManyToManySelf + { + public float DerivedProperty1 { get; set; } + } + + public class DependentSelfRefInverseRequired + { + public string Key1 { get; set; } + public string Key2 { get; set; } + + [InverseProperty("PrincipalNavigation")] + public DependentSelfRefInverseRequired DependentNavigation { get; set; } + + [Required] + public DependentSelfRefInverseRequired PrincipalNavigation { get; set; } + } + + public class Principal144934 + { + public string Key1 { get; set; } + + [InverseProperty("PrincipalNavigation")] + public Dependent144934 DependentNavigation { get; set; } + } + + public class Dependent144934 + { + public string PrincipalNavigationKey1 { get; set; } + + [Required] + public Principal144934 PrincipalNavigation { get; set; } + } + + public class ProductManyToManyTableNaming + { + public int Id { get; set; } + public string Name { get; set; } + public ICollection Suppliers { get; set; } + } + + public class SupplierManyToManyTableNaming + { + public int Id { get; set; } + public string Name { get; set; } + public ICollection Products { get; set; } + } + + public class DependentWithNullableFk + { + public int Id { get; set; } + public string PrincipalNavigationId { get; set; } + public PrincipalWithNullableFk PrincipalNavigation { get; set; } + } + + public class PrincipalWithNullableFk + { + public string Id { get; set; } + public ICollection DependentNavigation { get; set; } + } + + public class DependentWithNullableFkIdentifying + { + public int? Id { get; set; } + public PrincipalWithNullableFkIdentifying PrincipalNavigation { get; set; } + } + + public class PrincipalWithNullableFkIdentifying + { + public int? Id { get; set; } + public DependentWithNullableFkIdentifying DependentNavigation { get; set; } + } + + // Association from base to derived type + + public class Repro150565_Dependent : Repro150565_BaseDependent + { + public decimal? BaseDependentKey1 { get; set; } + public Repro150565_BaseDependent PrincipalNavigation { get; set; } + } + + public class Repro150565_BaseDependent + { + public Guid BaseProperty { get; set; } + public decimal? Key1 { get; set; } + public ICollection DependentNavigation { get; set; } + } + + public class Dependent_6927 + { + public string DependentForeignKeyPropertyNotFromConvention1 { get; set; } + public int Id { get; set; } + + [ForeignKey("DependentForeignKeyPropertyNotFromConvention1")] + public Principal_6927 PrincipalNavigation { get; set; } + } + + public class Principal_6927 + { + public string Key1 { get; set; } + public ICollection DependentNavigation { get; set; } + } + + public class Dependent_162348 + { + public short Key1 { get; set; } + public short? PrincipalNavigationKey1 { get; set; } + public Dependent_162348 PrincipalNavigation { get; set; } + } + + public class Order_181909 + { + public int OrderId { get; set; } + public int CustomerId { get; set; } + public virtual ICollection Lines { get; set; } + } + + public class OrderLine_181909 + { + public int OrderLineId { get; set; } + public int CustomerId { get; set; } + public int OrderId { get; set; } + public virtual Order_181909 Order { get; set; } + public string Description { get; set; } + public decimal Quantity { get; set; } + } + + public class Principal_181909 + { + public int Id { get; set; } + public virtual Dependent_181909 Order { get; set; } + } + + public class Dependent_181909 + { + public string Key { get; set; } + public int Principal_181909Id { get; set; } + + [Required] + public virtual Principal_181909 Order { get; set; } + } + + public class Principal_159001 + { + public int Key1 { get; set; } + } + + public class Dependent_159001a + { + [ForeignKey("PrincipalNavigation")] + public int DependentForeignKeyPropertyNotFromConvention1 { get; set; } + + [Required] + public Principal_159001 PrincipalNavigation { get; set; } + } + + public class Dependent_159001b + { + public int DependentForeignKeyPropertyNotFromConvention1 { get; set; } + + [Required] + [ForeignKey("DependentForeignKeyPropertyNotFromConvention1")] + public Principal_159001 PrincipalNavigation { get; set; } + } + + public class PrincipalWithNav_159001a + { + public int Key1 { get; set; } + + [Required] + public DependentWithNav_159001a DependentNavigation { get; set; } + } + + public class DependentWithNav_159001a + { + [ForeignKey("PrincipalNavigation")] + public int DependentForeignKeyPropertyNotFromConvention1 { get; set; } + + [Required] + public PrincipalWithNav_159001a PrincipalNavigation { get; set; } + } + + public class Dependent_172949 + { + public int Id { get; set; } + + [ForeignKey("PrincipalNavigation")] + public short DependentForeignKeyPropertyNotFromConvention1 { get; set; } + + public Principal_172949 PrincipalNavigation { get; set; } + } + + public class Principal_172949 + { + public short? Id { get; set; } + + [InverseProperty("PrincipalNavigation")] + public ICollection DependentNavigation { get; set; } + } + + public class TableSharing1 + { + public int Id { get; set; } + public int Name { get; set; } + } + + public class TableSharing2 + { + public int Id { get; set; } + public byte[] Picture { get; set; } + public TableSharing1 BackRef { get; set; } + } + + [Table("SharedTable")] + public class TableSharing1A + { + public int Id { get; set; } + public int Name { get; set; } + } + + [Table("SharedTable")] + public class TableSharing2A + { + public int Id { get; set; } + public byte[] Picture { get; set; } + public TableSharing1A BackRef { get; set; } + } + + public class OneToOneResult + { + public int OneToOneResultId { get; set; } + + [ForeignKey("OneToOneResultId")] + public virtual OneToOneResultDetail Detail { get; set; } + } + + public class OneToOneResultDetail + { + [Key] + public int OneToOneResultId { get; set; } + + public DateTime DataDate { get; set; } + } + + #endregion + + #region Model for Dev11 287430 + + [Table("person", Schema = "domain")] + public class Person287430 + { + [Key] + [Column("identifier", TypeName = "nvarchar")] + [StringLength(36, MinimumLength = 36)] + public string Identifier { get; private set; } + + [InverseProperty("Persons")] + public virtual ICollection Roles { get; set; } + } + + [Table("role", Schema = "domain")] + public class Role287430 + { + [Key] + [Column("identifier", TypeName = "nvarchar")] + [StringLength(36, MinimumLength = 36)] + public string Identifier { get; set; } + + [InverseProperty("Roles")] + public virtual ICollection Persons { get; set; } + } + + #endregion + + public class APerson + { + [Key] + public int Id { get; set; } + + [Required] + [DataType(DataType.Text)] + [Display(Name = "Full Name")] + public string Name { get; set; } + + [DataType(DataType.Text)] + [Display(Name = "Biography")] + public string Bio { get; set; } + + public Event Birth { get; set; } + public Event Death { get; set; } + + public APerson Mother { get; set; } + public APerson Father { get; set; } + + public GenderType Gender { get; set; } + } + + public class Event + { + [Key] + public int Id { get; set; } + + [Required] + [DataType(DataType.Date)] + public DateTime Date { get; set; } + + [DataType(DataType.Text)] + public string Location { get; set; } + } + + public enum GenderType + { + Male, + Female + } + + public class Marriage + { + [Key] + public int Id { get; set; } + + [Required] + public Person Husband { get; set; } + + [Required] + public Person Wife { get; set; } + + [Required] + public Event WeddingDay { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/CodeFirst/BasicMappingScenarioTests.cs b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/BasicMappingScenarioTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/CodeFirst/BasicMappingScenarioTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/CodeFirst/BasicMappingScenarioTests.cs index 78921c0d..dbc477a0 100644 --- a/test/EntityFramework/FunctionalTests/CodeFirst/BasicMappingScenarioTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/BasicMappingScenarioTests.cs @@ -1,6339 +1,6339 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests -{ - using System; - using System.Collections.Generic; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; - using System.Data.Entity; - using System.Data.Entity.Core; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.ModelConfiguration; - using System.Data.Entity.ModelConfiguration.Conventions; - using System.Data.Entity.ModelConfiguration.Edm; - using System.Data.Entity.ModelConfiguration.Edm.Services; - using System.Data.Entity.Utilities; - using System.Linq; - using System.Windows.Media; - using FunctionalTests.Model; - using Xunit; - - #region Fixtures - - public class Party - { - public int Id { get; set; } - } - - public class DayRecord - { - public int Id { get; set; } - public Party ReportedBy { get; set; } - public ICollection Forecasts { get; set; } - } - - public class HourlyForecast - { - public int Id { get; set; } - } - - public class TypeClass - { - public int Id { get; set; } - public int IntProp { get; set; } - public string StringProp { get; set; } - public byte[] ByteArrayProp { get; set; } - public DateTime DateTimeProp { get; set; } - public decimal DecimalProp { get; set; } - } - - public abstract class AbsAtBase - { - public int Id { get; set; } - public int Data { get; set; } - } - - public class AbsAtBaseL1 : AbsAtBase - { - public int L1Data { get; set; } - } - - public class AbsAtBaseL2 : AbsAtBaseL1 - { - public int L2Data { get; set; } - } - - public class AbsInMiddle - { - public int Id { get; set; } - public int Data { get; set; } - } - - public abstract class AbsInMiddleL1 : AbsInMiddle - { - public int L1Data { get; set; } - } - - public class AbsInMiddleL2 : AbsInMiddleL1 - { - public int L2Data { get; set; } - } - - public class AssocBase - { - public int Id { get; set; } - public string Name { get; set; } - public string BaseData { get; set; } - public int AssocRelatedBaseId { get; set; } - public AssocRelated AssocRelatedBase { get; set; } - } - - public class AssocDerived : AssocBase - { - public int AssocRelatedId { get; set; } - public string DerivedData1 { get; set; } - public string DerivedData2 { get; set; } - public AssocRelated AssocRelated { get; set; } - } - - public class AssocRelated - { - public int Id { get; set; } - public string Name { get; set; } - public ICollection Deriveds { get; set; } - public ICollection Bases { get; set; } - public AssocDerived RefDerived { get; set; } - public AssocBase RefBase { get; set; } - } - - public class AssocPrincipal - { - public int Id { get; set; } - public AssocDependent DependentNavigation { get; set; } - } - - public class AssocDependent : AssocBaseDependent - { - public AssocPrincipal PrincipalNavigation { get; set; } - } - - public class AssocBaseDependent - { - public string BaseProperty { get; set; } - public int Id { get; set; } - } - - public struct FancyId - { - public int Id1 { get; set; } - public int Id2 { get; set; } - } - - public class Stimulus - { - public int Id { get; set; } - public Brush Background { get; set; } - } - - public class TSItem - { - public int Id { get; set; } - public string Name { get; set; } - public TSItemDetail TSItemDetail { get; set; } - public TSItemDetailDiffKey TSItemDetailDiffKey { get; set; } - public TSItemDetailOverlappingProperty TSItemDetailOverlappingProperty { get; set; } - } - - public class TSItemDetail - { - public int Id { get; set; } - public string Detail { get; set; } - } - - public class TSItemDetailDiffKey - { - public int DiffId { get; set; } - public string Detail { get; set; } - } - - public class TSItemDetailOverlappingProperty - { - public int Id { get; set; } - public string Name { get; set; } - } - - public class TSIAItem - { - public int Id { get; set; } - public string Name { get; set; } - public TSIAItemDetail Detail { get; set; } - } - - public class TSIAItemDetail - { - public string Id { get; set; } - public string Detail { get; set; } - } - - public class TSBase - { - public int Id { get; set; } - public string BaseData { get; set; } - public TSBaseDetail BaseDetail { get; set; } - } - - public class TSBaseDetail - { - public int Id { get; set; } - public string BaseDetail { get; set; } - } - - public class TSDerived : TSBase - { - public string DerivedData { get; set; } - public TSDerivedDetail Detail { get; set; } - } - - public class TSDerivedDetail - { - public int Id { get; set; } - public string DerivedDetail { get; set; } - } - - public class CTBase - { - public int Id { get; set; } - public CTAddress HomeAddress { get; set; } - public CTAddress WorkAddress { get; set; } - } - - public class CTAddress - { - public string Street { get; set; } - public string City { get; set; } - public CTRegion Region { get; set; } - } - - public class CTRegion - { - public string Country { get; set; } - public string Zip { get; set; } - } - - public class TPHBase - { - public int Id { get; set; } - public string BaseData { get; set; } - public int IntProp { get; set; } - public int? NullableIntProp { get; set; } - } - - public class TPHDerived : TPHBase - { - public string DerivedData { get; set; } - } - - public class TPHLeaf : TPHDerived - { - public string LeafData { get; set; } - } - - public class TPHRoot - { - public int Id { get; set; } - public int RootData { get; set; } - } - - public class TPHNodeA : TPHRoot - { - public int AData { get; set; } - } - - public class TPHNodeB : TPHRoot - { - public int BData { get; set; } - } - - public class TPHNodeC : TPHRoot - { - public int CData { get; set; } - } - - // Hybrid tree: - // HybridBase - // / \ - // HybridL1A HybridL1B - // / - // HybridL2 - - public class HybridBase - { - public int Id { get; set; } - public int BaseData { get; set; } - } - - public class HybridL1A : HybridBase - { - public int L1AData { get; set; } - } - - public class HybridL1B : HybridBase - { - public int L1BData { get; set; } - } - - public class HybridL2 : HybridL1A - { - public int L2Data { get; set; } - } - - public class NullablePk - { - public int? Key { get; set; } - public int? Id { get; set; } - } - - public class AnnotatedNullablePk - { - [Key] - public int? Key { get; set; } - } - - public abstract class AbstractBaseEntity - { - public long Id { get; set; } - public abstract string AbstractBaseClassProperty { get; set; } - } - - public class BaseEntity : AbstractBaseEntity - { - public string BaseClassProperty { get; set; } - public virtual string VirtualBaseClassProperty { get; set; } - public override string AbstractBaseClassProperty { get; set; } - } - - public class Unit : BaseEntity - { - public override string VirtualBaseClassProperty { get; set; } - public virtual AbstractBaseEntity Related { get; set; } - } - - public class DifferentUnit : BaseEntity - { - public new string VirtualBaseClassProperty { get; set; } - } - - public class ACrazy - { - public int Id { get; set; } - public string A { get; set; } - } - - public abstract class BCrazy : ACrazy - { - public string B { get; set; } - } - - public class CCrazy : BCrazy - { - public string C { get; set; } - } - - public abstract class DCrazy : CCrazy - { - public string D { get; set; } - } - - public class ECrazy : DCrazy - { - public string E { get; set; } - } - - public class XCrazy : DCrazy - { - public string X { get; set; } - } - - public class IsolatedIsland - { - public int Id { get; set; } - public string Name { get; set; } - } - - public class CKCategory - { - public Guid Key1 { get; set; } - public double? Key2 { get; set; } - } - - public class CKImage - { - public Guid Key1 { get; set; } - public double? Key2 { get; set; } - public string ImageData { get; set; } - } - - public class CKProduct - { - public Guid CKCategoryKey1 { get; set; } - public double CKCategoryKey2 { get; set; } - public CKCategory CKCategory { get; set; } - } - - public class CKDerivedProduct : CKProduct - { - public decimal? DerivedProperty1 { get; set; } - public CKImage Image { get; set; } - } - - public class CKDerivedProduct2 : CKDerivedProduct - { - public decimal? DerivedProperty2 { get; set; } - } - - public class SelfRefDerived : SelfRefBase - { - public float? DependentKey1 { get; set; } - public SelfRefDerived SelfRefNavigation { get; set; } - } - - public class SelfRefBase - { - public string BaseProperty { get; set; } - public float Key1 { get; set; } - } - - public class Repro136761_A - { - public int Repro136761_AId { get; set; } - public string AData { get; set; } - } - - public class Repro136761_B : Repro136761_A - { - public string BData { get; set; } - } - - public class Repro136761_C - { - public int Repro136761_CId { get; set; } - public string CData { get; set; } - public int Repro136761_BId { get; set; } - public Repro136761_B Repro136761_B { get; set; } - } - - // Base association with property discriminator, composite nullable key types - - public class Repro136322_Principal - { - public byte[] Key1 { get; set; } - public long? Key2 { get; set; } - } - - public class Repro136322_Dependent - { - public byte[] PrincipalKey1 { get; set; } - public long PrincipalKey2 { get; set; } - public int Id { get; set; } - public Repro136322_Principal PrincipalNavigation { get; set; } - } - - public class Repro136322_DerivedDependent : Repro136322_Dependent - { - public string DerivedProperty1 { get; set; } - public string Discriminator1 { get; set; } - } - - // Base association, singleton non-nullable key type - - public class Repro136855_Dependent - { - public DateTime Key1 { get; set; } - public int Id { get; set; } - public Repro136855_Principal PrincipalNavigation { get; set; } - } - - public class Repro136855_Principal - { - public DateTime Key1 { get; set; } - } - - public class Repro136855_DerivedDependent : Repro136855_Dependent - { - public bool? DerivedProperty1 { get; set; } - } - - // Derived association - - public class Repro135563_Dependent : Repro135563_BaseDependent - { - public Repro135563_Principal PrincipalNavigation { get; set; } - } - - public class Repro135563_Principal - { - public decimal Key1 { get; set; } - public short? Key2 { get; set; } - public Repro135563_Dependent DependentNavigation { get; set; } - } - - public class Repro135563_BaseDependent - { - public TimeSpan BaseProperty { get; set; } - public int Id { get; set; } - } - - // Three Level Hierarchy, abstract middle, self-ref in middle - - public class ThreeLevelBase - { - public string BaseProperty { get; set; } - public float? Key1 { get; set; } - } - - public abstract class ThreeLevelDerived : ThreeLevelBase - { - public ICollection DependentNavigation { get; set; } - } - - public class ThreeLevelLeaf : ThreeLevelDerived - { - public string DerivedProperty1 { get; set; } - } - - // Two level hierarchy with byte[] prop - - public class ByteBase - { - public int Id { get; set; } - public byte[] ByteData { get; set; } - } - - public class ByteDerived : ByteBase - { - public byte[] DerivedData { get; set; } - } - - public class ByteDerived2 : ByteDerived - { - public byte[] ExtraData { get; set; } - } - - // Association to abstract dependent base type - - public abstract class AbsDep_Dependent - { - public int Id { get; set; } - public short PrincipalKey1 { get; set; } - public AbsDep_Principal PrincipalNavigation { get; set; } - } - - public class AbsDep_Principal - { - public short Key1 { get; set; } - public ICollection DependentNavigation { get; set; } - } - - public class AbsDep_DerivedDependent : AbsDep_Dependent - { - public byte[] DerivedProperty1 { get; set; } - } - - // Association to a principal base type - - public class AssocBase_Department - { - public int Id { get; set; } - public string Name { get; set; } - } - - public class AssocBase_OldDepartment : AssocBase_Department - { - public DateTime ObsoleteDate { get; set; } - } - - public class AssocBase_Employee - { - public int Id { get; set; } - public int AssocBase_DepartmentId { get; set; } - public AssocBase_Department AssocBase_Department { get; set; } - } - - // Two Hierachies with association between subtypes - - public class THABS_BasePrincipal - { - public string BaseProperty { get; set; } - public byte[] Key1 { get; set; } - } - - public class THABS_Principal : THABS_BasePrincipal - { - public ICollection THABS_DependentNavigation { get; set; } - } - - public class THABS_Dependent - { - public int Id { get; set; } - public THABS_Principal THABS_PrincipalNavigation { get; set; } - } - - public class THABS_DerivedDependent : THABS_Dependent - { - public DateTime DerivedProperty1 { get; set; } - } - - // Self-ref on derived type - - public class SRBase - { - public string BaseProperty { get; set; } - public float? Key1 { get; set; } - public DateTime Key2 { get; set; } - } - - public class SRDerived : SRBase - { - public ICollection Navigation { get; set; } - } - - // Table splitting on base...used with TPC - - public class Repro140106_Vehicle - { - public string Repro140106_VehicleId { get; set; } - public string Name { get; set; } - public Repro140106_Model Model { get; set; } - } - - public class Repro140106_Car : Repro140106_Vehicle - { - public string Type { get; set; } - } - - public class Repro140106_Model - { - public string Repro140106_ModelId { get; set; } - public decimal Description { get; set; } - public Repro140106_Vehicle Repro140106_Vehicle { get; set; } - } - - // Table splitting on base...used with TPT - - public class Repro140107_Vehicle - { - public int? Repro140107_VehicleId { get; set; } - public short? Name { get; set; } - public Repro140107_Model Repro140107_Model { get; set; } - } - - public class Repro140107_Car : Repro140107_Vehicle - { - public long Type { get; set; } - } - - public class Repro140107_Model - { - public int? Repro140107_ModelId { get; set; } - public bool Description { get; set; } - public Repro140107_Vehicle Repro140107_Vehicle { get; set; } - } - - // Hybrid mapping model - - public class Entity1 - { - public short? Entity1_Col1 { get; set; } - public DateTime Entity1_Col2 { get; set; } - public byte[] Entity1_Col3 { get; set; } - public string Id { get; set; } - } - - public class Entity2 : Entity1 - { - public DateTime? Entity2_Col1 { get; set; } - } - - public class Entity3 : Entity1 - { - public string Entity3_Col1 { get; set; } - public DateTimeOffset Entity3_Col2 { get; set; } - } - - public class Entity4 : Entity1 - { - public long? Entity4_Col1 { get; set; } - public string Entity4_Col2 { get; set; } - } - - public class Entity5 : Entity2 - { - public bool? Entity5_Col1 { get; set; } - public DateTime Entity5_Col2 { get; set; } - public TimeSpan Entity5_Col3 { get; set; } - public decimal? Entity5_Col4 { get; set; } - public DateTime Entity5_Col5 { get; set; } - } - - // Hybrid Scenario - - public class Repro137329_A1 - { - [DatabaseGenerated(DatabaseGeneratedOption.None)] - public int Id { get; set; } - - public string Age1 { get; set; } - public string Name { get; set; } - } - - public class Repro137329_A2 : Repro137329_A1 - { - public string Age2 { get; set; } - } - - public class Repro137329_A3 : Repro137329_A2 - { - public string Age3 { get; set; } - } - - public class Repro137329_A4 : Repro137329_A1 - { - public string Age4 { get; set; } - } - - // Property Discriminator - - public class Repro143236_Dependent - { - public int Id { get; set; } - } - - public class Repro143236_DerivedDependent : Repro143236_Dependent - { - public DateTime DerivedProperty1 { get; set; } - public double DiscriminatorNotNull { get; set; } - } - - // abstract base class - - public abstract class Repro143662_Party - { - public int Id { get; set; } - public string Name { get; set; } - } - - public class Repro143662_Agency : Repro143662_Party - { - public int Reputation { get; set; } - } - - public class Repro143662_Person : Repro143662_Party - { - public string Address { get; set; } - } - - // IA relationship between subtypes - - public class Repro109944_BaseEntity - { - public int ID { get; set; } - public string Title { get; set; } - } - - public class Repro109944_Entity1 : Repro109944_BaseEntity - { - public string SomeProperty { get; set; } - public Repro109944_Entity2 Repro109944_Entity2 { get; set; } - public int Repro109944_Entity2ID { get; set; } - } - - public class Repro109944_Entity2 : Repro109944_BaseEntity - { - public string SomeProperty { get; set; } - } - - // Base type to base type FK association - - public class Repro142961_Dependent - { - public decimal Key1 { get; set; } - public int Id { get; set; } - public Repro142961_Principal PrincipalNavigation { get; set; } - } - - public class Repro142961_Principal - { - public decimal Key1 { get; set; } - } - - public class Repro142961_DerivedDependent : Repro142961_Dependent - { - public Guid DerivedProperty1 { get; set; } - } - - public class Repro142961_DerivedPrincipal : Repro142961_Principal - { - public long DerivedProperty1 { get; set; } - } - - // Abstract base with discriminator - - public abstract class Repro142666_Dependent - { - public bool DependentForeignKeyPropertyNotFromConvention1 { get; set; } - public int Id { get; set; } - } - - public class Repro142666_DerivedDependent : Repro142666_Dependent - { - public string DerivedProperty1 { get; set; } - } - - // Simple three level hierarchy - - public class Repro143127_EntityA - { - public int Id { get; set; } - public string Description { get; set; } - } - - public class Repro143127_EntityB : Repro143127_EntityA - { - public int Count { get; set; } - public string Info { get; set; } - } - - public class Repro143127_EntityC : Repro143127_EntityB - { - public int P1 { get; set; } - } - - // IA from an abstract non-root type - - public abstract class Repro142682_Dependent : Repro142682_BaseDependent - { - public DateTime DependentForeignKeyPropertyNotFromConvention1 { get; set; } - public Repro142682_Principal PrincipalNavigation { get; set; } - } - - public class Repro142682_Principal - { - public DateTime? Key1 { get; set; } - public ICollection DependentNavigation { get; set; } - } - - public class Repro142682_BaseDependent - { - public long? BaseProperty { get; set; } - public int Id { get; set; } - } - - public class Repro142682_DerivedDependent : Repro142682_Dependent - { - public decimal? DerivedProperty1 { get; set; } - } - - // Simple hierarchy for TPC property renaming - - public class Repro144459_Product - { - public int Id { get; set; } - public string Name { get; set; } - } - - public class Repro144459_DiscontinuedProduct : Repro144459_Product - { - public DateTime DiscontinuedOn { get; set; } - } - - public class Repro144459_ClearanceProduct : Repro144459_Product - { - public decimal SalePrice { get; set; } - } - - // Abstract base as principal of FK association - - public abstract class Repro110459_Customer - { - public virtual Guid Id { get; set; } - public virtual string Name { get; set; } - public virtual ICollection Orders { get; set; } - } - - public class Repro110459_Account : Repro110459_Customer - { - public virtual string AccountNumber { get; set; } - } - - public class Repro110459_Contact : Repro110459_Customer - { - public virtual string FirstName { get; set; } - public virtual string LastName { get; set; } - } - - public class Repro110459_Order - { - public Guid Id { get; set; } - public string Name { get; set; } - public Repro110459_Customer BillToCustomer { get; set; } - public Guid BillToCustomerId { get; set; } - } - - // Multiple relationships at various points in hierarchy with TPT - - public class Repro109916_BaseEntity - { - [Key] - public int ID { get; set; } - - public string Title { get; set; } - - public Repro109916_Collectible Parent { get; set; } - public virtual ICollection Children { get; set; } - } - - public class Repro109916_Collectible - { - public int ID { get; set; } - } - - public class Repro109916_SomeEntity : Repro109916_BaseEntity - { - public byte Units { get; set; } - - public string Watermark { get; set; } - public Repro109916_BaseEntity BaseEntity { get; set; } - } - - public class Repro109916_SomeMore : Repro109916_BaseEntity - { - [Column("Watermark")] - public string Watermark { get; set; } - - public string Denomination { get; set; } - - // These cause the problem: - public Repro109916_Product Product { get; set; } - public Repro109916_SomeEntity SomeEntity { get; set; } - } - - public class Repro109916_Product - { - [Key] - public int ID { get; set; } - - public string Name { get; set; } - } - - // Three level hierarchy with abstract middle - - public class Repro147822_EntityA - { - public int Id { get; set; } - public byte[] Photo { get; set; } - public string Description { get; set; } - public string Name { get; set; } - } - - public abstract class Repro147822_EntityB : Repro147822_EntityA - { - public string Details { get; set; } - } - - public class Repro147822_EntityC : Repro147822_EntityB - { - public string Color { get; set; } - } - - // Two level hierarchy with abstract root type - - public abstract class Repro147906_EntityA1 - { - public int Id { get; set; } - public byte[] Photo { get; set; } - public string Description { get; set; } - public string Name { get; set; } - } - - public class Repro147906_EntityA1_1 : Repro147906_EntityA1 - { - public string Property1 { get; set; } - public string Property2 { get; set; } - public string Property3 { get; set; } - } - - public class Repro147906_EntityA1_2 : Repro147906_EntityA1 - { - public string Property4 { get; set; } - public string Property5 { get; set; } - public string Property6 { get; set; } - } - - // Complex Type on a base entity - - public class Repro148415_EntityC1 - { - public int Id { get; set; } - public Repro148415_ComplexTypeC1 ComplexProperty1 { get; set; } - public float Property2 { get; set; } - } - - public class Repro148415_EntityC1_1 : Repro148415_EntityC1 - { - public float Property3 { get; set; } - public float Property4 { get; set; } - } - - public class Repro148415_ComplexTypeC1 - { - public int P1 { get; set; } - public float P2 { get; set; } - } - - // Table splitting on base used for TPC - - public class TPCVehicle - { - public string TPCVehicleId { get; set; } - public string Name { get; set; } - public TPCModel TPCModel { get; set; } - } - - public class TPCCar : TPCVehicle - { - public string Type { get; set; } - } - - public class TPCModel - { - public string TPCModelId { get; set; } - public decimal Description { get; set; } - public TPCVehicle TPCVehicle { get; set; } - } - - // Three level hierarchy for entity splitting - - public class Repro147929_EntityB1 - { - public int Id { get; set; } - public byte[] Photo { get; set; } - public string Description { get; set; } - public string Name { get; set; } - } - - public class Repro147929_EntityB1_1 : Repro147929_EntityB1 - { - public string Property1 { get; set; } - public string Property2 { get; set; } - public string Property3 { get; set; } - } - - public class Repro147929_EntityB1_1_1 : Repro147929_EntityB1_1 - { - public string Property4 { get; set; } - public string Property5 { get; set; } - public string Property6 { get; set; } - } - - // Three level hierarchy with association between abstract middle types - - public class Repro150248_BaseDependent - { - public DateTime? BaseProperty { get; set; } - public string Key1 { get; set; } - } - - public abstract class Repro150248_Dependent : Repro150248_BaseDependent - { - public string PrincipalKey1 { get; set; } - public Repro150248_Principal PrincipalNavigation { get; set; } - } - - public class Repro150248_DerivedDependent : Repro150248_Dependent - { - public decimal? DerivedProperty1 { get; set; } - } - - public abstract class Repro150248_Principal : Repro150248_BaseDependent - { - public ICollection DependentNavigation { get; set; } - } - - public class Repro150248_DerivedPrincipal : Repro150248_Principal - { - public string DerivedProperty1 { get; set; } - } - - // 1:0..1 IA on derived dependent - - public class Repro150634_BaseDependent - { - public string BaseProperty { get; set; } - public Guid? Key1 { get; set; } - public Guid? Key2 { get; set; } - } - - public class Repro150634_Dependent : Repro150634_BaseDependent - { - public Int32 DependentForeignKeyPropertyNotFromConvention1 { get; set; } - public Repro150634_Principal PrincipalNavigation { get; set; } - } - - public class Repro150634_DerivedDependent : Repro150634_Dependent - { - public Int32 ExtraProp { get; set; } - } - - public class Repro150634_Principal - { - public int Id { get; set; } - public Repro150634_Dependent DependentNavigation { get; set; } - } - - // 0..1:* IA to derived principal - - public class Repro165020_BaseDependent - { - public int Id { get; set; } - } - - public class Repro165020_DerivedDependent : Repro165020_BaseDependent - { - public Repro165020_DerivedPrincipal PrincipalNavigation { get; set; } - } - - public class Repro165020_BasePrincipal - { - public DateTime? Key1 { get; set; } - public decimal Key2 { get; set; } - } - - public class Repro165020_DerivedPrincipal : Repro165020_BasePrincipal - { - public ICollection DependentNavigation { get; set; } - } - - // composite key with property ordering - - public class EntityWithCompositePK - { - [Column(Order = 1)] - public string Key1 { get; set; } - - [Column(Order = 2)] - public int Key2 { get; set; } - - [Column(Order = 3)] - public byte[] Property1 { get; set; } - - [Column(Order = 4)] - public string Property2 { get; set; } - } - - // Hierarchy with abstract base and FK on base - - public abstract class Repro150248_Dependent_2 - { - public string Key1 { get; set; } - public Repro150248_Principal_2 PrincipalNavigation { get; set; } - } - - public class Repro150248_Principal_2 : Repro150248_BasePrincipal_2 - { - public Repro150248_Dependent_2 DependentNavigation { get; set; } - } - - public class Repro150248_DerivedDependent_2 : Repro150248_Dependent_2 - { - public byte? DependentDerivedProperty1 { get; set; } - } - - public class Repro150248_BasePrincipal_2 - { - public string Key1 { get; set; } - } - - // hierarchy with middle type given a table name - - public class Repro143351_A1 - { - [DatabaseGenerated(DatabaseGeneratedOption.None)] - public string Id { get; set; } - - public string A1Col1 { get; set; } - public byte[] A1Col2 { get; set; } - } - - [Table("NewA2TableName")] - public class Repro143351_A2 : Repro143351_A1 - { - public byte[] A2Col1 { get; set; } - } - - public class Repro143351_A3 : Repro143351_A2 - { - public DateTime A3Col1 { get; set; } - } - - public class Repro143351_A4 : Repro143351_A1 - { - public long A4Col1 { get; set; } - } - - // self reference from derived to abstract base - - public class Repro135563_2_Dependent : Repro135563_2_BaseDependent - { - public Repro135563_2_BaseDependent PrincipalNavigation { get; set; } - } - - public abstract class Repro135563_2_BaseDependent - { - public Guid BaseProperty { get; set; } - public short Key1 { get; set; } - public ICollection DependentNavigation { get; set; } - } - - public class Repro135563_2_Other : Repro135563_2_BaseDependent - { - public string OtherData { get; set; } - } - - // self reference from derived to concrete base - - public class Repro135563_3_Dependent : Repro135563_3_BaseDependent - { - public Repro135563_3_BaseDependent PrincipalNavigation { get; set; } - } - - public class Repro135563_3_BaseDependent - { - public Guid BaseProperty { get; set; } - public short Key1 { get; set; } - public ICollection DependentNavigation { get; set; } - } - - // Basic Inheritance - - public class EntityL - { - public int Id { get; set; } - public string Property1 { get; set; } - public byte[] Property2 { get; set; } - } - - public class EntityL_1 : EntityL - { - public string Property3 { get; set; } - public byte[] Property4 { get; set; } - } - - // abstract at base for splitting - - public abstract class AbsBaseSplit - { - public int Id { get; set; } - public string Prop1 { get; set; } - public string Prop2 { get; set; } - } - - public class AbsDerivedSplit : AbsBaseSplit - { - public string Prop3 { get; set; } - } - - // abstract in middle for splitting - - public class EntityN - { - public int Id { get; set; } - public int Property1 { get; set; } - public int Property1_1 { get; set; } - } - - public abstract class EntityN_1 : EntityN - { - public int Property2 { get; set; } - public int Property2_1 { get; set; } - } - - public class EntityN_1_1 : EntityN_1 - { - public int Property3_1 { get; set; } - public int Property3 { get; set; } - } - - public abstract class BaseNote - { - public virtual Guid Id { get; set; } - public virtual string Description { get; set; } - } - - public class NoteWithRelationship1 : BaseNote - { - public virtual TargetEmployee TargetEmployee { get; set; } - } - - public class NoteWithRelationship2 : BaseNote - { - public virtual TargetEmployee TargetEmployee { get; set; } - } - - public abstract class BaseEmployee - { - public Guid Id { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } - } - - public class TargetEmployee : BaseEmployee - { - public DateTime? DateOfBirth { get; set; } - } - - // Reuse complex type in derived classes - - [Table("Product")] - public abstract class VehicleProduct - { - [Key] - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] - public int Id { get; set; } - } - - [Table("RedVehicle")] - public abstract class RedVehicle : VehicleProduct - { - public VehicleType VehicleType { get; set; } //The same name of complex type - } - - [Table("BlueVehicle")] - public abstract class BlueVehicle : VehicleProduct - { - public VehicleType VehicleType { get; set; } //The same name of complex type - } - - [Table("RedCar")] - public class RedCar : RedVehicle - { - } - - [Table("BlueCar")] - public class BlueCar : BlueVehicle - { - } - - [ComplexType] - public class VehicleType - { - [Required] - public string Model { get; set; } - } - - #endregion - - public sealed class BasicMappingScenarioTests : TestBase - { - [Fact] - public void Can_specify_default_schema() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.HasDefaultSchema("foo"); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(1, databaseMapping.Database.GetEntitySets().Count(es => es.Schema == "foo")); - } - - [Fact] - public void Can_specify_default_schema_and_explicit_schemas() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.HasDefaultSchema("foo"); - modelBuilder.Entity(); - modelBuilder.Entity().ToTable("days", "bar"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(2, databaseMapping.Database.GetEntitySets().Count(es => es.Schema == "foo")); - Assert.Equal(1, databaseMapping.Database.GetEntitySets().Count(es => es.Schema == "bar")); - } - - [Fact] - public void Can_specify_default_schema_and_explicit_dbo_schema() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.HasDefaultSchema("foo"); - modelBuilder.Entity(); - modelBuilder.Entity().ToTable("days", "dbo"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(2, databaseMapping.Database.GetEntitySets().Count(es => es.Schema == "foo")); - Assert.Equal(1, databaseMapping.Database.GetEntitySets().Count(es => es.Schema == "dbo")); - } - - #region Misc - - [Fact] - public void Has_max_length_should_work_when_no_max_length_convention() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Conventions.Remove(); - modelBuilder.Entity().HasKey(a => a.StringProp); - modelBuilder.Entity().Property(t => t.StringProp).HasMaxLength(42); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(t => t.StringProp).FacetEqual(true, f => f.IsUnicode); - databaseMapping.Assert(t => t.StringProp).FacetEqual(false, f => f.IsFixedLength); - databaseMapping.Assert(t => t.StringProp).FacetEqual(42, f => f.MaxLength); - databaseMapping.Assert(t => t.StringProp).DbEqual(42, f => f.MaxLength); - } - - [Fact] - public void Should_be_able_to_call_simple_has_key_twice() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey(a => a.Street); - modelBuilder.Entity().HasKey(a => a.Street); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Should_be_able_to_ignore_property_on_base_class() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Ignore(b => b.BaseClassProperty); - modelBuilder.Entity().Ignore(b => b.VirtualBaseClassProperty); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.False( - databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) - .Any(p => p.Name == "BaseClassProperty")); - Assert.False( - databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) - .Any(p => p.Name == "VirtualBaseClassProperty")); - } - - [Fact] - public void Ignore_property_on_base_class_and_derived_class_throws() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Ignore(b => b.BaseClassProperty); - modelBuilder.Entity().Ignore(b => b.VirtualBaseClassProperty); - modelBuilder.Entity().Ignore(b => b.BaseClassProperty); - modelBuilder.Entity().Ignore(b => b.VirtualBaseClassProperty); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage( - "CannotIgnoreMappedBaseProperty", - "BaseClassProperty", "FunctionalTests.Unit", - "FunctionalTests.BaseEntity"); - } - - [Fact] - public void Should_be_able_to_ignore_property_on_abstract_base_class() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Ignore(b => b.AbstractBaseClassProperty); - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.False( - databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) - .Any(p => p.Name == "AbstractBaseClassProperty")); - } - - [Fact] - public void Ignoring_mapped_base_class_property_throws() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().Ignore(u => u.BaseClassProperty); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage( - "CannotIgnoreMappedBaseProperty", - "BaseClassProperty", "FunctionalTests.Unit", - "FunctionalTests.BaseEntity"); - } - - [Fact] - public void Should_be_able_to_ignore_unmapped_base_class_property() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Entity().Ignore(u => u.BaseClassProperty); - modelBuilder.Entity().Ignore(u => u.VirtualBaseClassProperty); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.False( - databaseMapping.Model.EntityTypes.Single().Properties.Any( - p => p.Name == "BaseClassProperty")); - Assert.False( - databaseMapping.Model.EntityTypes.Single().Properties.Any( - p => p.Name == "VirtualBaseClassProperty")); - } - - [Fact] - public void Ignoring_new_property_with_same_name_as_in_mapped_base_class_throws() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().Ignore(u => u.VirtualBaseClassProperty); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage( - "CannotIgnoreMappedBaseProperty", - "VirtualBaseClassProperty", "FunctionalTests.DifferentUnit", - "FunctionalTests.BaseEntity"); - } - - [Fact] - public void Ignoring_overriden_mapped_base_class_property_throws() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Ignore(u => u.VirtualBaseClassProperty); - modelBuilder.Entity(); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage( - "CannotIgnoreMappedBaseProperty", - "VirtualBaseClassProperty", "FunctionalTests.Unit", - "FunctionalTests.BaseEntity"); - } - - [Fact] - public void Should_be_able_to_configure_nullable_ospace_key() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey(n => n.Key); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Should_be_able_to_annotate_nullable_ospace_key() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Should_be_able_to_discover_nullable_ospace_key() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Explicitly_configured_entity_set_name_is_not_pluralized() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasEntitySetName("Customer"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal("Customer", databaseMapping.Model.Containers.Single().EntitySets.Single().Name); - } - - [Fact] - public void Explicitly_configured_entity_set_names_are_uniqued() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasEntitySetName("Foo"); - modelBuilder.Entity().HasEntitySetName("Foo"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal("Foo", databaseMapping.Model.Containers.Single().EntitySets.First().Name); - Assert.Equal("Foo1", databaseMapping.Model.Containers.Single().EntitySets.Last().Name); - } - - [Fact] - public void Build_model_for_type_with_framework_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - - // WPF classes invalid - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Build_model_for_type_with_internal_member_to_configure_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity() - .HasKey(th => th.TransactionID); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); - } - - [Fact] - public void Build_model_for_type_with_configured_internal_members() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .HasKey(th => th.TransactionID); - modelBuilder.Entity() - .HasRequired(th => th.Product); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo, typeof(Product)); - - Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); - } - - [Fact] - public void Build_model_for_a_single_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_after_customizing_property_column_name() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Property(c => c.AccountNumber).HasColumnName("acc_no"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_after_customizing_property_column_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Property(c => c.AccountNumber).HasColumnType("NVARCHAR"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_a_single_type_with_a_nullable_key() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_a_single_type_with_a_composite_key() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasKey( - sc => new - { - sc.ContactID, - sc.CustomerID - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_a_single_type_with_a_string_key() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_default_tph_mapping() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - #endregion - - #region ToTable Tests - - [Fact] - public void ToTable_on_single_entity_changes_table_name() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("tbl_sp"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert("tbl_sp"); - } - - [Fact] - public void ToTable_on_single_entity_with_association_changes_table_name() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("tbl_sp"); - modelBuilder.Entity().HasOptional(o => o.SalesPerson).WithRequired(e => e.Employee); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert("tbl_sp"); - } - - #endregion - - #region ToTable Schema Tests - - [Fact] - public void Build_model_with_table_schema_configured() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("tbl_sp", "sales"); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "sales")); - Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "dbo")); - } - - [Fact] - public void Build_model_with_dotted_table_name_configured() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("sales.tbl_sp"); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "sales")); - Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "dbo")); - } - - [Fact] - public void Build_model_with_dotted_table_name_and_dotted_schema_configured() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("tbl_sp", "sales.A.B"); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "sales.A.B")); - Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "dbo")); - } - - [Fact] - public void Relationship_with_table_in_different_schema_works() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity().Map(m => m.ToTable("HourlyForecasts", "dbx")); - - var databaseMapping = BuildMapping(modelBuilder); - - var mws = databaseMapping.ToMetadataWorkspace(); - - var storeCollection = mws.GetItemCollection(DataSpace.SSpace); - Assert.Equal( - 2, - (storeCollection.GetItem("CodeFirstDatabase")).BaseEntitySets.OfType - ().Count()); - } - - #endregion - - #region Basic TPH Tests - - [Fact] - public void Requires_value_can_change_discriminator_column_name_and_use_strings() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue("a"); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("b"); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("c"); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert() - .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); - databaseMapping.Assert("TPHBases") - .Column("MyDisc") - .DbEqual(DatabaseMappingGenerator.DiscriminatorMaxLength, f => f.MaxLength); - databaseMapping.AssertMapping("TPHBases", false) - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "a"); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "b"); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "c"); - } - - [Fact] - public void ToTable_on_root_abstract_class_renames_TPH_hierarchy() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Foo"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Foo"); - } - - [Fact] - // Regression test for Dev 11 bug 136256 - public void Requires_value_can_change_discriminator_column_name_and_use_strings_on_derived_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue("a"); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("c"); }); - - modelBuilder.Entity().Map(mc => { mc.Requires("MyDisc").HasValue("b").HasColumnType("ntext"); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert() - .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); - databaseMapping.Assert("TPHBases") - .Column("MyDisc") - .DbEqual(null, f => f.MaxLength); - databaseMapping.AssertMapping("TPHBases", false) - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "a"); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "b"); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "c"); - } - - [Fact] - // Regression test for Dev 11 bug 142718 - public void Requires_value_can_change_discriminator_column_name_and_nullability() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue("a").IsOptional(); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("b"); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("c"); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert() - .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); - databaseMapping.Assert("TPHBases") - .Column("MyDisc") - .DbEqual(true, f => f.Nullable) - .DbEqual(DatabaseMappingGenerator.DiscriminatorMaxLength, f => f.MaxLength); - databaseMapping.AssertMapping("TPHBases", false) - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "a"); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "b"); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "c"); - } - - [Fact] - public void Requires_value_can_change_discriminator_column_name_and_nullability_on_derived_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue("a"); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("b").IsOptional(); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("c"); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert() - .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); - databaseMapping.Assert("TPHBases") - .Column("MyDisc") - .DbEqual(true, f => f.Nullable) - .DbEqual(DatabaseMappingGenerator.DiscriminatorMaxLength, f => f.MaxLength); - databaseMapping.AssertMapping("TPHBases", false) - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "a"); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "b"); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "c"); - } - - [Fact] - public void Requires_throws_on_conflicting_nullability() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue("a").IsRequired(); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("b").IsOptional(); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("c"); }); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - // Regression test for Dev 11 bug 136596 - public void Requires_value_works_with_table_annotation() - { - using (var tphBaseConfiguration = new DynamicTypeDescriptionConfiguration()) - { - tphBaseConfiguration.TypeAttributes = new[] { new TableAttribute("MegaTPH") }; - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue("a"); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("b"); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("c"); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert() - .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); - databaseMapping.Assert("MegaTPH") - .Column("MyDisc") - .DbEqual(DatabaseMappingGenerator.DiscriminatorMaxLength, f => f.MaxLength); - databaseMapping.AssertMapping("MegaTPH", false) - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "a"); - databaseMapping.AssertMapping("MegaTPH") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "b"); - databaseMapping.AssertMapping("MegaTPH") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "c"); - } - } - - [Fact] - public void Requires_value_can_change_discriminator_column_name_and_use_int16() - { - Requires_value_can_change_discriminator_column_name((Int16)1, (Int16)2, (Int16)3); - } - - [Fact] - public void Requires_value_can_change_discriminator_column_name_and_use_int32() - { - Requires_value_can_change_discriminator_column_name(1, 2, 3); - } - - [Fact] - public void Requires_value_can_change_discriminator_column_name_and_use_int64() - { - Requires_value_can_change_discriminator_column_name(1, 2, (Int64)3); - } - - [Fact] - public void Requires_value_can_change_discriminator_column_name_and_use_byte() - { - Requires_value_can_change_discriminator_column_name((byte)1, (byte)2, (byte)3); - } - - [Fact] - public void Requires_value_can_change_discriminator_column_name_and_use_sbyte() - { - sbyte a = 1, b = 2, c = 3; - - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue(a).HasColumnType("tinyint"); }) - .Map(mc => { mc.Requires("MyDisc").HasValue(b); }) - .Map(mc => { mc.Requires("MyDisc").HasValue(c); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert() - .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); - databaseMapping.AssertMapping("TPHBases", false) - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", a); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", b); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", c); - } - - [Fact] - public void Requires_value_can_change_discriminator_column_name_and_use_bool() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue(true); }) - .Map(mc => { mc.Requires("MyDisc").HasValue(false); }); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert() - .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "MyDisc"); - databaseMapping.AssertMapping("TPHBases", false) - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", true); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", false); - } - - [Fact] - public void Requires_throws_on_decimal_discriminator() - { - Assert.Throws( - () => - Requires_value_can_change_discriminator_column_name( - (decimal)1.0, - (decimal)2.0, - (decimal)3.0)); - } - - [Fact] - public void Requires_throws_on_DateTime_discriminator() - { - Assert.Throws( - () => - Requires_value_can_change_discriminator_column_name( - new DateTime(2011, 1, 1), new DateTime(2011, 1, 2), - new DateTime(2011, 1, 3))); - } - - [Fact] - public void Requires_throws_on_TimeSpan_discriminator() - { - Assert.Throws( - () => - Requires_value_can_change_discriminator_column_name( - new TimeSpan(1), - new TimeSpan(2), - new TimeSpan(3))); - } - - [Fact] - public void Requires_throws_on_a_nonPrimitive_discriminator() - { - Assert.Throws( - () => - Requires_value_can_change_discriminator_column_name( - new FancyId - { - Id1 = 1, - Id2 = 1 - }, - new FancyId - { - Id1 = 2, - Id2 = 2 - }, new FancyId - { - Id1 = 3, - Id2 = 3 - })); - } - - [Fact] - // Regression test for Dev11 Bug 136810 - public void Requires_can_only_be_called_once_per_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue("a"); }); - - Assert.Throws( - () => - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue("b"); })); - } - - [Fact] - public void Requires_throws_on_mixed_valid_discriminator_types() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue(1); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("yo"); }); - modelBuilder.Ignore(); - - Assert.Throws(() => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Requires_throws_on_ambiguous_valid_discriminator_types() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue(1); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("2"); }); - modelBuilder.Ignore(); - - Assert.Throws(() => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Requires_throws_on_mixed_valid_discriminator_types_when_column_type_is_set() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue(1).HasColumnType("int"); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("yo"); }); - modelBuilder.Ignore(); - - Assert.Throws( - () => - modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Requires_throws_on_conflicting_valid_discriminator_types_when_column_type_is_set() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue(1).HasColumnType("int"); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("yo").HasColumnType("ntext"); }); - modelBuilder.Ignore(); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - private void Requires_value_can_change_discriminator_column_name(T a, T b, T c) where T : struct - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue(a); }) - .Map(mc => { mc.Requires("MyDisc").HasValue(b); }) - .Map(mc => { mc.Requires("MyDisc").HasValue(c); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert() - .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); - databaseMapping.AssertMapping("TPHBases", false) - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", a); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", b); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", c); - } - - [Fact] - public void Requires_value_can_be_null_with_nullable_string() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("MyDisc").HasValue("a"); }) - .Map(mc => { mc.Requires("MyDisc").HasValue("b"); }) - .Map(mc => { mc.Requires("MyDisc").HasValue(null); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert() - .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); - databaseMapping.Assert("TPHBases") - .Column("MyDisc") - .DbEqual(DatabaseMappingGenerator.DiscriminatorMaxLength, f => f.MaxLength); - databaseMapping.AssertMapping("TPHBases", false) - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "a"); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "b"); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasNullabilityColumnCondition("MyDisc", true); - } - - [Fact] - public void NotNull_condition_does_not_require_IsRequired_property() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mc => mc.Requires("DerivedData").HasValue(null)); - modelBuilder.Entity().Map(mc => mc.Requires(b => b.DerivedData).HasValue()); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - Assert.False( - databaseMapping.Model.EntityTypes.Single(et => et.Name == "TPHDerived").Properties.Single( - p => p.Name == "DerivedData").Nullable); - - databaseMapping.Assert() - .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData"); - databaseMapping.Assert("TPHBases") - .Column("DerivedData") - .DbEqual(null, f => f.MaxLength); - databaseMapping.AssertMapping("TPHBases", false) - .HasNoPropertyConditions() - .HasNullabilityColumnCondition("DerivedData", false); - databaseMapping.AssertMapping("TPHBases", false) - .HasNoPropertyConditions() - .HasNullabilityColumnCondition("DerivedData", true); - } - - [Fact] - public void NotNull_condition_works_with_IsRequired() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mc => mc.Requires("DerivedData").HasValue(null)); - modelBuilder.Entity().Map(mc => mc.Requires(b => b.DerivedData).HasValue()); - modelBuilder.Entity().Property(b => b.DerivedData).IsRequired(); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - Assert.False( - databaseMapping.Model.EntityTypes.Single(et => et.Name == "TPHDerived").Properties.Single( - p => p.Name == "DerivedData").Nullable); - databaseMapping.Assert() - .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData"); - databaseMapping.Assert("TPHBases") - .Column("DerivedData") - .DbEqual(null, f => f.MaxLength); - databaseMapping.AssertMapping("TPHBases") - .HasNoPropertyConditions() - .HasNullabilityColumnCondition("DerivedData", false); - databaseMapping.AssertMapping("TPHBases", false) - .HasNoPropertyConditions() - .HasNullabilityColumnCondition("DerivedData", true); - } - - [Fact] - public void NotNull_condition_on_derived_with_abstract_base_in_TPH_and_base_condition_ignored() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mc => mc.Requires("L1Data").HasValue(null)); - modelBuilder.Entity().Map(mc => mc.Requires(e => e.L1Data).HasValue()); - modelBuilder.Entity().Property(b => b.L1Data); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.AssertMapping("AbsAtBases").HasNoColumnConditions(); - databaseMapping.AssertMapping("AbsAtBases").HasNullabilityColumnCondition("L1Data", false); - } - - [Fact] - public void NotNull_condition_with_IsOptional_throws() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mc => mc.Requires("DerivedData").HasValue(null)); - modelBuilder.Entity().Map(mc => mc.Requires(b => b.DerivedData).HasValue()); - modelBuilder.Entity().Property(b => b.DerivedData).IsOptional(); - modelBuilder.Ignore(); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Tree_hierarchy_can_map_to_same_table() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - mc => - { - mc.Requires("MyDisc").HasValue("a"); - mc.ToTable("Woof"); - }) - .Map( - mc => - { - mc.Requires("MyDisc").HasValue("b"); - mc.ToTable("Woof"); - }) - .Map( - mc => - { - mc.Requires("MyDisc").HasValue("c"); - mc.ToTable("Woof"); - }); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Woof") - .HasColumns("Id", "RootData", "AData", "BData", "MyDisc"); - databaseMapping.Assert("Woof") - .Column("MyDisc") - .DbEqual(DatabaseMappingGenerator.DiscriminatorMaxLength, f => f.MaxLength); - databaseMapping.AssertMapping("Woof", false) - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "a"); - databaseMapping.AssertMapping("Woof") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "b"); - databaseMapping.AssertMapping("Woof") - .HasNoPropertyConditions() - .HasColumnCondition("MyDisc", "c"); - } - - [Fact] - public void Changing_only_root_table_moves_all_TPH_hierarchy() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.ToTable("Woof"); }); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Woof") - .HasColumns("Id", "RootData", "AData", "BData", "Discriminator"); - databaseMapping.Assert("Woof") - .Column("Discriminator") - .DbEqual(DatabaseMappingGenerator.DiscriminatorMaxLength, f => f.MaxLength); - databaseMapping.AssertMapping("Woof", false) - .HasNoPropertyConditions() - .HasColumnCondition("Discriminator", "TPHRoot"); - databaseMapping.AssertMapping("Woof") - .HasNoPropertyConditions() - .HasColumnCondition("Discriminator", "TPHNodeA"); - databaseMapping.AssertMapping("Woof") - .HasNoPropertyConditions() - .HasColumnCondition("Discriminator", "TPHNodeB"); - } - - [Fact] - public void Null_discriminator_value_gets_string_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("disc").HasValue(null); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert() - .HasColumns("Id", "Name", "disc") - .DbEqual("nvarchar", tm => tm.Properties.Single(c => c.Name == "disc").TypeName) - .DbEqual(128, tm => tm.Properties.Single(c => c.Name == "disc").MaxLength); - databaseMapping.AssertMapping("IsolatedIslands") - .HasNullabilityColumnCondition("disc", true); - } - - [Fact] - public void Null_discriminator_value_with_specified_length_gets_string_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { mc.Requires("disc").HasValue(null).HasMaxLength(100); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert() - .HasColumns("Id", "Name", "disc") - .DbEqual("nvarchar", tm => tm.Properties.Single(c => c.Name == "disc").TypeName) - .DbEqual(100, tm => tm.Properties.Single(c => c.Name == "disc").MaxLength); - databaseMapping.AssertMapping("IsolatedIslands") - .HasNullabilityColumnCondition("disc", true); - } - - [Fact] - public void FKs_in_base_type_remain_non_nullable_with_nullability_condition() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasKey( - e => new - { - e.Key1, - e.Key2, - }); - modelBuilder.Entity().Map( - mapping => { mapping.Requires(e => e.Discriminator1).HasValue(); }); - modelBuilder.Entity().Map( - mapping => { mapping.Requires("Discriminator1").HasValue(null); }); - modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany(). - HasForeignKey( - dependent => new - { - dependent.PrincipalKey1, - dependent.PrincipalKey2, - }); - modelBuilder.Entity().Property(p => p.PrincipalKey1).IsRequired(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert() - .DbEqual(false, tm => tm.Properties.Single(c => c.Name == "PrincipalKey1").Nullable) - .DbEqual(false, tm => tm.Properties.Single(c => c.Name == "PrincipalKey2").Nullable); - } - - [Fact] - public void FKs_in_base_type_remain_non_nullable_with_nullability_condition_when_base_defined_first() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasKey( - e => new - { - e.Key1, - e.Key2, - }); - modelBuilder.Entity().Map( - mapping => { mapping.Requires("Discriminator1").HasValue(null); }); - modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany(). - HasForeignKey( - dependent => new - { - dependent.PrincipalKey1, - dependent.PrincipalKey2, - }); - modelBuilder.Entity().Property(p => p.PrincipalKey1).IsRequired(); - modelBuilder.Entity().Map( - mapping => { mapping.Requires(e => e.Discriminator1).HasValue(); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert() - .DbEqual(false, tm => tm.Properties.Single(c => c.Name == "PrincipalKey1").Nullable) - .DbEqual(false, tm => tm.Properties.Single(c => c.Name == "PrincipalKey2").Nullable); - } - - [Fact] - // Repro for pending 136283 - public void Three_level_TPH_with_abstract_middle_has_nullable_discriminatorx() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .HasKey(e => e.Key1); - modelBuilder.Entity().Map( - mapping => - { - mapping.Requires("Discriminator2") - .HasValue("zbpmhdbllp") - .IsRequired() - .HasColumnType("nchar") - .HasMaxLength(30) - .IsUnicode() - .IsFixedLength(); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.Requires("Discriminator2").HasValue(""); - mapping.Requires("Discriminator1").HasValue( - "analysismapping").HasColumnType("varchar"). - HasMaxLength(20).IsVariableLength(); - }); - modelBuilder.Entity() - .HasMany(e => e.DependentNavigation) - .WithOptional() - .Map(m => m.MapKey(new[] { "IndependentColumn1" })); - - modelBuilder.Entity().Map( - mapping => - { - mapping.Requires("Discriminator2") - .HasValue(""); - mapping.Requires("Discriminator1") - .HasValue("authenticode"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert() - .DbEqual(false, tm => tm.Properties.Single(c => c.Name == "Discriminator2").Nullable) - .DbEqual(true, tm => tm.Properties.Single(c => c.Name == "Discriminator1").Nullable); - } - - [Fact] - public void Three_level_TPH_with_abstract_middle_with_IA_self_ref() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map( - mapping => - { - mapping.Requires("Discriminator2").HasValue("zbpmhdbllp").IsRequired().HasColumnType("nchar"). - HasMaxLength(30).IsUnicode().IsFixedLength(); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.Requires("Discriminator2").HasValue(""); - mapping.Requires("Discriminator1").HasValue( - "analysismapping").HasColumnType("varchar"). - HasMaxLength(20).IsVariableLength(); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.Requires("Discriminator2").HasValue(""); - mapping.Requires("Discriminator1").HasValue("authenticode"); - }); - modelBuilder.Entity().HasKey(e => e.Key1); - modelBuilder.Entity() - .HasMany(e => e.DependentNavigation) - .WithOptional() - .Map(m => m.MapKey(new[] { "IndependentColumn1" })); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("ThreeLevelBases") - .HasColumns( - "Key1", "BaseProperty", "DerivedProperty1", "IndependentColumn1", "Discriminator2", - "Discriminator1"); - - databaseMapping.AssertMapping("ThreeLevelBases", false) - .HasColumnCondition("Discriminator2", "zbpmhdbllp"); - - databaseMapping.AssertNoMapping(); - - databaseMapping.AssertMapping("ThreeLevelBases") - .HasColumnCondition("Discriminator2", "") - .HasColumnCondition("Discriminator1", "authenticode"); - } - - [Fact] - public void Derived_association_creates_nullable_FKs_in_TPH() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - - modelBuilder.Entity().HasOptional(e => e.DependentNavigation).WithRequired( - e => e.PrincipalNavigation); - modelBuilder.Entity().Property(p => p.BaseProperty).HasColumnType("time"); - modelBuilder.Entity().HasKey( - e => new - { - e.Key1, - e.Key2, - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert() - .DbEqual(true, tm => tm.Properties.Single(c => c.Name == "PrincipalNavigation_Key1").Nullable) - .DbEqual(true, tm => tm.Properties.Single(c => c.Name == "PrincipalNavigation_Key1").Nullable); - } - - [Fact] - public void Base_FK_association_to_abstract_dependent_in_TPH() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasKey(e => e.Key1); - modelBuilder.Entity() - .HasRequired(e => e.PrincipalNavigation) - .WithMany(e => e.DependentNavigation) - .HasForeignKey( - dependent => new - { - dependent.PrincipalKey1 - }); - modelBuilder.Entity().Map( - mapping => { mapping.Requires("Discriminator1").HasValue("kssfjohr"); }); - modelBuilder.Entity().Map( - mapping => - { - mapping.Requires("Discriminator1").HasValue("qrpnfdzhixxjujsgfsryoffpelbaxhtankvxlz").IsRequired(). - HasColumnType("nvarchar").HasMaxLength(40).IsUnicode().IsVariableLength(); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("AbsDep_Principal") - .HasColumns("Key1") - .HasNoForeignKeyColumns(); - - databaseMapping.Assert("AbsDep_Dependent") - .HasColumns("Id", "PrincipalKey1", "DerivedProperty1", "Discriminator1") - .HasForeignKeyColumn("PrincipalKey1", "AbsDep_Principal"); - } - - [Fact] - public void Base_IA_association_to_abstract_dependent_in_TPH() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasKey(e => e.Key1); - modelBuilder.Entity() - .HasRequired(e => e.PrincipalNavigation) - .WithMany(e => e.DependentNavigation) - .Map(im => im.MapKey("IndependentKey1")); - modelBuilder.Entity().Map( - mapping => { mapping.Requires("Discriminator1").HasValue("kssfjohr"); }); - modelBuilder.Entity().Map( - mapping => - { - mapping.Requires("Discriminator1").HasValue("qrpnfdzhixxjujsgfsryoffpelbaxhtankvxlz").IsRequired(). - HasColumnType("nvarchar").HasMaxLength(40).IsUnicode().IsVariableLength(); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("AbsDep_Principal") - .HasColumns("Key1") - .HasNoForeignKeyColumns(); - - databaseMapping.Assert("AbsDep_Dependent") - .HasColumns("Id", "PrincipalKey1", "DerivedProperty1", "IndependentKey1", "Discriminator1") - .HasForeignKeyColumn("IndependentKey1", "AbsDep_Principal"); - } - - [Fact] - public void Requires_property_is_sufficient_for_base() - { - var modelBuilder = new AdventureWorksModelBuilder(); - modelBuilder.Entity(); - modelBuilder.Entity().Map( - mapping => { mapping.Requires(e => e.DiscriminatorNotNull).HasValue(); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - } - - [Fact] - public void Condition_column_configuration_on_abstract_base_applied_to_column() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map( - mapping => - { - mapping.Requires("DiscriminatorValue").HasValue("2").IsRequired().HasColumnType("nchar"). - HasMaxLength(30).IsUnicode().IsFixedLength(); - }); - modelBuilder.Entity().Map( - mapping => { mapping.Requires("DiscriminatorValue").HasValue("1"); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert() - .DbEqual("nchar", t => t.Properties.Single(c => c.Name == "DiscriminatorValue").TypeName) - .DbEqual(30, t => t.Properties.Single(c => c.Name == "DiscriminatorValue").MaxLength); - } - - [Fact] - public void TPH_with_an_IA_from_abstract_non_root_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany( - e => e.DependentNavigation); - modelBuilder.Entity().Map( - mapping => { mapping.Requires("DiscriminatorValue").HasValue("2"); }); - modelBuilder.Entity().Map( - mapping => { mapping.Requires("DiscriminatorValue").HasValue("1"); }); - modelBuilder.Entity().Map( - mapping => - { - mapping.Requires("DiscriminatorValue").HasValue("3").IsRequired().HasColumnType("nvarchar(max)"). - IsUnicode(); - }); - modelBuilder.Entity().HasKey(e => e.Key1); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - } - - [Fact] - public void TPH_with_an_FK_from_abstract_root_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasKey(e => e.Key1); - modelBuilder.Entity().HasKey(e => e.Key1); - modelBuilder.Entity().HasOptional(e => e.DependentNavigation).WithRequired( - e => e.PrincipalNavigation); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("BasePrincipal"); }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - } - - [Fact] - public void TPH_with_self_ref_FK_on_derived_type_has_non_nullable_FK_when_base_type_is_abstract() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map( - mapping => { mapping.Requires("DiscriminatorValue").HasValue(1).HasColumnType("tinyint"); }); - modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany( - e => e.DependentNavigation).Map(m => { }); - modelBuilder.Entity().HasKey(e => e.Key1); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert() - .HasColumns("Key1", "BaseProperty", "PrincipalNavigation_Key1", "DiscriminatorValue") - .HasForeignKeyColumn("PrincipalNavigation_Key1") - .DbEqual(false, t => t.Properties.Single(c => c.Name == "PrincipalNavigation_Key1").Nullable); - } - - [Fact] - public void - TPH_with_self_ref_FK_on_derived_type_has_nullable_FK_when_base_type_is_abstract_but_there_are_other_nonrelated_derived_types() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map( - mapping => { mapping.Requires("DiscriminatorValue").HasValue(1).HasColumnType("tinyint"); }); - modelBuilder.Entity().Map( - mapping => { mapping.Requires("DiscriminatorValue").HasValue(0); }); - modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany( - e => e.DependentNavigation).Map(m => { }); - modelBuilder.Entity().HasKey(e => e.Key1); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert() - .HasColumns("Key1", "BaseProperty", "OtherData", "PrincipalNavigation_Key1", "DiscriminatorValue") - .HasForeignKeyColumn("PrincipalNavigation_Key1") - .DbEqual(true, t => t.Properties.Single(c => c.Name == "PrincipalNavigation_Key1").Nullable); - } - - [Fact] - public void TPH_with_self_ref_FK_on_derived_type_has_nullable_FK_when_base_type_is_concrete() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map( - mapping => { mapping.Requires("DiscriminatorValue").HasValue(0).HasColumnType("tinyint"); }); - modelBuilder.Entity().Map( - mapping => { mapping.Requires("DiscriminatorValue").HasValue(1); }); - modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany( - e => e.DependentNavigation).Map(m => { }); - modelBuilder.Entity().HasKey(e => e.Key1); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert() - .HasColumns("Key1", "BaseProperty", "PrincipalNavigation_Key1", "DiscriminatorValue") - .HasForeignKeyColumn("PrincipalNavigation_Key1") - .DbEqual(true, t => t.Properties.Single(c => c.Name == "PrincipalNavigation_Key1").Nullable); - } - - #endregion - - #region Basic TPT Tests - - [Fact] - public void ToTable_configures_basic_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Bases"); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Entity().ToTable("Deriveds"); - modelBuilder.Entity().Ignore(b => b.AssocRelated); - modelBuilder.Entity().Ignore(b => b.AssocRelatedId); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - Assert.Equal( - 2, - databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Single().EntityTypeMappings. - Count()); - - databaseMapping.Assert("Bases"); - databaseMapping.Assert("Deriveds"); - } - - [Fact] - public void ToTable_configures_TPT_with_unmapped_abstract_base_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("L1"); - modelBuilder.Entity().ToTable("L2"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - Assert.Equal( - 2, - databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Single().EntityTypeMappings. - Count()); - databaseMapping.Assert("L1"); - databaseMapping.Assert("L2"); - } - - [Fact] - public void ToTable_configures_TPT_with_mapped_abstract_base_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Bases"); - modelBuilder.Entity().ToTable("L1"); - modelBuilder.Entity().ToTable("L2"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - Assert.Equal( - 3, - databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Single().EntityTypeMappings. - Count()); - - databaseMapping.Assert("Bases"); - databaseMapping.Assert("L1"); - databaseMapping.Assert("L2"); - } - - [Fact] - public void ToTable_configures_TPT_with_FK_on_base_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Bases"); - modelBuilder.Entity().Ignore(b => b.AssocRelated); - modelBuilder.Entity().Ignore(b => b.AssocRelatedId); - modelBuilder.Entity().ToTable("Derived"); - modelBuilder.Entity().Ignore(r => r.Deriveds); - modelBuilder.Entity().Ignore(r => r.RefBase); - modelBuilder.Entity().Ignore(r => r.RefDerived); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Bases"); - databaseMapping.Assert("Derived"); - databaseMapping.Assert().HasForeignKeyColumn("AssocRelatedBaseId"); - } - - [Fact] - public void ToTable_configures_TPT_with_FK_on_derived_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Bases"); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Entity().ToTable("Derived"); - modelBuilder.Entity().Ignore(r => r.Bases); - modelBuilder.Entity().Ignore(r => r.RefBase); - modelBuilder.Entity().Ignore(r => r.RefDerived); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Bases"); - databaseMapping.Assert("Derived"); - databaseMapping.Assert().HasForeignKeyColumn("AssocRelatedId"); - } - - [Fact] - public void ToTable_configures_TPT_with_IA_on_base_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Bases"); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Entity().Ignore(b => b.AssocRelated); - modelBuilder.Entity().Ignore(b => b.AssocRelatedId); - modelBuilder.Entity().ToTable("Derived"); - modelBuilder.Entity().Ignore(r => r.Deriveds); - modelBuilder.Entity().Ignore(r => r.RefBase); - modelBuilder.Entity().Ignore(r => r.RefDerived); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Bases"); - databaseMapping.Assert("Derived"); - databaseMapping.Assert().HasForeignKeyColumn("AssocRelatedBase_Id"); - } - - [Fact] - public void ToTable_configures_TPT_with_IA_on_derived_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Bases"); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Entity().ToTable("Derived"); - modelBuilder.Entity().Ignore(x => x.AssocRelatedId); - modelBuilder.Entity().Ignore(r => r.Bases); - modelBuilder.Entity().Ignore(r => r.RefBase); - modelBuilder.Entity().Ignore(r => r.RefDerived); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Bases"); - databaseMapping.Assert("Derived"); - databaseMapping.Assert().HasForeignKeyColumn("AssocRelated_Id"); - } - - [Fact] - public void ToTable_configures_TPT_with_IA_on_derived_type_with_configured_relationship() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasRequired(e => e.AssocRelated).WithOptional(e => e.RefDerived); - - modelBuilder.Entity().ToTable("Bases"); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - - modelBuilder.Entity().ToTable("Derived"); - modelBuilder.Entity().Ignore(x => x.AssocRelatedId); - modelBuilder.Entity().Ignore(r => r.Bases); - modelBuilder.Entity().Ignore(r => r.RefBase); - modelBuilder.Entity().Ignore(r => r.Deriveds); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Bases"); - databaseMapping.Assert("Derived"); - // 1:0..1 makes Id the FK for the AssocRelated to AssocDerived relationship - databaseMapping.Assert().DbEqual(2, t => t.ForeignKeyBuilders.Count()); - databaseMapping.Assert().HasForeignKeyColumn("Id", "Bases"); - databaseMapping.Assert().HasForeignKeyColumn("Id", "AssocRelateds"); - } - - [Fact] - public void ToTable_configures_TPT_and_sets_FK_to_base_table() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("A"); - modelBuilder.Entity().ToTable("B"); - modelBuilder.Entity().ToTable("C"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert("B").HasForeignKeyColumn("Id", "A") - .DbEqual(1, t => t.ForeignKeyBuilders.Count()); - databaseMapping.Assert("C").HasForeignKeyColumn("Id", "B") - .DbEqual(1, t => t.ForeignKeyBuilders.Count()); - } - - [Fact] - public void ToTable_configures_TPT_and_creates_single_FK_to_related() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Property(p => p.Key1).HasColumnType("uniqueidentifier"); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); - modelBuilder.Entity().HasKey( - e => new - { - e.Key1, - e.Key2, - }); - - modelBuilder.Entity().Property(p => p.Key1).HasColumnType("uniqueidentifier"); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Images"); }); - modelBuilder.Entity().HasKey( - e => new - { - e.Key1, - e.Key2, - }); - - modelBuilder.Entity().HasRequired(e => e.CKCategory).WithOptional().WillCascadeOnDelete(true); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); - modelBuilder.Entity().HasKey( - e => new - { - e.CKCategoryKey1, - e.CKCategoryKey2, - }); - - modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); - modelBuilder.Entity().HasRequired(dp => dp.Image).WithOptional(); - - modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent2"); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert() - .DbEqual(0, t => t.ForeignKeyBuilders.Count()); - - databaseMapping.Assert() - .DbEqual(1, t => t.ForeignKeyBuilders.Count()) - .HasForeignKey(new[] { "CKCategoryKey1", "CKCategoryKey2" }, "Principal"); - - databaseMapping.Assert() - .DbEqual(2, t => t.ForeignKeyBuilders.Count()) - .HasForeignKey(new[] { "CKCategoryKey1", "CKCategoryKey2" }, "Dependent") - .HasForeignKey(new[] { "CKCategoryKey1", "CKCategoryKey2" }, "Images"); - - databaseMapping.Assert() - .DbEqual(1, t => t.ForeignKeyBuilders.Count()) - .HasForeignKey(new[] { "CKCategoryKey1", "CKCategoryKey2" }, "DerivedDependent"); - } - - [Fact] - public void ToTable_configures_TPT_and_creates_single_FK_to_self_reference() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasKey(e => e.Key1); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("SelfRefBase"); }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("SelfRefDerived"); }); - modelBuilder.Entity().HasOptional(e => e.SelfRefNavigation).WithMany().HasForeignKey( - d => new - { - d.DependentKey1 - }).WillCascadeOnDelete(false); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert() - .DbEqual(0, t => t.ForeignKeyBuilders.Count()); - - databaseMapping.Assert() - .DbEqual(2, t => t.ForeignKeyBuilders.Count()) - .HasForeignKeyColumn("Key1", "SelfRefBase") - .HasForeignKeyColumn("DependentKey1", "SelfRefDerived"); - } - - [Fact] - public void TPT_moves_FKs_pointing_to_moved_table() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("A"); - modelBuilder.Entity().ToTable("B"); - modelBuilder.Entity().ToTable("C"); - modelBuilder.Entity().HasRequired(c => c.Repro136761_B).WithMany().HasForeignKey( - c => c.Repro136761_BId); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert() - .DbEqual(0, t => t.ForeignKeyBuilders.Count()); - - databaseMapping.Assert() - .DbEqual(1, t => t.ForeignKeyBuilders.Count()) - .HasForeignKeyColumn("Repro136761_AId", "A"); - - databaseMapping.Assert() - .DbEqual(1, t => t.ForeignKeyBuilders.Count()) - .HasForeignKeyColumn("Repro136761_BId", "B"); - } - - [Fact] - public void FKs_in_base_type_remain_non_nullable_with_nullability_condition_in_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Property(p => p.DerivedProperty1).HasColumnType("bit"); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); - modelBuilder.Entity().Property(p => p.Key1).HasColumnType("smalldatetime"); - modelBuilder.Entity().HasKey(e => e.Key1); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert() - .DbEqual(false, tm => tm.Properties.Single(c => c.Name == "Key1").Nullable); - } - - [Fact] - public void FKs_in_base_type_remain_non_nullable_with_nullability_condition_when_base_defined_first_in_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); - modelBuilder.Entity().Property(p => p.DerivedProperty1).HasColumnType("bit"); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); - modelBuilder.Entity().Property(p => p.Key1).HasColumnType("smalldatetime"); - modelBuilder.Entity().HasKey(e => e.Key1); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert() - .DbEqual(false, tm => tm.Properties.Single(c => c.Name == "Key1").Nullable); - } - - [Fact] - public void IA_Association_between_subtypes_with_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasKey(e => e.Key1); - modelBuilder.Entity().HasMany(e => e.THABS_DependentNavigation); - modelBuilder.Entity().HasOptional(e => e.THABS_PrincipalNavigation); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("BasePrincipal"); }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("BasePrincipal") - .HasColumns("Key1", "BaseProperty") - .HasNoForeignKeyColumns(); - - databaseMapping.Assert("Principal") - .HasColumns("Key1") - .HasForeignKeyColumn("Key1", "BasePrincipal"); - - databaseMapping.Assert("Dependent") - .HasColumns("Id", "THABS_PrincipalNavigation_Key1") - .HasForeignKeyColumn("THABS_PrincipalNavigation_Key1", "Principal"); - - databaseMapping.Assert("DerivedDependent") - .HasColumns("Id", "DerivedProperty1") - .HasForeignKeyColumn("Id", "Dependent"); - } - - [Fact] - public void Self_referencing_relationship_on_derived_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Base"); }); - modelBuilder.Entity().HasKey( - e => new - { - e.Key1, - e.Key2, - }); - modelBuilder.Entity().HasMany(e => e.Navigation).WithMany(); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Derived"); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Base") - .HasColumns("Key1", "Key2", "BaseProperty") - .HasNoForeignKeyColumns(); - - databaseMapping.Assert("Derived") - .HasColumns("Key1", "Key2") - .HasForeignKey(new[] { "Key1", "Key2" }, "Base"); - - var joinTable = databaseMapping.Database.EntityTypes.ElementAt(1); - Assert.Equal("SRDerivedSRDeriveds", databaseMapping.Database.GetEntitySet(joinTable).Table); - Assert.True( - joinTable.Properties.Select(x => x.Name).SequenceEqual( - new[] - { - "SRDerived_Key1", "SRDerived_Key2", - "SRDerived_Key11", "SRDerived_Key21" - })); - Assert.Equal(2, joinTable.ForeignKeyBuilders.Count()); - Assert.True( - joinTable.ForeignKeyBuilders.All( - fk => databaseMapping.Database.GetEntitySet(fk.PrincipalTable).Table == "Derived")); - } - - [Fact] - public void ToTable_TPT_to_same_base_table_results_in_default_TPH() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("A1"); - modelBuilder.Entity().ToTable("A1"); - modelBuilder.Entity().ToTable("A1"); - modelBuilder.Entity().ToTable("A1"); - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.AssertMapping("A1", false) - .HasColumnCondition("Discriminator", "Repro137329_A1"); - } - - [Fact] - public void IA_between_TPT_subtypes_has_FK_to_sub_table() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("BaseEntities"); - modelBuilder.Entity().ToTable("Entity1s"); - modelBuilder.Entity().Ignore(x => x.Repro109944_Entity2ID); - modelBuilder.Entity().ToTable("Entity2s"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert() - .HasNoForeignKeyColumns(); - databaseMapping.Assert() - .HasForeignKeyColumn("ID", "BaseEntities") - .HasForeignKeyColumn("Repro109944_Entity2_ID", "Entity2s"); - databaseMapping.Assert() - .HasForeignKeyColumn("ID", "BaseEntities"); - } - - [Fact] - public void FK_between_TPT_subtypes_has_FK_to_sub_table() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("BaseEntities"); - modelBuilder.Entity().ToTable("Entity1s"); - modelBuilder.Entity().ToTable("Entity2s"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert() - .HasNoForeignKeyColumns(); - databaseMapping.Assert() - .HasForeignKeyColumn("ID", "BaseEntities") - .HasForeignKeyColumn("Repro109944_Entity2ID", "Entity2s"); - databaseMapping.Assert() - .HasForeignKeyColumn("ID", "BaseEntities"); - } - - [Fact] - public void FK_between_TPT_base_types_has_FK_to_base_table() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedPrincipal"); }); - modelBuilder.Entity().HasKey(e => e.Key1); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert("Dependent") - .HasForeignKeyColumn("Key1", "Principal"); - } - - [Fact] - public void IA_between_TPT_base_types_has_FK_to_base_table() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); - modelBuilder.Entity().Ignore(x => x.Key1); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedPrincipal"); }); - modelBuilder.Entity().HasKey(e => e.Key1); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert("Dependent") - .HasForeignKeyColumn("PrincipalNavigation_Key1", "Principal"); - } - - [Fact] - public void TPT_with_multiple_associations_in_hierarchy() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("BaseEntities"); - modelBuilder.Entity().ToTable("SomeEntities"); - modelBuilder.Entity().ToTable("SomeMores"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - } - - [Fact] - public void TPT_with_asociation_between_middle_types() - { - var builder = new AdventureWorksModelBuilder(); - - builder.Entity().HasMany(e => e.DependentNavigation); - // Works if this line is commented out. - builder.Entity().Property(p => p.DerivedProperty1).HasColumnType( - "nvarchar(max)").IsUnicode(); - builder.Entity().HasRequired(e => e.PrincipalNavigation); - builder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); - builder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); - builder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); - builder.Entity().Property(p => p.BaseProperty).HasColumnType("date"); - builder.Entity().Map(mapping => { mapping.ToTable("BaseDependent"); }); - builder.Entity().Property(p => p.DerivedProperty1).HasColumnType("smallmoney"); - builder.Entity().Map(mapping => { mapping.ToTable("DerivedPrincipal"); }); - builder.Entity().HasKey(e => e.Key1); - builder.Entity().Property(p => p.PrincipalKey1).IsRequired(); - - var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - } - - [Fact] - public void TPT_with_no_asociation_between_middle_types() - { - var builder = new AdventureWorksModelBuilder(); - - builder.Entity().Ignore(e => e.DependentNavigation); - // Works if this line is commented out. - builder.Entity().Property(p => p.DerivedProperty1).HasColumnType( - "nvarchar(max)").IsUnicode(); - builder.Entity().Ignore(e => e.PrincipalNavigation); - builder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); - builder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); - builder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); - builder.Entity().Property(p => p.BaseProperty).HasColumnType("date"); - builder.Entity().Map(mapping => { mapping.ToTable("BaseDependent"); }); - builder.Entity().Property(p => p.DerivedProperty1).HasColumnType("smallmoney"); - builder.Entity().Map(mapping => { mapping.ToTable("DerivedPrincipal"); }); - builder.Entity().HasKey(e => e.Key1); - builder.Entity().Property(p => p.PrincipalKey1).IsRequired(); - - var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - } - - [Fact] - public void TPT_with_required_to_optional_IA_on_derived_type_creates_non_nullable_FK() - { - var builder = new AdventureWorksModelBuilder(); - - builder.Entity().HasKey( - e => new - { - e.Key1, - e.Key2, - }); - builder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); - builder.Entity().Map(mapping => { mapping.ToTable("BaseDependent"); }); - builder.Entity().HasRequired(e => e.PrincipalNavigation).WithOptional( - e => e.DependentNavigation) - .Map(_ => { }).WillCascadeOnDelete(false); - - builder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); - builder.Ignore(); - - var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert("Dependent") - .DbEqual(false, t => t.Properties.Single(x => x.Name == "PrincipalNavigation_Id").Nullable); - } - - [Fact] - public void TPT_with_required_to_optional_IA_on_derived_middle_type_creates_non_nullable_FK() - { - var builder = new AdventureWorksModelBuilder(); - - builder.Entity().HasKey( - e => new - { - e.Key1, - e.Key2, - }); - builder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); - builder.Entity().Map(mapping => { mapping.ToTable("BaseDependent"); }); - builder.Entity().HasRequired(e => e.PrincipalNavigation).WithOptional( - e => e.DependentNavigation) - .Map(_ => { }).WillCascadeOnDelete(false); - - builder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); - builder.Entity().ToTable("DerivedDependent"); - - var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert("Dependent") - .DbEqual(false, t => t.Properties.Single(x => x.Name == "PrincipalNavigation_Id").Nullable); - } - - [Fact] - public void Uniquification_happens_correctly_when_relationship_with_same_name_exists_in_two_derived_types() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().ToTable("BaseEmployee"); - modelBuilder.Entity().ToTable("TargetEmployee"); - modelBuilder.Entity().ToTable("Note"); - modelBuilder.Entity().ToTable("NoteWithRelationship1"); - modelBuilder.Entity().HasRequired(x => x.TargetEmployee); - modelBuilder.Entity().ToTable("NoteWithRelationship2"); - modelBuilder.Entity().HasRequired(x => x.TargetEmployee); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Uniquification_happens_correctly_when_complex_type_reused_in_derived_types() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - #endregion - - #region Basic TPC Tests - - [Fact] - public void Two_entity_TPC() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => mc.ToTable("Bases")); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Entity() - .Map( - mc => - { - mc.MapInheritedProperties(); - mc.ToTable("Deriveds"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelated); - modelBuilder.Entity().Ignore(b => b.AssocRelatedId); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - Assert.Equal( - 2, - databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Single().EntityTypeMappings. - Count()); - databaseMapping.Assert("Bases").HasColumns("Id", "Name", "BaseData"); - databaseMapping.AssertMapping("Bases", false); - databaseMapping.Assert("Deriveds").HasColumns( - "Id", "Name", "BaseData", "DerivedData1", - "DerivedData2"); - databaseMapping.AssertMapping("Deriveds", false); - } - - [Fact] - public void Two_entity_TPC_with_multiple_nonconflicting_configurations() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => mc.ToTable("Bases")); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - - Assert.Throws( - () => - modelBuilder.Entity() - .Map(mc => { mc.Properties(d => d.DerivedData1); }) - .Map(mc => { mc.Properties(d => d.DerivedData2); }) - .Map(mc => { mc.MapInheritedProperties(); }) - .Map(mc => { mc.ToTable("Deriveds"); })); - } - - [Fact] - public void Two_entity_TPC_with_column_override() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => mc.ToTable("Bases")) - .Property(a => a.Name).HasColumnType("char"); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Entity() - .Map( - mc => - { - mc.MapInheritedProperties(); - mc.ToTable("Deriveds"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelated); - modelBuilder.Entity().Ignore(b => b.AssocRelatedId); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - Assert.Equal( - 2, - databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Single().EntityTypeMappings. - Count()); - databaseMapping.Assert("Bases").HasColumns("Id", "Name", "BaseData"); - databaseMapping.Assert("Bases").DbEqual( - "char", - x => x.Properties.Single(c => c.Name == "Name").TypeName); - databaseMapping.Assert("Deriveds").HasColumns( - "Id", "Name", "BaseData", "DerivedData1", - "DerivedData2"); - databaseMapping.Assert("Deriveds").DbEqual( - "char", - x => - x.Properties.Single(c => c.Name == "Name").TypeName); - } - - //[Fact] - //public void ToTable_configures_TPT_with_unmapped_abstract_base_type() - //{ - // var modelBuilder = new AdventureWorksModelBuilder(); - - // modelBuilder.Entity().ToTable("L1"); - // modelBuilder.Entity().ToTable("L2"); - - // var databaseMapping = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; - - // Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - // Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Single().EntityTypeMappings.Count); - // Assert.True(databaseMapping.Database.Schemas.Single().Tables.Any(t => t.Name == "L1")); - // Assert.True(databaseMapping.Database.Schemas.Single().Tables.Any(t => t.Name == "L2")); - //} - - //[Fact] - //public void ToTable_configures_TPT_with_mapped_abstract_base_type() - //{ - // var modelBuilder = new AdventureWorksModelBuilder(); - - // modelBuilder.Entity().ToTable("Bases"); - // modelBuilder.Entity().ToTable("L1"); - // modelBuilder.Entity().ToTable("L2"); - - // var databaseMapping = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; - - // Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - // Assert.Equal(3, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Single().EntityTypeMappings.Count); - // Assert.True(databaseMapping.Database.Schemas.Single().Tables.Any(t => t.Name == "Bases")); - // Assert.True(databaseMapping.Database.Schemas.Single().Tables.Any(t => t.Name == "L1")); - // Assert.True(databaseMapping.Database.Schemas.Single().Tables.Any(t => t.Name == "L2")); - //} - - [Fact] - public void ToTable_configures_TPC_with_FK_on_base_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Bases"); - modelBuilder.Entity().Ignore(b => b.AssocRelated); - modelBuilder.Entity().Ignore(b => b.AssocRelatedId); - modelBuilder.Entity() - .Map( - mc => - { - mc.MapInheritedProperties(); - mc.ToTable("Deriveds"); - }); - modelBuilder.Entity().Ignore(r => r.Deriveds); - modelBuilder.Entity().Ignore(r => r.RefBase); - modelBuilder.Entity().Ignore(r => r.RefDerived); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Bases").HasColumns("Id", "Name", "BaseData", "AssocRelatedBaseId"); - databaseMapping.Assert("Deriveds").HasColumns( - "Id", "Name", "BaseData", "AssocRelatedBaseId", - "DerivedData1", "DerivedData2"); - databaseMapping.Assert("Bases").HasForeignKeyColumn("AssocRelatedBaseId"); - databaseMapping.Assert("Deriveds").HasForeignKeyColumn("AssocRelatedBaseId"); - } - - [Fact] - public void ToTable_configures_TPC_with_FK_on_derived_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Bases"); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Entity() - .Map( - mc => - { - mc.MapInheritedProperties(); - mc.ToTable("Deriveds"); - }); - modelBuilder.Entity().Ignore(r => r.Bases); - modelBuilder.Entity().Ignore(r => r.RefBase); - modelBuilder.Entity().Ignore(r => r.RefDerived); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Bases").HasColumns("Id", "Name", "BaseData"); - databaseMapping.Assert("Deriveds").HasColumns( - "Id", "Name", "BaseData", "AssocRelatedId", - "DerivedData1", "DerivedData2"); - databaseMapping.Assert("Deriveds").HasForeignKeyColumn("AssocRelatedId"); - } - - [Fact] - public void ToTable_configures_TPC_with_IA_on_derived_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Bases"); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Entity() - .Map( - mc => - { - mc.MapInheritedProperties(); - mc.ToTable("Deriveds"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelatedId); - modelBuilder.Entity().Ignore(r => r.Bases); - modelBuilder.Entity().Ignore(r => r.RefBase); - modelBuilder.Entity().Ignore(r => r.RefDerived); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Bases").HasColumns("Id", "Name", "BaseData"); - databaseMapping.Assert("Deriveds").HasColumns( - "Id", "AssocRelated_Id", "Name", "BaseData", - "DerivedData1", "DerivedData2"); - databaseMapping.Assert("Deriveds").HasForeignKeyColumn("AssocRelated_Id"); - } - - [Fact] - public void ToTable_configures_TPC_and_creates_single_FK_to_related() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Property(p => p.Key1).HasColumnType("uniqueidentifier"); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); - modelBuilder.Entity().HasKey( - e => new - { - e.Key1, - e.Key2, - }); - modelBuilder.Entity().HasRequired(e => e.CKCategory).WithOptional().WillCascadeOnDelete(true); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); - modelBuilder.Entity().HasKey( - e => new - { - e.CKCategoryKey1, - e.CKCategoryKey2, - }); - - modelBuilder.Entity().Map( - mapping => - { - mapping.MapInheritedProperties(); - mapping.ToTable("DerivedDependent"); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.MapInheritedProperties(); - mapping.ToTable("DerivedDependent2"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert() - .DbEqual(0, t => t.ForeignKeyBuilders.Count()); - - databaseMapping.Assert() - .DbEqual(1, t => t.ForeignKeyBuilders.Count()) - .HasForeignKey(new[] { "CKCategoryKey1", "CKCategoryKey2" }, "Principal"); - - databaseMapping.Assert() - .DbEqual(1, t => t.ForeignKeyBuilders.Count()) - .HasForeignKey(new[] { "CKCategoryKey1", "CKCategoryKey2" }, "Principal"); - - databaseMapping.Assert() - .DbEqual(1, t => t.ForeignKeyBuilders.Count()) - .HasForeignKey(new[] { "CKCategoryKey1", "CKCategoryKey2" }, "Principal"); - } - - [Fact] - public void Mapping_store_type_propagates_to_derived_TPC_table() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().Property(x => x.DerivedData).HasColumnType("image"); - modelBuilder.Entity() - .Map( - mc => - { - mc.ToTable("Derived"); - mc.MapInheritedProperties(); - }); - modelBuilder.Entity() - .Map( - mc => - { - mc.ToTable("Derived2"); - mc.MapInheritedProperties(); - }); - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - databaseMapping.Assert().DbEqual( - "image", - t => t.Properties.Single(c => c.Name == "DerivedData").TypeName); - databaseMapping.Assert().DbEqual( - "image", - t => t.Properties.Single(c => c.Name == "DerivedData").TypeName); - } - - [Fact] - public void Mapping_store_type_propagates_to_dependent_IA() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Property(p => p.Key1).HasColumnType("date"); - modelBuilder.Entity().Property(p => p.Key2).HasColumnType("numeric").HasPrecision(15, 5); - modelBuilder.Entity().Map( - mapping => - { - mapping.MapInheritedProperties(); - mapping.ToTable("Repro165020_BaseDependent"); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.MapInheritedProperties(); - mapping.ToTable("Repro165020_BasePrincipal"); - }); - modelBuilder.Entity().HasKey( - e => new - { - e.Key1, - e.Key2, - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.MapInheritedProperties(); - mapping.ToTable("Repro165020_DerivedPrincipal"); - }); - - modelBuilder.Entity().Map( - mapping => - { - mapping.MapInheritedProperties(); - mapping.ToTable("Repro165020_DerivedDependent"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - databaseMapping.Assert().DbEqual( - "date", t => t.Properties.Single(c => c.Name == "PrincipalNavigation_Key1").TypeName); - databaseMapping.Assert().DbEqual( - "numeric", t => t.Properties.Single(c => c.Name == "PrincipalNavigation_Key2").TypeName); - } - - [Fact] - public void FK_association_to_principal_base_should_not_make_FK_in_TPC() - { - var modelBuilder = new AdventureWorksModelBuilder(); - modelBuilder.Entity(); - - modelBuilder.Entity() - .Map(m => m.ToTable("Department")) - .Map( - m => - { - m.MapInheritedProperties(); - m.ToTable("OldDepartment"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert().HasNoForeignKeyColumns(); - databaseMapping.Assert().HasNoForeignKeyColumns(); - databaseMapping.Assert().HasNoForeignKeyColumns(); - } - - [Fact] - public void Self_referencing_relationship_on_derived_TPC() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Base"); }); - modelBuilder.Entity().HasKey( - e => new - { - e.Key1, - e.Key2, - }); - modelBuilder.Entity().HasMany(e => e.Navigation).WithMany(); - modelBuilder.Entity().Map( - mapping => - { - mapping.MapInheritedProperties(); - mapping.ToTable("Derived"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Base") - .HasColumns("Key1", "Key2", "BaseProperty") - .HasNoForeignKeyColumns(); - - databaseMapping.Assert("Derived") - .HasColumns("Key1", "Key2", "BaseProperty") - .HasNoForeignKeyColumns(); - - var joinTable = databaseMapping.Database.EntityTypes.ElementAt(1); - Assert.Equal("SRDerivedSRDeriveds", databaseMapping.Database.GetEntitySet(joinTable).Table); - Assert.True( - joinTable.Properties.Select(x => x.Name).SequenceEqual( - new[] - { - "SRDerived_Key1", "SRDerived_Key2", - "SRDerived_Key11", "SRDerived_Key21" - })); - } - - [Fact] - public void TPC_with_abstract_base_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - m => - { - m.MapInheritedProperties(); - m.ToTable("Agencies"); - }) - .Map( - m => - { - m.MapInheritedProperties(); - m.ToTable("People"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Column_type_configuration_on_non_root_type_is_propagated_to_derived_types() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Property(e => e.Info).HasColumnType("varchar(max)"); - modelBuilder.Entity().Map( - m => { m.ToTable("Table1"); }); - modelBuilder.Entity().Map( - m => - { - m.MapInheritedProperties(); - m.ToTable("Table2"); - }); - modelBuilder.Entity().Map( - m => - { - m.MapInheritedProperties(); - m.ToTable("Table3"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Table2") - .DbEqual("varchar(max)", t => t.Properties.Single(c => c.Name == "Info").TypeName); - databaseMapping.Assert("Table3") - .DbEqual("varchar(max)", t => t.Properties.Single(c => c.Name == "Info").TypeName); - } - - [Fact] - public void Column_name_configuration_on_non_root_type_is_propagated_to_derived_types() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Property(e => e.Name).HasColumnName("NameOfProduct"); - modelBuilder.Entity().ToTable("Products"); - modelBuilder.Entity().Map(mapping => { mapping.MapInheritedProperties(); }). - ToTable("ClearanceProduct"); - modelBuilder.Entity().Map(mapping => { mapping.MapInheritedProperties(); }) - .ToTable("DiscontinuedProduct"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Products") - .DbEqual(true, t => t.Properties.Any(c => c.Name == "NameOfProduct")); - databaseMapping.Assert("ClearanceProduct") - .DbEqual(true, t => t.Properties.Any(c => c.Name == "NameOfProduct")); - } - - [Fact] - public void Abstract_principal_can_be_mapped_with_TPC() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - modelBuilder.Entity() - .Map(mc => { mc.MapInheritedProperties(); }) - .ToTable("Accounts"); - - modelBuilder.Entity() - .Map(mc => { mc.MapInheritedProperties(); }) - .ToTable("Contacts"); - - modelBuilder.Entity().HasRequired(o => o.BillToCustomer).WithMany(c => c.Orders). - HasForeignKey(o => o.BillToCustomerId); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - } - - #endregion - - #region Hybrid - - [Fact] - public void Can_move_one_type_to_TPT_in_TPH_hierarchy() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Woof"); - modelBuilder.Entity().ToTable("TableC"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Woof") - .HasColumns("Id", "RootData", "AData", "BData", "Discriminator"); - databaseMapping.Assert("TableC") - .HasColumns("Id", "CData") - .HasForeignKeyColumn("Id"); - databaseMapping.AssertMapping("Woof", true) - .HasNoPropertyConditions() - .HasNoColumnConditions(); - databaseMapping.AssertMapping("Woof", false) - .HasNoPropertyConditions() - .HasColumnCondition("Discriminator", "TPHRoot"); - databaseMapping.AssertMapping("Woof") - .HasNoPropertyConditions() - .HasColumnCondition("Discriminator", "TPHNodeA"); - databaseMapping.AssertMapping("Woof") - .HasNoPropertyConditions() - .HasColumnCondition("Discriminator", "TPHNodeB"); - databaseMapping.AssertMapping("TableC") - .HasNoPropertyConditions() - .HasNoColumnConditions(); - } - - [Fact] - public void Mix_TPH_and_TPT_by_mapping_one_middle_type_to_TPH() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Base"); - modelBuilder.Entity(); - modelBuilder.Entity().ToTable("L1B"); - modelBuilder.Entity().ToTable("L2"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Base") - .HasColumns("Id", "BaseData", "L1AData", "Discriminator"); - databaseMapping.AssertMapping("Base", false) - .HasColumnCondition("Discriminator", "HybridBase"); - databaseMapping.Assert("Base") - .HasColumns("Id", "BaseData", "L1AData", "Discriminator"); - databaseMapping.AssertMapping("Base") - .HasColumnCondition("Discriminator", "HybridL1A"); - - databaseMapping.Assert("L1B") - .HasColumns("Id", "L1BData"); - databaseMapping.AssertMapping("L1B") - .HasNoColumnConditions(); - - databaseMapping.Assert("L2") - .HasColumns("Id", "L2Data"); - databaseMapping.AssertMapping("L2") - .HasNoColumnConditions(); - } - - [Fact] - public void Mix_TPH_and_TPT_by_mapping_one_middle_type_to_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Base"); - modelBuilder.Entity().ToTable("A"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Base") - .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); - databaseMapping.AssertMapping("Base", false) - .HasColumnCondition("Discriminator", "HybridBase"); - - databaseMapping.Assert("A") - .HasColumns("Id", "L1AData"); - databaseMapping.AssertMapping("A") - .HasNoColumnConditions(); - - databaseMapping.Assert("Base") - .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); - databaseMapping.AssertMapping("Base") - .HasColumnCondition("Discriminator", "HybridL1B"); - - databaseMapping.Assert("Base") - .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); - databaseMapping.AssertMapping("Base") - .HasColumnCondition("Discriminator", "HybridL2"); - } - - [Fact] - public void Mix_TPH_and_TPT_by_mapping_one_middle_type_to_TPT_with_derived_type_configuration() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Base"); - modelBuilder.Entity().ToTable("A"); - modelBuilder.Entity().Map(mc => { }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Base") - .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); - databaseMapping.AssertMapping("Base", false) - .HasColumnCondition("Discriminator", "HybridBase"); - - databaseMapping.Assert("A") - .HasColumns("Id", "L1AData"); - databaseMapping.AssertMapping("A") - .HasNoColumnConditions(); - - databaseMapping.Assert("Base") - .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); - databaseMapping.AssertMapping("Base") - .HasColumnCondition("Discriminator", "HybridL1B"); - - databaseMapping.Assert("Base") - .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); - databaseMapping.AssertMapping("Base") - .HasColumnCondition("Discriminator", "HybridL2"); - } - - [Fact] - public void Mix_TPH_and_TPT_by_mapping_one_middle_type_to_TPT_using_attribute() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mapping => { mapping.Requires("luqkau").HasValue("1"); }) - .Map(mapping => { mapping.Requires("luqkau").HasValue("2"); }) - .Map(mapping => { mapping.Requires("luqkau").HasValue("3"); }) - .ToTable("A1"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Mix_TPH_and_TPC_by_mapping_one_middle_type_to_TPC() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity() - .Map( - mc => - { - mc.MapInheritedProperties(); - mc.ToTable("L1"); - }); - modelBuilder.Entity(); - modelBuilder.Entity(); - - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Mix_TPH_and_TPC_by_mapping_both_middle_types_to_TPC() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity() - .Map( - mc => - { - mc.MapInheritedProperties(); - mc.ToTable("L1A"); - }); - modelBuilder.Entity() - .Map( - mc => - { - mc.MapInheritedProperties(); - mc.ToTable("L1B"); - }); - modelBuilder.Entity(); - - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Mix_TPH_and_TPC_and_TPT_by_mapping_one_middle_type_to_TPC_and_one_middle_type_to_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity() - .Map( - mc => - { - mc.MapInheritedProperties(); - mc.ToTable("L1A"); - }); - modelBuilder.Entity() - .Map(mc => { mc.ToTable("L1B"); }); - modelBuilder.Entity(); - - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Mix_TPH_and_TPT_by_mapping_middle_type_to_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity() - .Map(mc => { mc.ToTable("L1"); }); - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("HybridBases") - .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); - databaseMapping.AssertMapping("HybridBases", true) - .HasNoColumnConditions(); - databaseMapping.AssertMapping("HybridBases", false) - .HasColumnCondition("Discriminator", "HybridBase"); - databaseMapping.Assert("L1") - .HasColumns("Id", "L1AData"); - databaseMapping.AssertMapping("L1") - .HasNoColumnConditions(); - databaseMapping.Assert("HybridBases") - .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); - databaseMapping.AssertMapping("HybridBases") - .HasColumnCondition("Discriminator", "HybridL1B"); - databaseMapping.Assert("HybridBases") - .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); - databaseMapping.AssertMapping("HybridBases") - .HasColumnCondition("Discriminator", "HybridL2"); - } - - [Fact] - public void Can_alternate_abstract_in_TPH_hierarchy() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("ACrazies") - .HasColumns("Id", "A", "B", "C", "D", "E", "Discriminator"); - - databaseMapping.AssertMapping("ACrazies", false) - .HasColumnCondition("Discriminator", "ACrazy"); - - databaseMapping.AssertNoMapping(); - - databaseMapping.AssertMapping("ACrazies", false) - .HasColumnCondition("Discriminator", "CCrazy"); - - databaseMapping.AssertNoMapping(); - - databaseMapping.AssertMapping("ACrazies", false) - .HasColumnCondition("Discriminator", "ECrazy"); - } - - [Fact] - public void Can_alternate_abstract_in_TPH_hierarchy_with_extra_TPT_leaf() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity().ToTable("Tx"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("ACrazies") - .HasColumns("Id", "A", "B", "C", "D", "E", "Discriminator"); - - databaseMapping.Assert("Tx") - .HasColumns("Id", "X"); - - databaseMapping.AssertMapping("ACrazies", true) - .HasNoColumnConditions(); - databaseMapping.AssertMapping("ACrazies", false) - .HasColumnCondition("Discriminator", "ACrazy"); - - databaseMapping.AssertNoMapping(); - - databaseMapping.AssertMapping("ACrazies", false) - .HasColumnCondition("Discriminator", "CCrazy"); - - databaseMapping.AssertNoMapping(); - - databaseMapping.AssertMapping("ACrazies", false) - .HasColumnCondition("Discriminator", "ECrazy"); - - databaseMapping.AssertMapping("Tx", false) - .HasNoColumnConditions(); - } - - [Fact] - // Regression for 142318 - public void Can_have_TPH_alone_at_base_of_3_level_heirarchy() - { - // E1 -- TPH alone - // / | \ - // E2 E3 E4 -- all TPC - // / - // E5 -- TPT to E2 - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Entity1"); - mapping.Requires( - "aduvbkqcgjqomqpyniiftbsqzzeehyhyddqlbdtmhvmdnoktgjbylbqumovbhn") - .HasValue("true").HasColumnType("varchar(max)"); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Entity4"); - mapping.MapInheritedProperties(); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Entity2"); - mapping.MapInheritedProperties(); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Entity5"); - mapping.Requires("rdfmyypkivldry").HasValue(-10).HasColumnType( - "bigint"); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Entity3"); - mapping.MapInheritedProperties(); - }); - modelBuilder.Entity().Property(p => p.Entity1_Col1).HasColumnType("smallint"); - modelBuilder.Entity().Property(p => p.Entity1_Col2).HasColumnType("datetime2"); - modelBuilder.Entity().Property(p => p.Entity1_Col3).HasColumnType("binary").HasMaxLength(10). - IsFixedLength(); - modelBuilder.Entity().Property(p => p.Id).IsRequired().HasColumnType("char").HasMaxLength(20). - IsFixedLength(); - modelBuilder.Entity().Property(p => p.Entity2_Col1).HasColumnType("smalldatetime"); - modelBuilder.Entity().Property(p => p.Entity3_Col1).IsRequired().HasColumnType("ntext").IsUnicode(); - modelBuilder.Entity().Property(p => p.Entity3_Col2).HasColumnType("datetimeoffset"); - modelBuilder.Entity().Property(p => p.Entity4_Col1).HasColumnType("bigint"); - modelBuilder.Entity().Property(p => p.Entity4_Col2).HasColumnType("varchar(max)"); - modelBuilder.Entity().Property(p => p.Entity5_Col1).HasColumnType("bit"); - modelBuilder.Entity().Property(p => p.Entity5_Col2).HasColumnType("smalldatetime"); - modelBuilder.Entity().Property(p => p.Entity5_Col3).HasColumnType("time"); - modelBuilder.Entity().Property(p => p.Entity5_Col4).HasColumnType("decimal").HasPrecision(28, 4); - modelBuilder.Entity().Property(p => p.Entity5_Col5).HasColumnType("date"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Mixed_TPH_and_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mapping => { mapping.ToTable("A1"); }) - .Map(mapping => { mapping.ToTable("A3"); }) - .Map(mapping => { mapping.ToTable("A4"); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Mixed_TPH_and_TPC_with_TPC_has_nullable_discriminator() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mapping => { mapping.ToTable("A1"); }).Map( - mapping => - { - mapping.ToTable("A3"); - mapping.MapInheritedProperties(); - }).Map( - mapping => - { - mapping.ToTable("A4"); - mapping.MapInheritedProperties(); - }); - - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Mixed_TPH_and_TPC_and_TPT_has_nullable_discriminator() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mapping => { mapping.ToTable("A1"); }).Map( - mapping => - { - mapping.ToTable("A3"); - mapping.MapInheritedProperties(); - }).Map(mapping => { mapping.ToTable("A4"); }); - - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void TPC_under_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("T1"); - modelBuilder.Entity().ToTable("T2"); - modelBuilder.Entity().ToTable("T3"); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("T4"); - mapping.MapInheritedProperties(); - }); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - #endregion - - #region Entity Splitting - - [Fact] - public void Setting_all_Properties_does_not_trigger_entity_splitting() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.Name, - a.BaseData - }); - mc.ToTable("Tbl"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - Assert.Equal(1, databaseMapping.Database.EntityTypes.Count()); - } - - [Fact] - public void Entity_split_single_type_including_pks() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.Name - }); - mc.ToTable("NameTbl"); - }) - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.BaseData - }); - mc.ToTable("DataTbl"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("NameTbl") - .HasColumns("Id", "Name") - .DbEqual( - StoreGeneratedPattern.Identity, - t => t.Properties.Single(c => c.Name == "Id").StoreGeneratedPattern); - databaseMapping.Assert("DataTbl") - .HasColumns("Id", "BaseData") - .HasForeignKeyColumn("Id", "NameTbl") - .DbEqual(StoreGeneratedPattern.None, t => t.Properties.Single(c => c.Name == "Id").StoreGeneratedPattern); - } - - [Fact] - public void Entity_split_single_type_without_specifying_table_name() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - Assert.Throws( - () => - modelBuilder.Entity() - .Map( - mc => mc.Properties( - a => new - { - a.Id, - a.Name - })) - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.BaseData - }); - mc.ToTable("DataTbl"); - })); - } - - [Fact] - public void Entity_split_single_type_not_including_pks() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - a => new - { - a.Name - }); - mc.ToTable("NameTbl"); - }) - .Map( - mc => - { - mc.Properties( - a => new - { - a.BaseData - }); - mc.ToTable("DataTbl"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - Assert.Equal(2, databaseMapping.Database.EntityTypes.Count()); - Assert.Equal( - 2, - databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.ElementAt(0). - MappingFragments.Count); - databaseMapping.Assert("NameTbl").HasColumns("Id", "Name"); - databaseMapping.Assert("DataTbl").HasColumns("Id", "BaseData"); - } - - [Fact] - public void Empty_properties_call_in_middle_makes_extra_fragments() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.Name - }); - mc.ToTable("NameTbl"); - }) - .Map( - mc => - { - mc.Properties( - a => new - { - }); - mc.ToTable("Empty"); - }) - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.BaseData - }); - mc.ToTable("DataTbl"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - Assert.Equal(3, databaseMapping.Database.EntityTypes.Count()); - Assert.Equal( - 3, - databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.ElementAt(0). - MappingFragments.Count); - databaseMapping.Assert("NameTbl").HasColumns("Id", "Name"); - databaseMapping.Assert("DataTbl").HasColumns("Id", "BaseData"); - databaseMapping.Assert("Empty").HasColumns("Id"); - } - - [Fact] - public void Mapping_property_twice_throws() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.Name - }); - mc.ToTable("NameTbl"); - }) - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.BaseData, - a.Name - }); - mc.ToTable("DataTbl"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Ignore(); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Mapping_subtype_twice_chained_throws() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => { }); - - Assert.Throws( - () => - modelBuilder.Entity() - .Map(mc => { })); - - modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - } - - [Fact] - public void Mapping_subtype_twice_throws() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => mc.ToTable("derived")); - - modelBuilder.Entity() - .Map(mc => mc.ToTable("deriveds")); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Mapping_property_again_after_everything_mapped_throws() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.Name, - a.BaseData - }); - mc.ToTable("AssocBase"); - }) - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.Name - }); - mc.ToTable("Other"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Ignore(); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Mapping_inherited_properties_after_everything_mapped_throws() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.Name, - a.BaseData - }); - mc.ToTable("AssocBase"); - }) - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.Name - }); - mc.ToTable("Other"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Ignore(); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Mapping_all_properties_after_everything_mapped_throws() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => mc.ToTable("AssocBase")) - .Map(mc => mc.ToTable("Other")); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Ignore(); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Mapping_inherited_properties_twice_throws() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - mc => - { - mc.MapInheritedProperties(); - mc.ToTable("One"); - }) - .Map( - mc => - { - mc.MapInheritedProperties(); - mc.ToTable("Two"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Entity().Ignore(b => b.AssocRelated); - modelBuilder.Entity().Ignore(b => b.AssocRelatedId); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Empty_properties_call_at_end_makes_extra_fragments() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.Name - }); - mc.ToTable("NameTbl"); - }) - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.BaseData - }); - mc.ToTable("DataTbl"); - }) - .Map( - mc => - { - mc.Properties( - a => new - { - }); - mc.ToTable("Empty"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - Assert.Equal(3, databaseMapping.Database.EntityTypes.Count()); - Assert.Equal( - 3, - databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.ElementAt(0). - MappingFragments.Count); - databaseMapping.Assert("NameTbl").HasColumns("Id", "Name"); - databaseMapping.Assert("DataTbl").HasColumns("Id", "BaseData"); - databaseMapping.Assert("Empty").HasColumns("Id"); - } - - [Fact] - public void Properties_with_only_PK_creates_extra_fragment() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.Name - }); - mc.ToTable("NameTbl"); - }) - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id - }); - mc.ToTable("Empty"); - }) - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.BaseData - }); - mc.ToTable("DataTbl"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("NameTbl").HasColumns("Id", "Name"); - databaseMapping.Assert("DataTbl").HasColumns("Id", "BaseData"); - databaseMapping.Assert("Empty").HasColumns("Id"); - } - - [Fact] - public void Entity_split_derived_type_with_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Bases"); - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.DerivedData1 - }); - mc.ToTable("Deriveds1"); - }) - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.DerivedData2 - }); - mc.ToTable("Deriveds2"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Entity().Ignore(d => d.AssocRelated); - modelBuilder.Entity().Ignore(d => d.AssocRelatedId); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert().HasColumns("Id", "Name", "BaseData"); - databaseMapping.Assert("Deriveds1").HasColumns("Id", "DerivedData1"); - databaseMapping.Assert("Deriveds2").HasColumns("Id", "DerivedData2"); - } - - [Fact] - public void Entity_split_base_type_with_derived_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.Name - }); - mc.ToTable("NameTbl"); - }) - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.BaseData - }); - mc.ToTable("DataTbl"); - }); - modelBuilder.Entity().ToTable("Deriveds"); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Entity().Ignore(d => d.AssocRelated); - modelBuilder.Entity().Ignore(d => d.AssocRelatedId); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert().HasColumns("Id", "DerivedData1", "DerivedData2"); - databaseMapping.Assert("NameTbl").HasColumns("Id", "Name"); - databaseMapping.Assert("DataTbl").HasColumns("Id", "BaseData"); - } - - [Fact] - public void Entity_split_derived_type_with_TPC() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Bases"); - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.DerivedData1 - }); - mc.ToTable("Deriveds1"); - }) - .Map( - mc => - { - mc.MapInheritedProperties(); - mc.Properties( - a => new - { - a.Id, - a.DerivedData2 - }); - mc.ToTable("Deriveds2"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Entity().Ignore(d => d.AssocRelated); - modelBuilder.Entity().Ignore(d => d.AssocRelatedId); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert().HasColumns("Id", "Name", "BaseData"); - databaseMapping.Assert("Deriveds1").HasColumns("Id", "DerivedData1"); - databaseMapping.Assert("Deriveds2").HasColumns("Id", "Name", "BaseData", "DerivedData2"); - } - - [Fact] - public void Entity_split_base_type_with_derived_TPC() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.Name - }); - mc.ToTable("NameTbl"); - }) - .Map( - mc => - { - mc.Properties( - a => new - { - a.Id, - a.BaseData - }); - mc.ToTable("DataTbl"); - }); - modelBuilder.Entity() - .Map( - mc => - { - mc.MapInheritedProperties(); - mc.ToTable("Deriveds"); - }); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); - modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); - modelBuilder.Entity().Ignore(d => d.AssocRelated); - modelBuilder.Entity().Ignore(d => d.AssocRelatedId); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert().HasColumns("Id", "Name", "BaseData", "DerivedData1", "DerivedData2"); - databaseMapping.Assert("NameTbl").HasColumns("Id", "Name"); - databaseMapping.Assert("DataTbl").HasColumns("Id", "BaseData"); - } - - [Fact] - public void Entity_split_base_type_with_derived_TPT_with_abstract_middle_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Properties( - e => new - { - e.Name, - e.Description, - }); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table2"); - mapping.Properties(e => e.Photo); - }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Table3"); }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Table4"); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Table1") - .HasColumns("Id", "Description", "Name"); - databaseMapping.Assert("Table2") - .HasColumns("Id", "Photo") - .HasForeignKeyColumn("Id", "Table1"); - databaseMapping.Assert("Table3") - .HasColumns("Id", "Details") - .HasForeignKeyColumn("Id", "Table1"); - databaseMapping.Assert("Table4") - .HasColumns("Id", "Color") - .HasForeignKeyColumn("Id", "Table3"); - } - - [Fact] - public void Entity_split_base_type_with_derived_TPH_with_abstract_base_with_duplicate_property_throws() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Requires("discriminator").HasValue("Entity1_1"); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Properties(e => e.Property4); - mapping.Requires("discriminator").HasValue("Entity1_2"); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table2"); - mapping.Properties(e => e.Property6); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table3"); - mapping.Properties(e => e.Property6); - }); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Entity_split_base_type_with_derived_TPH_with_abstract_base() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Requires("discriminator").HasValue("Entity1_1"); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Properties(e => e.Property4); - mapping.Requires("discriminator").HasValue("Entity1_2"); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table2"); - mapping.Properties(e => e.Property5); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table3"); - mapping.Properties(e => e.Property6); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Table1") - .HasColumns( - "Id", "Photo", "Description", "Name", "Property1", "Property2", "Property3", "Property4", - "discriminator"); - databaseMapping.Assert("Table1") - .HasColumns( - "Id", "Photo", "Description", "Name", "Property1", "Property2", "Property3", "Property4", - "discriminator"); - databaseMapping.Assert("Table2") - .HasColumns("Id", "Property5"); - databaseMapping.Assert("Table3") - .HasColumns("Id", "Property6"); - } - - [Fact] - public void Entity_split_base_type_with_a_complex_type_in_TPH() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Requires("d").HasValue("EntityC1"); - mapping.Properties(e => e.Property2); - mapping.Properties(e => e.ComplexProperty1.P2); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table2"); - mapping.Properties(e => e.ComplexProperty1.P1); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Requires("d").HasValue("EntityC1_1"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Table1") - .HasColumns("Id", "ComplexProperty1_P2", "Property2", "Property3", "Property4", "d"); - - databaseMapping.Assert("Table2") - .HasColumns("Id", "ComplexProperty1_P1"); - - databaseMapping.AssertMapping("Table1", false) - .HasColumnCondition("d", "EntityC1"); - - databaseMapping.AssertMapping("Table1", true) - .HasNoColumnConditions(); - - databaseMapping.Assert("Table1") - .HasColumns("Id", "ComplexProperty1_P2", "Property2", "Property3", "Property4", "d"); - - databaseMapping.AssertMapping("Table1", false) - .HasColumnCondition("d", "EntityC1_1"); - } - - [Fact] - public void Entity_split_middle_type_in_TPH() - { - var builder = new AdventureWorksModelBuilder(); - - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Requires("d").HasValue("EntityB1"); - }); - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Properties(e => e.Property1); - mapping.Requires("d").HasValue("EntityB1_1"); - }); - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table2"); - mapping.Properties( - e => new - { - e.Property2, - e.Property3 - }); - }); - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Requires("d").HasValue("EntityB1_1_1"); - }); - - builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo, true); - } - - [Fact] - public void Entity_split_middle_type_in_TPH2() - { - var builder = new AdventureWorksModelBuilder(); - - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Requires("d").HasValue("EntityB1"); - }); - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Properties(e => e.Property1); - mapping.Requires("d").HasValue("EntityB1_1"); - }); - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table2"); - mapping.Properties( - e => new - { - e.Property2, - e.Property3 - }); - }); - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Requires("d").HasValue("EntityB1_1_1"); - }); - - var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Entity_splitting_maintains_configured_composite_key_ordering() - { - var builder = new AdventureWorksModelBuilder(); - - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Properties(e => e.Property1); - }); - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table2"); - mapping.Properties(e => e.Property2); - }); - builder.Entity().HasKey( - e => new - { - e.Key2, - e.Key1, - }); - - var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Table1") - .HasColumns("Key1", "Key2", "Property1"); - databaseMapping.Assert("Table2") - .HasColumns("Key1", "Key2", "Property2") - .HasForeignKey(new[] { "Key1", "Key2" }, "Table1"); - } - - [Fact] - public void Entity_splitting_derived_table_creates_FK_to_first_table() - { - var builder = new AdventureWorksModelBuilder(); - - builder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table2"); - mapping.Properties( - e => new - { - e.Property1, - e.Property2 - }); - mapping.Properties(e => e.Property3); - }); - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table3"); - mapping.Properties(e => e.Property4); - }); - - var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Table1") - .HasNoForeignKeyColumns(); - - databaseMapping.Assert("Table2") - .HasNoForeignKeyColumns(); - - databaseMapping.Assert("Table3") - .HasForeignKeyColumn("Id", "Table2"); - } - - [Fact] - public void Entity_splitting_derived_TPC_creates_FK_to_first_table() - { - var builder = new AdventureWorksModelBuilder(); - - builder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table2"); - mapping.Properties( - e => new - { - e.Property1, - e.Property3 - }); - }); - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table3"); - mapping.Properties( - e => new - { - e.Property2, - e.Property4 - }); - }); - - var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Table1") - .HasNoForeignKeyColumns(); - - databaseMapping.Assert("Table2") - .HasNoForeignKeyColumns(); - - databaseMapping.Assert("Table3") - .HasForeignKeyColumn("Id", "Table2"); - } - - [Fact] - public void Entity_splitting_all_inherited_props_in_derived_TPC_creates_FK_to_first_table() - { - var builder = new AdventureWorksModelBuilder(); - - builder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table2"); - mapping.Properties( - e => new - { - e.Property3, - e.Property4 - }); - }); - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table3"); - mapping.Properties( - e => new - { - e.Property1, - e.Property2 - }); - }); - - var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Table1") - .HasNoForeignKeyColumns(); - - databaseMapping.Assert("Table2") - .HasNoForeignKeyColumns(); - - databaseMapping.Assert("Table3") - .HasForeignKeyColumn("Id", "Table2"); - } - - [Fact] - public void Entity_splitting_derived_TPT_creates_FK_to_first_table() - { - var builder = new AdventureWorksModelBuilder(); - - builder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table2"); - mapping.Properties( - e => new - { - e.Property3 - }); - }); - builder.Entity().Map( - mapping => - { - mapping.ToTable("Table3"); - mapping.Properties( - e => new - { - e.Property4 - }); - }); - - var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert("Table1") - .HasNoForeignKeyColumns(); - - databaseMapping.Assert("Table2") - .HasForeignKeyColumn("Id", "Table1") - .DbEqual(1, t => t.ForeignKeyBuilders.Count()); - - databaseMapping.Assert("Table3") - .HasForeignKeyColumn("Id", "Table2") - .DbEqual(1, t => t.ForeignKeyBuilders.Count()); - } - - [Fact] - public void Entity_splitting_names_store_entity_types_and_sets_properly() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - a => new - { - a.IntProp - }); - mc.ToTable("Tbl"); - }) - .Map( - mc => - { - mc.Properties( - a => new - { - a.StringProp - }); - mc.ToTable("Tbl2"); - }).Map( - mc => - { - mc.Properties( - a => new - { - a.ByteArrayProp, - a.DateTimeProp, - a.DecimalProp - }); - mc.ToTable("Tbl3"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - var mws = databaseMapping.ToMetadataWorkspace(); - - var itemCollection = mws.GetItemCollection(DataSpace.SSpace) as StoreItemCollection; - - Assert.NotNull(itemCollection.GetItem("CodeFirstDatabaseSchema.TypeClass")); - Assert.NotNull(itemCollection.GetItem("CodeFirstDatabaseSchema.TypeClass1")); - Assert.NotNull(itemCollection.GetItem("CodeFirstDatabaseSchema.TypeClass2")); - } - - #endregion - - #region Table Splitting - - [Fact] - public void One_to_one_relationship_can_share_table() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().Ignore(x => x.TSItemDetailDiffKey); - modelBuilder.Entity().Ignore(x => x.TSItemDetailOverlappingProperty); - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().HasRequired(i => i.TSItemDetail).WithRequiredPrincipal(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Items").DbEqual(3, t => t.Properties.Count); - databaseMapping.Assert("Items").DbEqual(0, t => t.ForeignKeyBuilders.Count()); - databaseMapping.Assert("Items").HasColumns("Id", "Name", "Detail"); - } - - [Fact] - // Regression test for Dev 11 bug 86852 - public void Table_split_with_conflicting_key_column_order_throws() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().Ignore(x => x.TSItemDetailDiffKey); - modelBuilder.Entity().Ignore(x => x.TSItemDetailOverlappingProperty); - modelBuilder.Entity().HasKey( - c => new - { - c.Id, - c.Name - }); - modelBuilder.Entity().Property(i => i.Id).HasColumnOrder(1); - modelBuilder.Entity().Property(i => i.Name).HasColumnOrder(2); - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().HasKey( - c => new - { - c.Id, - c.Detail - }); - modelBuilder.Entity().Property(i => i.Id).HasColumnOrder(2); - modelBuilder.Entity().Property(i => i.Detail).HasColumnOrder(1); - modelBuilder.Entity().HasRequired(i => i.TSItemDetail).WithRequiredPrincipal(); - - Assert.Throws( - () => - modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Table_split_with_conflicting_primary_key_columnType_throws() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().Ignore(x => x.TSItemDetailDiffKey); - modelBuilder.Entity().Ignore(x => x.TSItemDetailOverlappingProperty); - modelBuilder.Entity().Property(i => i.Id).HasColumnType("nvarchar(max)"); - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().Property(i => i.Id).HasColumnType("ntext"); - modelBuilder.Entity().HasRequired(i => i.TSItemDetail).WithRequiredPrincipal(); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Table_split_with_different_primary_key_name_uses_principal_name() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().Ignore(x => x.TSItemDetail); - modelBuilder.Entity().Ignore(x => x.TSItemDetailOverlappingProperty); - modelBuilder.Entity().HasKey(x => x.DiffId); - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().HasRequired(i => i.TSItemDetailDiffKey).WithRequiredPrincipal(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Items").DbEqual(3, t => t.Properties.Count); - databaseMapping.Assert("Items").DbEqual(0, t => t.ForeignKeyBuilders.Count()); - databaseMapping.Assert("Items").HasColumns("Id", "Name", "Detail"); - } - - [Fact] - public void Table_split_with_different_primary_key_property_name_that_is_mapped_to_same_column_name() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().Ignore(x => x.TSItemDetail); - modelBuilder.Entity().Ignore(x => x.TSItemDetailOverlappingProperty); - modelBuilder.Entity().HasKey(x => x.DiffId); - modelBuilder.Entity().Property(x => x.DiffId).HasColumnName("Id"); - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().HasRequired(i => i.TSItemDetailDiffKey).WithRequiredPrincipal(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Items").DbEqual(3, t => t.Properties.Count); - databaseMapping.Assert("Items").DbEqual(0, t => t.ForeignKeyBuilders.Count()); - databaseMapping.Assert("Items").HasColumns("Id", "Name", "Detail"); - } - - [Fact] - public void Table_split_with_different_primary_key_property_name_that_is_mapped_to_new_column_name() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().Ignore(x => x.TSItemDetail); - modelBuilder.Entity().Ignore(x => x.TSItemDetailOverlappingProperty); - modelBuilder.Entity().HasKey(x => x.DiffId); - modelBuilder.Entity().Property(x => x.DiffId).HasColumnName("Foo"); - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().HasRequired(i => i.TSItemDetailDiffKey).WithRequiredPrincipal(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Items").DbEqual(3, t => t.Properties.Count); - databaseMapping.Assert("Items").DbEqual(0, t => t.ForeignKeyBuilders.Count()); - databaseMapping.Assert("Items").HasColumns("Foo", "Name", "Detail"); - } - - [Fact] - public void Table_split_with_overlapping_property_name() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().Ignore(x => x.TSItemDetail); - modelBuilder.Entity().Ignore(x => x.TSItemDetailDiffKey); - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().HasRequired(i => i.TSItemDetailOverlappingProperty).WithRequiredPrincipal(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert("Items").HasColumns("Id", "Name", "Name1"); - } - - [Fact] - public void Table_split_with_overlapping_property_name_that_has_been_renamed() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().Ignore(x => x.TSItemDetail); - modelBuilder.Entity().Ignore(x => x.TSItemDetailDiffKey); - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().Property(x => x.Name).HasColumnName("OtherName"); - modelBuilder.Entity().HasRequired(i => i.TSItemDetailOverlappingProperty).WithRequiredPrincipal(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Items").DbEqual(3, t => t.Properties.Count); - databaseMapping.Assert("Items").DbEqual(0, t => t.ForeignKeyBuilders.Count()); - databaseMapping.Assert("Items").HasColumns("Id", "Name", "OtherName"); - } - - [Fact] - public void Table_split_with_IA_one_to_one_relationship_throws() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().ToTable("Items"); - modelBuilder.Entity().HasRequired(i => i.Detail).WithRequiredPrincipal(); - - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("EntityMappingConfiguration_InvalidTableSharing", "TSIAItemDetail", "TSIAItem", "Items"); - } - - [Fact] - public void Table_split_base_on_TPH() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map( - mc => - { - mc.ToTable("TS"); - mc.Requires("disc").HasValue("TSBase"); - }); - modelBuilder.Entity().Map( - mc => - { - mc.ToTable("TS"); - mc.Requires("disc").HasValue("TSDerived"); - }); - modelBuilder.Entity().Ignore(x => x.Detail); - modelBuilder.Entity().Map(mc => { mc.ToTable("TS"); }); - modelBuilder.Entity().HasRequired(i => i.BaseDetail).WithRequiredPrincipal(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - databaseMapping.Assert("TS").HasColumns("Id", "BaseData", "DerivedData", "disc", "BaseDetail"); - databaseMapping.Assert("TS").HasColumns("Id", "BaseData", "DerivedData", "disc", "BaseDetail"); - databaseMapping.Assert("TS").HasColumns("Id", "BaseData", "DerivedData", "disc", "BaseDetail"); - } - - [Fact] - public void Table_split_base_on_default_TPH() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity().Ignore(x => x.Detail); - modelBuilder.Entity().Map(mc => { mc.ToTable("TSBase"); }); - modelBuilder.Entity().HasRequired(i => i.BaseDetail).WithRequiredPrincipal(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - databaseMapping.Assert("TSBase").HasColumns( - "Id", "BaseData", "DerivedData", "Discriminator", - "BaseDetail"); - databaseMapping.Assert("TSBase").HasColumns( - "Id", "BaseData", "DerivedData", "Discriminator", - "BaseDetail"); - databaseMapping.Assert("TSBase").HasColumns( - "Id", "BaseData", "DerivedData", "Discriminator", - "BaseDetail"); - } - - [Fact] - public void Table_split_base_on_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mc => { mc.ToTable("A"); }); - modelBuilder.Entity().Map(mc => { mc.ToTable("A"); }); - modelBuilder.Entity().Map(mc => { mc.ToTable("B"); }); - modelBuilder.Entity().Ignore(x => x.Detail); - modelBuilder.Entity().HasRequired(i => i.BaseDetail).WithRequiredPrincipal(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - databaseMapping.Assert("A").HasColumns("Id", "BaseData", "BaseDetail"); - databaseMapping.Assert("B").HasColumns("Id", "DerivedData"); - databaseMapping.Assert("A").HasColumns("Id", "BaseData", "BaseDetail"); - } - - [Fact] - public void Table_split_base_on_TPT_2() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Vehicle"); }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Car"); }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Vehicle"); }); - modelBuilder.Entity().HasRequired(e => e.Repro140107_Model).WithRequiredPrincipal( - e => e.Repro140107_Vehicle); - modelBuilder.Entity().HasRequired(e => e.Repro140107_Vehicle).WithRequiredDependent( - e => e.Repro140107_Model); - modelBuilder.Entity().Property(p => p.Repro140107_VehicleId).HasColumnType("int"); - modelBuilder.Entity().Property(p => p.Name).HasColumnType("smallint"); - modelBuilder.Entity().Property(p => p.Type).HasColumnType("bigint"); - modelBuilder.Entity().Property(p => p.Repro140107_ModelId).HasColumnType("int"); - modelBuilder.Entity().Property(p => p.Description).HasColumnType("bit"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - } - - [Fact] - // Doesn't work due to an EF bug - public void Table_split_base_on_TPC() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mc => { mc.ToTable("A"); }); - modelBuilder.Entity().Map(mc => { mc.ToTable("A"); }); - modelBuilder.Entity().Map( - mc => - { - mc.MapInheritedProperties(); - mc.ToTable("B"); - }); - modelBuilder.Entity().Ignore(x => x.Detail); - - modelBuilder.Entity().HasRequired(i => i.BaseDetail).WithRequiredPrincipal(); - - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo, true)); - } - - [Fact] - // Doesn't work due to an EF bug - public void Table_split_base_on_TPC_2() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Vehicle"); }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Car"); - mapping.MapInheritedProperties(); - }); - modelBuilder.Entity().ToTable("Vehicle"); - modelBuilder.Entity().HasRequired(e => e.Model).WithRequiredPrincipal( - e => e.Repro140106_Vehicle); - modelBuilder.Entity().HasRequired(e => e.Repro140106_Vehicle).WithRequiredDependent( - e => e.Model); - modelBuilder.Entity().Property(p => p.Repro140106_VehicleId).IsRequired().HasColumnType - ("nvarchar").HasMaxLength(40).IsUnicode().IsVariableLength(); - modelBuilder.Entity().Property(p => p.Name).HasColumnType("nvarchar(max)").IsUnicode(); - modelBuilder.Entity().Property(p => p.Type).IsRequired().HasColumnType("text"); - modelBuilder.Entity().Property(p => p.Repro140106_ModelId).IsRequired().HasColumnType( - "nvarchar").HasMaxLength(40).IsUnicode().IsVariableLength(); - modelBuilder.Entity().Property(p => p.Description).HasColumnType("numeric").HasPrecision( - 15, 5); - - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo, true)); - } - - [Fact] - // Doesn't work due to an EF bug - public void Table_split_base_on_TPC_has_no_FK_to_base_and_table_split_entity_props_not_inherited() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Vehicle"); }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Car"); - mapping.MapInheritedProperties(); - }); - modelBuilder.Entity().ToTable("Vehicle"); - modelBuilder.Entity().HasRequired(e => e.TPCModel).WithRequiredPrincipal(e => e.TPCVehicle); - modelBuilder.Entity().HasRequired(e => e.TPCVehicle).WithRequiredDependent(e => e.TPCModel); - modelBuilder.Entity().Property(p => p.TPCVehicleId).IsRequired().HasColumnType("nvarchar"). - HasMaxLength(40).IsUnicode().IsVariableLength(); - modelBuilder.Entity().Property(p => p.Name).HasColumnType("nvarchar(max)").IsUnicode(); - modelBuilder.Entity().Property(p => p.Type).IsRequired().HasColumnType("text"); - modelBuilder.Entity().Property(p => p.TPCModelId).IsRequired().HasColumnType("nvarchar"). - HasMaxLength(40).IsUnicode().IsVariableLength(); - modelBuilder.Entity().Property(p => p.Description).HasColumnType("numeric").HasPrecision(15, 5); - - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo, true)); - } - - #endregion - - #region Complex Types - - [Fact] - public void ComplexType_Properties_Can_Be_Entity_Split() - { - var modelBuilder = new AdventureWorksModelBuilder(); - modelBuilder.Ignore(); - modelBuilder.ComplexType().Ignore(c => c.Region); - - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - p => new - { - p.Id, - p.HomeAddress - }); - mc.ToTable("Home"); - }) - .Map( - mc => - { - mc.Properties( - p => new - { - p.Id, - p.WorkAddress - }); - mc.ToTable("Work"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Home").HasColumns("Id", "HomeAddress_Street", "HomeAddress_City"); - databaseMapping.Assert("Work").HasColumns("Id", "WorkAddress_Street", "WorkAddress_City"); - } - - [Fact] - public void Scalars_Inside_ComplexType_Properties_Can_Be_Entity_Split() - { - var modelBuilder = new AdventureWorksModelBuilder(); - modelBuilder.Ignore(); - modelBuilder.Entity().Ignore(b => b.WorkAddress); - modelBuilder.ComplexType().Ignore(c => c.Region); - - modelBuilder.Entity() - .Map( - mc => - { - mc.Properties( - p => new - { - p.Id, - p.HomeAddress.Street - }); - mc.ToTable("HomeStreet"); - }) - .Map( - mc => - { - mc.Properties( - p => new - { - p.Id, - p.HomeAddress.City - }); - mc.ToTable("HomeCity"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("HomeStreet").HasColumns("Id", "HomeAddress_Street"); - databaseMapping.Assert("HomeCity").HasColumns("Id", "HomeAddress_City"); - } - - #endregion - - #region Abstract In Middle - - [Fact] - public void Abstract_in_middle_of_hierarchy_with_TPH() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("AbsInMiddles").HasColumns( - "Id", "Data", "L1Data", "L2Data", - "Discriminator"); - databaseMapping.AssertNoMapping(); - databaseMapping.Assert("AbsInMiddles").HasColumns( - "Id", "Data", "L1Data", "L2Data", - "Discriminator"); - } - - [Fact] - public void Abstract_in_middle_of_hierarchy_with_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Base"); - modelBuilder.Entity().ToTable("L1"); - modelBuilder.Entity().ToTable("L2"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.Assert("Base").HasColumns("Id", "Data"); - databaseMapping.Assert("L1").HasColumns("Id", "L1Data"); - databaseMapping.Assert("L2").HasColumns("Id", "L2Data"); - } - - [Fact] - public void Abstract_in_middle_of_hierarchy_with_TPC() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Base"); - modelBuilder.Entity( - - ).Map( - mc => - { - mc.ToTable("L2"); - mc.MapInheritedProperties(); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - Assert.Equal(2, databaseMapping.Database.EntityTypes.Count()); - databaseMapping.Assert("Base").HasColumns("Id", "Data"); - databaseMapping.Assert("L2").HasColumns("Id", "Data", "L1Data", "L2Data"); - } - - [Fact] - public void Entity_split_abstract_middle_in_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table2"); - mapping.Properties( - e => new - { - e.Property2, - }); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table3"); - mapping.Properties( - e => new - { - e.Property2_1, - }); - }); - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Table4"); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Entity_split_abstract_middle_in_TPH() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Properties( - e => new - { - e.Id, - e.Property1, - e.Property1_1, - e.Property2, - }); - }); - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table2"); - mapping.Properties( - e => new - { - e.Id, - e.Property2_1, - }); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - #endregion - - #region Abstract At Base - - [Fact] - public void Can_specify_not_null_condition_on_derived_with_abstract_base_in_TPH() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().Map(mc => { mc.Requires(e => e.L1Data).HasValue(); }); - modelBuilder.Entity().Property(p => p.L1Data).IsRequired(); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.AssertMapping("AbsAtBases", true).HasNoColumnConditions(); - databaseMapping.AssertMapping("AbsAtBases").HasNullabilityColumnCondition("L1Data", false); - } - - [Fact] - public void Can_specify_not_null_condition_on_derived_and_null_value_on_base_with_abstract_base_in_TPH_throws() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map(mc => { mc.Requires("L1Data").HasValue(null); }); - modelBuilder.Entity().Map(mc => { mc.Requires(e => e.L1Data).HasValue(); }); - modelBuilder.Entity().Property(p => p.L1Data).IsRequired(); - modelBuilder.Ignore(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - databaseMapping.AssertMapping("AbsAtBases").HasNoColumnConditions(); - databaseMapping.AssertMapping("AbsAtBases").HasNullabilityColumnCondition("L1Data", false); - } - - [Fact] - public void Entity_split_abstract_base_in_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map( - mc => - { - mc.ToTable("Base1"); - mc.Properties( - b => new - { - b.Id, - b.Prop1 - }); - }).Map( - mc => - { - mc.ToTable("Base2"); - mc.Properties( - b => new - { - b.Id, - b.Prop2 - }); - }); - - modelBuilder.Entity().Map(mc => { mc.ToTable("Derived"); }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Entity_split_abstract_base_in_TPH() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map( - mc => - { - mc.ToTable("Base1"); - mc.Properties( - b => new - { - b.Id, - b.Prop1 - }); - }).Map( - mc => - { - mc.ToTable("Base2"); - mc.Properties( - b => new - { - b.Id, - b.Prop2 - }); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - #endregion - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests +{ + using System; + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + using System.ComponentModel.DataAnnotations.Schema; + using System.Data.Entity; + using System.Data.Entity.Core; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.ModelConfiguration; + using System.Data.Entity.ModelConfiguration.Conventions; + using System.Data.Entity.ModelConfiguration.Edm; + using System.Data.Entity.ModelConfiguration.Edm.Services; + using System.Data.Entity.Utilities; + using System.Linq; + using System.Windows.Media; + using FunctionalTests.Model; + using Xunit; + + #region Fixtures + + public class Party + { + public int Id { get; set; } + } + + public class DayRecord + { + public int Id { get; set; } + public Party ReportedBy { get; set; } + public ICollection Forecasts { get; set; } + } + + public class HourlyForecast + { + public int Id { get; set; } + } + + public class TypeClass + { + public int Id { get; set; } + public int IntProp { get; set; } + public string StringProp { get; set; } + public byte[] ByteArrayProp { get; set; } + public DateTime DateTimeProp { get; set; } + public decimal DecimalProp { get; set; } + } + + public abstract class AbsAtBase + { + public int Id { get; set; } + public int Data { get; set; } + } + + public class AbsAtBaseL1 : AbsAtBase + { + public int L1Data { get; set; } + } + + public class AbsAtBaseL2 : AbsAtBaseL1 + { + public int L2Data { get; set; } + } + + public class AbsInMiddle + { + public int Id { get; set; } + public int Data { get; set; } + } + + public abstract class AbsInMiddleL1 : AbsInMiddle + { + public int L1Data { get; set; } + } + + public class AbsInMiddleL2 : AbsInMiddleL1 + { + public int L2Data { get; set; } + } + + public class AssocBase + { + public int Id { get; set; } + public string Name { get; set; } + public string BaseData { get; set; } + public int AssocRelatedBaseId { get; set; } + public AssocRelated AssocRelatedBase { get; set; } + } + + public class AssocDerived : AssocBase + { + public int AssocRelatedId { get; set; } + public string DerivedData1 { get; set; } + public string DerivedData2 { get; set; } + public AssocRelated AssocRelated { get; set; } + } + + public class AssocRelated + { + public int Id { get; set; } + public string Name { get; set; } + public ICollection Deriveds { get; set; } + public ICollection Bases { get; set; } + public AssocDerived RefDerived { get; set; } + public AssocBase RefBase { get; set; } + } + + public class AssocPrincipal + { + public int Id { get; set; } + public AssocDependent DependentNavigation { get; set; } + } + + public class AssocDependent : AssocBaseDependent + { + public AssocPrincipal PrincipalNavigation { get; set; } + } + + public class AssocBaseDependent + { + public string BaseProperty { get; set; } + public int Id { get; set; } + } + + public struct FancyId + { + public int Id1 { get; set; } + public int Id2 { get; set; } + } + + public class Stimulus + { + public int Id { get; set; } + public Brush Background { get; set; } + } + + public class TSItem + { + public int Id { get; set; } + public string Name { get; set; } + public TSItemDetail TSItemDetail { get; set; } + public TSItemDetailDiffKey TSItemDetailDiffKey { get; set; } + public TSItemDetailOverlappingProperty TSItemDetailOverlappingProperty { get; set; } + } + + public class TSItemDetail + { + public int Id { get; set; } + public string Detail { get; set; } + } + + public class TSItemDetailDiffKey + { + public int DiffId { get; set; } + public string Detail { get; set; } + } + + public class TSItemDetailOverlappingProperty + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class TSIAItem + { + public int Id { get; set; } + public string Name { get; set; } + public TSIAItemDetail Detail { get; set; } + } + + public class TSIAItemDetail + { + public string Id { get; set; } + public string Detail { get; set; } + } + + public class TSBase + { + public int Id { get; set; } + public string BaseData { get; set; } + public TSBaseDetail BaseDetail { get; set; } + } + + public class TSBaseDetail + { + public int Id { get; set; } + public string BaseDetail { get; set; } + } + + public class TSDerived : TSBase + { + public string DerivedData { get; set; } + public TSDerivedDetail Detail { get; set; } + } + + public class TSDerivedDetail + { + public int Id { get; set; } + public string DerivedDetail { get; set; } + } + + public class CTBase + { + public int Id { get; set; } + public CTAddress HomeAddress { get; set; } + public CTAddress WorkAddress { get; set; } + } + + public class CTAddress + { + public string Street { get; set; } + public string City { get; set; } + public CTRegion Region { get; set; } + } + + public class CTRegion + { + public string Country { get; set; } + public string Zip { get; set; } + } + + public class TPHBase + { + public int Id { get; set; } + public string BaseData { get; set; } + public int IntProp { get; set; } + public int? NullableIntProp { get; set; } + } + + public class TPHDerived : TPHBase + { + public string DerivedData { get; set; } + } + + public class TPHLeaf : TPHDerived + { + public string LeafData { get; set; } + } + + public class TPHRoot + { + public int Id { get; set; } + public int RootData { get; set; } + } + + public class TPHNodeA : TPHRoot + { + public int AData { get; set; } + } + + public class TPHNodeB : TPHRoot + { + public int BData { get; set; } + } + + public class TPHNodeC : TPHRoot + { + public int CData { get; set; } + } + + // Hybrid tree: + // HybridBase + // / \ + // HybridL1A HybridL1B + // / + // HybridL2 + + public class HybridBase + { + public int Id { get; set; } + public int BaseData { get; set; } + } + + public class HybridL1A : HybridBase + { + public int L1AData { get; set; } + } + + public class HybridL1B : HybridBase + { + public int L1BData { get; set; } + } + + public class HybridL2 : HybridL1A + { + public int L2Data { get; set; } + } + + public class NullablePk + { + public int? Key { get; set; } + public int? Id { get; set; } + } + + public class AnnotatedNullablePk + { + [Key] + public int? Key { get; set; } + } + + public abstract class AbstractBaseEntity + { + public long Id { get; set; } + public abstract string AbstractBaseClassProperty { get; set; } + } + + public class BaseEntity : AbstractBaseEntity + { + public string BaseClassProperty { get; set; } + public virtual string VirtualBaseClassProperty { get; set; } + public override string AbstractBaseClassProperty { get; set; } + } + + public class Unit : BaseEntity + { + public override string VirtualBaseClassProperty { get; set; } + public virtual AbstractBaseEntity Related { get; set; } + } + + public class DifferentUnit : BaseEntity + { + public new string VirtualBaseClassProperty { get; set; } + } + + public class ACrazy + { + public int Id { get; set; } + public string A { get; set; } + } + + public abstract class BCrazy : ACrazy + { + public string B { get; set; } + } + + public class CCrazy : BCrazy + { + public string C { get; set; } + } + + public abstract class DCrazy : CCrazy + { + public string D { get; set; } + } + + public class ECrazy : DCrazy + { + public string E { get; set; } + } + + public class XCrazy : DCrazy + { + public string X { get; set; } + } + + public class IsolatedIsland + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class CKCategory + { + public Guid Key1 { get; set; } + public double? Key2 { get; set; } + } + + public class CKImage + { + public Guid Key1 { get; set; } + public double? Key2 { get; set; } + public string ImageData { get; set; } + } + + public class CKProduct + { + public Guid CKCategoryKey1 { get; set; } + public double CKCategoryKey2 { get; set; } + public CKCategory CKCategory { get; set; } + } + + public class CKDerivedProduct : CKProduct + { + public decimal? DerivedProperty1 { get; set; } + public CKImage Image { get; set; } + } + + public class CKDerivedProduct2 : CKDerivedProduct + { + public decimal? DerivedProperty2 { get; set; } + } + + public class SelfRefDerived : SelfRefBase + { + public float? DependentKey1 { get; set; } + public SelfRefDerived SelfRefNavigation { get; set; } + } + + public class SelfRefBase + { + public string BaseProperty { get; set; } + public float Key1 { get; set; } + } + + public class Repro136761_A + { + public int Repro136761_AId { get; set; } + public string AData { get; set; } + } + + public class Repro136761_B : Repro136761_A + { + public string BData { get; set; } + } + + public class Repro136761_C + { + public int Repro136761_CId { get; set; } + public string CData { get; set; } + public int Repro136761_BId { get; set; } + public Repro136761_B Repro136761_B { get; set; } + } + + // Base association with property discriminator, composite nullable key types + + public class Repro136322_Principal + { + public byte[] Key1 { get; set; } + public long? Key2 { get; set; } + } + + public class Repro136322_Dependent + { + public byte[] PrincipalKey1 { get; set; } + public long PrincipalKey2 { get; set; } + public int Id { get; set; } + public Repro136322_Principal PrincipalNavigation { get; set; } + } + + public class Repro136322_DerivedDependent : Repro136322_Dependent + { + public string DerivedProperty1 { get; set; } + public string Discriminator1 { get; set; } + } + + // Base association, singleton non-nullable key type + + public class Repro136855_Dependent + { + public DateTime Key1 { get; set; } + public int Id { get; set; } + public Repro136855_Principal PrincipalNavigation { get; set; } + } + + public class Repro136855_Principal + { + public DateTime Key1 { get; set; } + } + + public class Repro136855_DerivedDependent : Repro136855_Dependent + { + public bool? DerivedProperty1 { get; set; } + } + + // Derived association + + public class Repro135563_Dependent : Repro135563_BaseDependent + { + public Repro135563_Principal PrincipalNavigation { get; set; } + } + + public class Repro135563_Principal + { + public decimal Key1 { get; set; } + public short? Key2 { get; set; } + public Repro135563_Dependent DependentNavigation { get; set; } + } + + public class Repro135563_BaseDependent + { + public TimeSpan BaseProperty { get; set; } + public int Id { get; set; } + } + + // Three Level Hierarchy, abstract middle, self-ref in middle + + public class ThreeLevelBase + { + public string BaseProperty { get; set; } + public float? Key1 { get; set; } + } + + public abstract class ThreeLevelDerived : ThreeLevelBase + { + public ICollection DependentNavigation { get; set; } + } + + public class ThreeLevelLeaf : ThreeLevelDerived + { + public string DerivedProperty1 { get; set; } + } + + // Two level hierarchy with byte[] prop + + public class ByteBase + { + public int Id { get; set; } + public byte[] ByteData { get; set; } + } + + public class ByteDerived : ByteBase + { + public byte[] DerivedData { get; set; } + } + + public class ByteDerived2 : ByteDerived + { + public byte[] ExtraData { get; set; } + } + + // Association to abstract dependent base type + + public abstract class AbsDep_Dependent + { + public int Id { get; set; } + public short PrincipalKey1 { get; set; } + public AbsDep_Principal PrincipalNavigation { get; set; } + } + + public class AbsDep_Principal + { + public short Key1 { get; set; } + public ICollection DependentNavigation { get; set; } + } + + public class AbsDep_DerivedDependent : AbsDep_Dependent + { + public byte[] DerivedProperty1 { get; set; } + } + + // Association to a principal base type + + public class AssocBase_Department + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class AssocBase_OldDepartment : AssocBase_Department + { + public DateTime ObsoleteDate { get; set; } + } + + public class AssocBase_Employee + { + public int Id { get; set; } + public int AssocBase_DepartmentId { get; set; } + public AssocBase_Department AssocBase_Department { get; set; } + } + + // Two Hierachies with association between subtypes + + public class THABS_BasePrincipal + { + public string BaseProperty { get; set; } + public byte[] Key1 { get; set; } + } + + public class THABS_Principal : THABS_BasePrincipal + { + public ICollection THABS_DependentNavigation { get; set; } + } + + public class THABS_Dependent + { + public int Id { get; set; } + public THABS_Principal THABS_PrincipalNavigation { get; set; } + } + + public class THABS_DerivedDependent : THABS_Dependent + { + public DateTime DerivedProperty1 { get; set; } + } + + // Self-ref on derived type + + public class SRBase + { + public string BaseProperty { get; set; } + public float? Key1 { get; set; } + public DateTime Key2 { get; set; } + } + + public class SRDerived : SRBase + { + public ICollection Navigation { get; set; } + } + + // Table splitting on base...used with TPC + + public class Repro140106_Vehicle + { + public string Repro140106_VehicleId { get; set; } + public string Name { get; set; } + public Repro140106_Model Model { get; set; } + } + + public class Repro140106_Car : Repro140106_Vehicle + { + public string Type { get; set; } + } + + public class Repro140106_Model + { + public string Repro140106_ModelId { get; set; } + public decimal Description { get; set; } + public Repro140106_Vehicle Repro140106_Vehicle { get; set; } + } + + // Table splitting on base...used with TPT + + public class Repro140107_Vehicle + { + public int? Repro140107_VehicleId { get; set; } + public short? Name { get; set; } + public Repro140107_Model Repro140107_Model { get; set; } + } + + public class Repro140107_Car : Repro140107_Vehicle + { + public long Type { get; set; } + } + + public class Repro140107_Model + { + public int? Repro140107_ModelId { get; set; } + public bool Description { get; set; } + public Repro140107_Vehicle Repro140107_Vehicle { get; set; } + } + + // Hybrid mapping model + + public class Entity1 + { + public short? Entity1_Col1 { get; set; } + public DateTime Entity1_Col2 { get; set; } + public byte[] Entity1_Col3 { get; set; } + public string Id { get; set; } + } + + public class Entity2 : Entity1 + { + public DateTime? Entity2_Col1 { get; set; } + } + + public class Entity3 : Entity1 + { + public string Entity3_Col1 { get; set; } + public DateTimeOffset Entity3_Col2 { get; set; } + } + + public class Entity4 : Entity1 + { + public long? Entity4_Col1 { get; set; } + public string Entity4_Col2 { get; set; } + } + + public class Entity5 : Entity2 + { + public bool? Entity5_Col1 { get; set; } + public DateTime Entity5_Col2 { get; set; } + public TimeSpan Entity5_Col3 { get; set; } + public decimal? Entity5_Col4 { get; set; } + public DateTime Entity5_Col5 { get; set; } + } + + // Hybrid Scenario + + public class Repro137329_A1 + { + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public int Id { get; set; } + + public string Age1 { get; set; } + public string Name { get; set; } + } + + public class Repro137329_A2 : Repro137329_A1 + { + public string Age2 { get; set; } + } + + public class Repro137329_A3 : Repro137329_A2 + { + public string Age3 { get; set; } + } + + public class Repro137329_A4 : Repro137329_A1 + { + public string Age4 { get; set; } + } + + // Property Discriminator + + public class Repro143236_Dependent + { + public int Id { get; set; } + } + + public class Repro143236_DerivedDependent : Repro143236_Dependent + { + public DateTime DerivedProperty1 { get; set; } + public double DiscriminatorNotNull { get; set; } + } + + // abstract base class + + public abstract class Repro143662_Party + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class Repro143662_Agency : Repro143662_Party + { + public int Reputation { get; set; } + } + + public class Repro143662_Person : Repro143662_Party + { + public string Address { get; set; } + } + + // IA relationship between subtypes + + public class Repro109944_BaseEntity + { + public int ID { get; set; } + public string Title { get; set; } + } + + public class Repro109944_Entity1 : Repro109944_BaseEntity + { + public string SomeProperty { get; set; } + public Repro109944_Entity2 Repro109944_Entity2 { get; set; } + public int Repro109944_Entity2ID { get; set; } + } + + public class Repro109944_Entity2 : Repro109944_BaseEntity + { + public string SomeProperty { get; set; } + } + + // Base type to base type FK association + + public class Repro142961_Dependent + { + public decimal Key1 { get; set; } + public int Id { get; set; } + public Repro142961_Principal PrincipalNavigation { get; set; } + } + + public class Repro142961_Principal + { + public decimal Key1 { get; set; } + } + + public class Repro142961_DerivedDependent : Repro142961_Dependent + { + public Guid DerivedProperty1 { get; set; } + } + + public class Repro142961_DerivedPrincipal : Repro142961_Principal + { + public long DerivedProperty1 { get; set; } + } + + // Abstract base with discriminator + + public abstract class Repro142666_Dependent + { + public bool DependentForeignKeyPropertyNotFromConvention1 { get; set; } + public int Id { get; set; } + } + + public class Repro142666_DerivedDependent : Repro142666_Dependent + { + public string DerivedProperty1 { get; set; } + } + + // Simple three level hierarchy + + public class Repro143127_EntityA + { + public int Id { get; set; } + public string Description { get; set; } + } + + public class Repro143127_EntityB : Repro143127_EntityA + { + public int Count { get; set; } + public string Info { get; set; } + } + + public class Repro143127_EntityC : Repro143127_EntityB + { + public int P1 { get; set; } + } + + // IA from an abstract non-root type + + public abstract class Repro142682_Dependent : Repro142682_BaseDependent + { + public DateTime DependentForeignKeyPropertyNotFromConvention1 { get; set; } + public Repro142682_Principal PrincipalNavigation { get; set; } + } + + public class Repro142682_Principal + { + public DateTime? Key1 { get; set; } + public ICollection DependentNavigation { get; set; } + } + + public class Repro142682_BaseDependent + { + public long? BaseProperty { get; set; } + public int Id { get; set; } + } + + public class Repro142682_DerivedDependent : Repro142682_Dependent + { + public decimal? DerivedProperty1 { get; set; } + } + + // Simple hierarchy for TPC property renaming + + public class Repro144459_Product + { + public int Id { get; set; } + public string Name { get; set; } + } + + public class Repro144459_DiscontinuedProduct : Repro144459_Product + { + public DateTime DiscontinuedOn { get; set; } + } + + public class Repro144459_ClearanceProduct : Repro144459_Product + { + public decimal SalePrice { get; set; } + } + + // Abstract base as principal of FK association + + public abstract class Repro110459_Customer + { + public virtual Guid Id { get; set; } + public virtual string Name { get; set; } + public virtual ICollection Orders { get; set; } + } + + public class Repro110459_Account : Repro110459_Customer + { + public virtual string AccountNumber { get; set; } + } + + public class Repro110459_Contact : Repro110459_Customer + { + public virtual string FirstName { get; set; } + public virtual string LastName { get; set; } + } + + public class Repro110459_Order + { + public Guid Id { get; set; } + public string Name { get; set; } + public Repro110459_Customer BillToCustomer { get; set; } + public Guid BillToCustomerId { get; set; } + } + + // Multiple relationships at various points in hierarchy with TPT + + public class Repro109916_BaseEntity + { + [Key] + public int ID { get; set; } + + public string Title { get; set; } + + public Repro109916_Collectible Parent { get; set; } + public virtual ICollection Children { get; set; } + } + + public class Repro109916_Collectible + { + public int ID { get; set; } + } + + public class Repro109916_SomeEntity : Repro109916_BaseEntity + { + public byte Units { get; set; } + + public string Watermark { get; set; } + public Repro109916_BaseEntity BaseEntity { get; set; } + } + + public class Repro109916_SomeMore : Repro109916_BaseEntity + { + [Column("Watermark")] + public string Watermark { get; set; } + + public string Denomination { get; set; } + + // These cause the problem: + public Repro109916_Product Product { get; set; } + public Repro109916_SomeEntity SomeEntity { get; set; } + } + + public class Repro109916_Product + { + [Key] + public int ID { get; set; } + + public string Name { get; set; } + } + + // Three level hierarchy with abstract middle + + public class Repro147822_EntityA + { + public int Id { get; set; } + public byte[] Photo { get; set; } + public string Description { get; set; } + public string Name { get; set; } + } + + public abstract class Repro147822_EntityB : Repro147822_EntityA + { + public string Details { get; set; } + } + + public class Repro147822_EntityC : Repro147822_EntityB + { + public string Color { get; set; } + } + + // Two level hierarchy with abstract root type + + public abstract class Repro147906_EntityA1 + { + public int Id { get; set; } + public byte[] Photo { get; set; } + public string Description { get; set; } + public string Name { get; set; } + } + + public class Repro147906_EntityA1_1 : Repro147906_EntityA1 + { + public string Property1 { get; set; } + public string Property2 { get; set; } + public string Property3 { get; set; } + } + + public class Repro147906_EntityA1_2 : Repro147906_EntityA1 + { + public string Property4 { get; set; } + public string Property5 { get; set; } + public string Property6 { get; set; } + } + + // Complex Type on a base entity + + public class Repro148415_EntityC1 + { + public int Id { get; set; } + public Repro148415_ComplexTypeC1 ComplexProperty1 { get; set; } + public float Property2 { get; set; } + } + + public class Repro148415_EntityC1_1 : Repro148415_EntityC1 + { + public float Property3 { get; set; } + public float Property4 { get; set; } + } + + public class Repro148415_ComplexTypeC1 + { + public int P1 { get; set; } + public float P2 { get; set; } + } + + // Table splitting on base used for TPC + + public class TPCVehicle + { + public string TPCVehicleId { get; set; } + public string Name { get; set; } + public TPCModel TPCModel { get; set; } + } + + public class TPCCar : TPCVehicle + { + public string Type { get; set; } + } + + public class TPCModel + { + public string TPCModelId { get; set; } + public decimal Description { get; set; } + public TPCVehicle TPCVehicle { get; set; } + } + + // Three level hierarchy for entity splitting + + public class Repro147929_EntityB1 + { + public int Id { get; set; } + public byte[] Photo { get; set; } + public string Description { get; set; } + public string Name { get; set; } + } + + public class Repro147929_EntityB1_1 : Repro147929_EntityB1 + { + public string Property1 { get; set; } + public string Property2 { get; set; } + public string Property3 { get; set; } + } + + public class Repro147929_EntityB1_1_1 : Repro147929_EntityB1_1 + { + public string Property4 { get; set; } + public string Property5 { get; set; } + public string Property6 { get; set; } + } + + // Three level hierarchy with association between abstract middle types + + public class Repro150248_BaseDependent + { + public DateTime? BaseProperty { get; set; } + public string Key1 { get; set; } + } + + public abstract class Repro150248_Dependent : Repro150248_BaseDependent + { + public string PrincipalKey1 { get; set; } + public Repro150248_Principal PrincipalNavigation { get; set; } + } + + public class Repro150248_DerivedDependent : Repro150248_Dependent + { + public decimal? DerivedProperty1 { get; set; } + } + + public abstract class Repro150248_Principal : Repro150248_BaseDependent + { + public ICollection DependentNavigation { get; set; } + } + + public class Repro150248_DerivedPrincipal : Repro150248_Principal + { + public string DerivedProperty1 { get; set; } + } + + // 1:0..1 IA on derived dependent + + public class Repro150634_BaseDependent + { + public string BaseProperty { get; set; } + public Guid? Key1 { get; set; } + public Guid? Key2 { get; set; } + } + + public class Repro150634_Dependent : Repro150634_BaseDependent + { + public Int32 DependentForeignKeyPropertyNotFromConvention1 { get; set; } + public Repro150634_Principal PrincipalNavigation { get; set; } + } + + public class Repro150634_DerivedDependent : Repro150634_Dependent + { + public Int32 ExtraProp { get; set; } + } + + public class Repro150634_Principal + { + public int Id { get; set; } + public Repro150634_Dependent DependentNavigation { get; set; } + } + + // 0..1:* IA to derived principal + + public class Repro165020_BaseDependent + { + public int Id { get; set; } + } + + public class Repro165020_DerivedDependent : Repro165020_BaseDependent + { + public Repro165020_DerivedPrincipal PrincipalNavigation { get; set; } + } + + public class Repro165020_BasePrincipal + { + public DateTime? Key1 { get; set; } + public decimal Key2 { get; set; } + } + + public class Repro165020_DerivedPrincipal : Repro165020_BasePrincipal + { + public ICollection DependentNavigation { get; set; } + } + + // composite key with property ordering + + public class EntityWithCompositePK + { + [Column(Order = 1)] + public string Key1 { get; set; } + + [Column(Order = 2)] + public int Key2 { get; set; } + + [Column(Order = 3)] + public byte[] Property1 { get; set; } + + [Column(Order = 4)] + public string Property2 { get; set; } + } + + // Hierarchy with abstract base and FK on base + + public abstract class Repro150248_Dependent_2 + { + public string Key1 { get; set; } + public Repro150248_Principal_2 PrincipalNavigation { get; set; } + } + + public class Repro150248_Principal_2 : Repro150248_BasePrincipal_2 + { + public Repro150248_Dependent_2 DependentNavigation { get; set; } + } + + public class Repro150248_DerivedDependent_2 : Repro150248_Dependent_2 + { + public byte? DependentDerivedProperty1 { get; set; } + } + + public class Repro150248_BasePrincipal_2 + { + public string Key1 { get; set; } + } + + // hierarchy with middle type given a table name + + public class Repro143351_A1 + { + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public string Id { get; set; } + + public string A1Col1 { get; set; } + public byte[] A1Col2 { get; set; } + } + + [Table("NewA2TableName")] + public class Repro143351_A2 : Repro143351_A1 + { + public byte[] A2Col1 { get; set; } + } + + public class Repro143351_A3 : Repro143351_A2 + { + public DateTime A3Col1 { get; set; } + } + + public class Repro143351_A4 : Repro143351_A1 + { + public long A4Col1 { get; set; } + } + + // self reference from derived to abstract base + + public class Repro135563_2_Dependent : Repro135563_2_BaseDependent + { + public Repro135563_2_BaseDependent PrincipalNavigation { get; set; } + } + + public abstract class Repro135563_2_BaseDependent + { + public Guid BaseProperty { get; set; } + public short Key1 { get; set; } + public ICollection DependentNavigation { get; set; } + } + + public class Repro135563_2_Other : Repro135563_2_BaseDependent + { + public string OtherData { get; set; } + } + + // self reference from derived to concrete base + + public class Repro135563_3_Dependent : Repro135563_3_BaseDependent + { + public Repro135563_3_BaseDependent PrincipalNavigation { get; set; } + } + + public class Repro135563_3_BaseDependent + { + public Guid BaseProperty { get; set; } + public short Key1 { get; set; } + public ICollection DependentNavigation { get; set; } + } + + // Basic Inheritance + + public class EntityL + { + public int Id { get; set; } + public string Property1 { get; set; } + public byte[] Property2 { get; set; } + } + + public class EntityL_1 : EntityL + { + public string Property3 { get; set; } + public byte[] Property4 { get; set; } + } + + // abstract at base for splitting + + public abstract class AbsBaseSplit + { + public int Id { get; set; } + public string Prop1 { get; set; } + public string Prop2 { get; set; } + } + + public class AbsDerivedSplit : AbsBaseSplit + { + public string Prop3 { get; set; } + } + + // abstract in middle for splitting + + public class EntityN + { + public int Id { get; set; } + public int Property1 { get; set; } + public int Property1_1 { get; set; } + } + + public abstract class EntityN_1 : EntityN + { + public int Property2 { get; set; } + public int Property2_1 { get; set; } + } + + public class EntityN_1_1 : EntityN_1 + { + public int Property3_1 { get; set; } + public int Property3 { get; set; } + } + + public abstract class BaseNote + { + public virtual Guid Id { get; set; } + public virtual string Description { get; set; } + } + + public class NoteWithRelationship1 : BaseNote + { + public virtual TargetEmployee TargetEmployee { get; set; } + } + + public class NoteWithRelationship2 : BaseNote + { + public virtual TargetEmployee TargetEmployee { get; set; } + } + + public abstract class BaseEmployee + { + public Guid Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + } + + public class TargetEmployee : BaseEmployee + { + public DateTime? DateOfBirth { get; set; } + } + + // Reuse complex type in derived classes + + [Table("Product")] + public abstract class VehicleProduct + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + } + + [Table("RedVehicle")] + public abstract class RedVehicle : VehicleProduct + { + public VehicleType VehicleType { get; set; } //The same name of complex type + } + + [Table("BlueVehicle")] + public abstract class BlueVehicle : VehicleProduct + { + public VehicleType VehicleType { get; set; } //The same name of complex type + } + + [Table("RedCar")] + public class RedCar : RedVehicle + { + } + + [Table("BlueCar")] + public class BlueCar : BlueVehicle + { + } + + [ComplexType] + public class VehicleType + { + [Required] + public string Model { get; set; } + } + + #endregion + + public sealed class BasicMappingScenarioTests : TestBase + { + [Fact] + public void Can_specify_default_schema() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.HasDefaultSchema("foo"); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(1, databaseMapping.Database.GetEntitySets().Count(es => es.Schema == "foo")); + } + + [Fact] + public void Can_specify_default_schema_and_explicit_schemas() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.HasDefaultSchema("foo"); + modelBuilder.Entity(); + modelBuilder.Entity().ToTable("days", "bar"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(2, databaseMapping.Database.GetEntitySets().Count(es => es.Schema == "foo")); + Assert.Equal(1, databaseMapping.Database.GetEntitySets().Count(es => es.Schema == "bar")); + } + + [Fact] + public void Can_specify_default_schema_and_explicit_dbo_schema() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.HasDefaultSchema("foo"); + modelBuilder.Entity(); + modelBuilder.Entity().ToTable("days", "dbo"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(2, databaseMapping.Database.GetEntitySets().Count(es => es.Schema == "foo")); + Assert.Equal(1, databaseMapping.Database.GetEntitySets().Count(es => es.Schema == "dbo")); + } + + #region Misc + + [Fact] + public void Has_max_length_should_work_when_no_max_length_convention() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Conventions.Remove(); + modelBuilder.Entity().HasKey(a => a.StringProp); + modelBuilder.Entity().Property(t => t.StringProp).HasMaxLength(42); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(t => t.StringProp).FacetEqual(true, f => f.IsUnicode); + databaseMapping.Assert(t => t.StringProp).FacetEqual(false, f => f.IsFixedLength); + databaseMapping.Assert(t => t.StringProp).FacetEqual(42, f => f.MaxLength); + databaseMapping.Assert(t => t.StringProp).DbEqual(42, f => f.MaxLength); + } + + [Fact] + public void Should_be_able_to_call_simple_has_key_twice() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey(a => a.Street); + modelBuilder.Entity().HasKey(a => a.Street); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Should_be_able_to_ignore_property_on_base_class() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Ignore(b => b.BaseClassProperty); + modelBuilder.Entity().Ignore(b => b.VirtualBaseClassProperty); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.False( + databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) + .Any(p => p.Name == "BaseClassProperty")); + Assert.False( + databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) + .Any(p => p.Name == "VirtualBaseClassProperty")); + } + + [Fact] + public void Ignore_property_on_base_class_and_derived_class_throws() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Ignore(b => b.BaseClassProperty); + modelBuilder.Entity().Ignore(b => b.VirtualBaseClassProperty); + modelBuilder.Entity().Ignore(b => b.BaseClassProperty); + modelBuilder.Entity().Ignore(b => b.VirtualBaseClassProperty); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage( + "CannotIgnoreMappedBaseProperty", + "BaseClassProperty", "FunctionalTests.Unit", + "FunctionalTests.BaseEntity"); + } + + [Fact] + public void Should_be_able_to_ignore_property_on_abstract_base_class() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Ignore(b => b.AbstractBaseClassProperty); + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.False( + databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) + .Any(p => p.Name == "AbstractBaseClassProperty")); + } + + [Fact] + public void Ignoring_mapped_base_class_property_throws() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().Ignore(u => u.BaseClassProperty); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage( + "CannotIgnoreMappedBaseProperty", + "BaseClassProperty", "FunctionalTests.Unit", + "FunctionalTests.BaseEntity"); + } + + [Fact] + public void Should_be_able_to_ignore_unmapped_base_class_property() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Entity().Ignore(u => u.BaseClassProperty); + modelBuilder.Entity().Ignore(u => u.VirtualBaseClassProperty); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.False( + databaseMapping.Model.EntityTypes.Single().Properties.Any( + p => p.Name == "BaseClassProperty")); + Assert.False( + databaseMapping.Model.EntityTypes.Single().Properties.Any( + p => p.Name == "VirtualBaseClassProperty")); + } + + [Fact] + public void Ignoring_new_property_with_same_name_as_in_mapped_base_class_throws() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().Ignore(u => u.VirtualBaseClassProperty); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage( + "CannotIgnoreMappedBaseProperty", + "VirtualBaseClassProperty", "FunctionalTests.DifferentUnit", + "FunctionalTests.BaseEntity"); + } + + [Fact] + public void Ignoring_overriden_mapped_base_class_property_throws() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Ignore(u => u.VirtualBaseClassProperty); + modelBuilder.Entity(); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage( + "CannotIgnoreMappedBaseProperty", + "VirtualBaseClassProperty", "FunctionalTests.Unit", + "FunctionalTests.BaseEntity"); + } + + [Fact] + public void Should_be_able_to_configure_nullable_ospace_key() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey(n => n.Key); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Should_be_able_to_annotate_nullable_ospace_key() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Should_be_able_to_discover_nullable_ospace_key() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Explicitly_configured_entity_set_name_is_not_pluralized() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasEntitySetName("Customer"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal("Customer", databaseMapping.Model.Containers.Single().EntitySets.Single().Name); + } + + [Fact] + public void Explicitly_configured_entity_set_names_are_uniqued() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasEntitySetName("Foo"); + modelBuilder.Entity().HasEntitySetName("Foo"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal("Foo", databaseMapping.Model.Containers.Single().EntitySets.First().Name); + Assert.Equal("Foo1", databaseMapping.Model.Containers.Single().EntitySets.Last().Name); + } + + [Fact] + public void Build_model_for_type_with_framework_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + + // WPF classes invalid + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Build_model_for_type_with_internal_member_to_configure_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity() + .HasKey(th => th.TransactionID); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); + } + + [Fact] + public void Build_model_for_type_with_configured_internal_members() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .HasKey(th => th.TransactionID); + modelBuilder.Entity() + .HasRequired(th => th.Product); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo, typeof(Product)); + + Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); + } + + [Fact] + public void Build_model_for_a_single_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_after_customizing_property_column_name() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Property(c => c.AccountNumber).HasColumnName("acc_no"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_after_customizing_property_column_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Property(c => c.AccountNumber).HasColumnType("NVARCHAR"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_a_single_type_with_a_nullable_key() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_a_single_type_with_a_composite_key() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasKey( + sc => new + { + sc.ContactID, + sc.CustomerID + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_a_single_type_with_a_string_key() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_default_tph_mapping() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + #endregion + + #region ToTable Tests + + [Fact] + public void ToTable_on_single_entity_changes_table_name() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("tbl_sp"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert("tbl_sp"); + } + + [Fact] + public void ToTable_on_single_entity_with_association_changes_table_name() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("tbl_sp"); + modelBuilder.Entity().HasOptional(o => o.SalesPerson).WithRequired(e => e.Employee); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert("tbl_sp"); + } + + #endregion + + #region ToTable Schema Tests + + [Fact] + public void Build_model_with_table_schema_configured() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("tbl_sp", "sales"); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "sales")); + Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "dbo")); + } + + [Fact] + public void Build_model_with_dotted_table_name_configured() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("sales.tbl_sp"); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "sales")); + Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "dbo")); + } + + [Fact] + public void Build_model_with_dotted_table_name_and_dotted_schema_configured() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("tbl_sp", "sales.A.B"); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "sales.A.B")); + Assert.True(databaseMapping.Database.GetEntitySets().Any(s => s.Schema == "dbo")); + } + + [Fact] + public void Relationship_with_table_in_different_schema_works() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity().Map(m => m.ToTable("HourlyForecasts", "dbx")); + + var databaseMapping = BuildMapping(modelBuilder); + + var mws = databaseMapping.ToMetadataWorkspace(); + + var storeCollection = mws.GetItemCollection(DataSpace.SSpace); + Assert.Equal( + 2, + (storeCollection.GetItem("CodeFirstDatabase")).BaseEntitySets.OfType + ().Count()); + } + + #endregion + + #region Basic TPH Tests + + [Fact] + public void Requires_value_can_change_discriminator_column_name_and_use_strings() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue("a"); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("b"); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("c"); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert() + .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); + databaseMapping.Assert("TPHBases") + .Column("MyDisc") + .DbEqual(DatabaseMappingGenerator.DiscriminatorMaxLength, f => f.MaxLength); + databaseMapping.AssertMapping("TPHBases", false) + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "a"); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "b"); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "c"); + } + + [Fact] + public void ToTable_on_root_abstract_class_renames_TPH_hierarchy() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Foo"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Foo"); + } + + [Fact] + // Regression test for Dev 11 bug 136256 + public void Requires_value_can_change_discriminator_column_name_and_use_strings_on_derived_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue("a"); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("c"); }); + + modelBuilder.Entity().Map(mc => { mc.Requires("MyDisc").HasValue("b").HasColumnType("ntext"); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert() + .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); + databaseMapping.Assert("TPHBases") + .Column("MyDisc") + .DbEqual(null, f => f.MaxLength); + databaseMapping.AssertMapping("TPHBases", false) + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "a"); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "b"); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "c"); + } + + [Fact] + // Regression test for Dev 11 bug 142718 + public void Requires_value_can_change_discriminator_column_name_and_nullability() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue("a").IsOptional(); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("b"); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("c"); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert() + .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); + databaseMapping.Assert("TPHBases") + .Column("MyDisc") + .DbEqual(true, f => f.Nullable) + .DbEqual(DatabaseMappingGenerator.DiscriminatorMaxLength, f => f.MaxLength); + databaseMapping.AssertMapping("TPHBases", false) + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "a"); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "b"); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "c"); + } + + [Fact] + public void Requires_value_can_change_discriminator_column_name_and_nullability_on_derived_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue("a"); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("b").IsOptional(); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("c"); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert() + .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); + databaseMapping.Assert("TPHBases") + .Column("MyDisc") + .DbEqual(true, f => f.Nullable) + .DbEqual(DatabaseMappingGenerator.DiscriminatorMaxLength, f => f.MaxLength); + databaseMapping.AssertMapping("TPHBases", false) + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "a"); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "b"); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "c"); + } + + [Fact] + public void Requires_throws_on_conflicting_nullability() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue("a").IsRequired(); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("b").IsOptional(); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("c"); }); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + // Regression test for Dev 11 bug 136596 + public void Requires_value_works_with_table_annotation() + { + using (var tphBaseConfiguration = new DynamicTypeDescriptionConfiguration()) + { + tphBaseConfiguration.TypeAttributes = new[] { new TableAttribute("MegaTPH") }; + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue("a"); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("b"); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("c"); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert() + .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); + databaseMapping.Assert("MegaTPH") + .Column("MyDisc") + .DbEqual(DatabaseMappingGenerator.DiscriminatorMaxLength, f => f.MaxLength); + databaseMapping.AssertMapping("MegaTPH", false) + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "a"); + databaseMapping.AssertMapping("MegaTPH") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "b"); + databaseMapping.AssertMapping("MegaTPH") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "c"); + } + } + + [Fact] + public void Requires_value_can_change_discriminator_column_name_and_use_int16() + { + Requires_value_can_change_discriminator_column_name((Int16)1, (Int16)2, (Int16)3); + } + + [Fact] + public void Requires_value_can_change_discriminator_column_name_and_use_int32() + { + Requires_value_can_change_discriminator_column_name(1, 2, 3); + } + + [Fact] + public void Requires_value_can_change_discriminator_column_name_and_use_int64() + { + Requires_value_can_change_discriminator_column_name(1, 2, (Int64)3); + } + + [Fact] + public void Requires_value_can_change_discriminator_column_name_and_use_byte() + { + Requires_value_can_change_discriminator_column_name((byte)1, (byte)2, (byte)3); + } + + [Fact] + public void Requires_value_can_change_discriminator_column_name_and_use_sbyte() + { + sbyte a = 1, b = 2, c = 3; + + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue(a).HasColumnType("tinyint"); }) + .Map(mc => { mc.Requires("MyDisc").HasValue(b); }) + .Map(mc => { mc.Requires("MyDisc").HasValue(c); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert() + .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); + databaseMapping.AssertMapping("TPHBases", false) + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", a); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", b); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", c); + } + + [Fact] + public void Requires_value_can_change_discriminator_column_name_and_use_bool() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue(true); }) + .Map(mc => { mc.Requires("MyDisc").HasValue(false); }); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert() + .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "MyDisc"); + databaseMapping.AssertMapping("TPHBases", false) + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", true); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", false); + } + + [Fact] + public void Requires_throws_on_decimal_discriminator() + { + Assert.Throws( + () => + Requires_value_can_change_discriminator_column_name( + (decimal)1.0, + (decimal)2.0, + (decimal)3.0)); + } + + [Fact] + public void Requires_throws_on_DateTime_discriminator() + { + Assert.Throws( + () => + Requires_value_can_change_discriminator_column_name( + new DateTime(2011, 1, 1), new DateTime(2011, 1, 2), + new DateTime(2011, 1, 3))); + } + + [Fact] + public void Requires_throws_on_TimeSpan_discriminator() + { + Assert.Throws( + () => + Requires_value_can_change_discriminator_column_name( + new TimeSpan(1), + new TimeSpan(2), + new TimeSpan(3))); + } + + [Fact] + public void Requires_throws_on_a_nonPrimitive_discriminator() + { + Assert.Throws( + () => + Requires_value_can_change_discriminator_column_name( + new FancyId + { + Id1 = 1, + Id2 = 1 + }, + new FancyId + { + Id1 = 2, + Id2 = 2 + }, new FancyId + { + Id1 = 3, + Id2 = 3 + })); + } + + [Fact] + // Regression test for Dev11 Bug 136810 + public void Requires_can_only_be_called_once_per_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue("a"); }); + + Assert.Throws( + () => + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue("b"); })); + } + + [Fact] + public void Requires_throws_on_mixed_valid_discriminator_types() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue(1); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("yo"); }); + modelBuilder.Ignore(); + + Assert.Throws(() => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Requires_throws_on_ambiguous_valid_discriminator_types() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue(1); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("2"); }); + modelBuilder.Ignore(); + + Assert.Throws(() => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Requires_throws_on_mixed_valid_discriminator_types_when_column_type_is_set() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue(1).HasColumnType("int"); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("yo"); }); + modelBuilder.Ignore(); + + Assert.Throws( + () => + modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Requires_throws_on_conflicting_valid_discriminator_types_when_column_type_is_set() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue(1).HasColumnType("int"); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("yo").HasColumnType("ntext"); }); + modelBuilder.Ignore(); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + private void Requires_value_can_change_discriminator_column_name(T a, T b, T c) where T : struct + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue(a); }) + .Map(mc => { mc.Requires("MyDisc").HasValue(b); }) + .Map(mc => { mc.Requires("MyDisc").HasValue(c); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert() + .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); + databaseMapping.AssertMapping("TPHBases", false) + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", a); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", b); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", c); + } + + [Fact] + public void Requires_value_can_be_null_with_nullable_string() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("MyDisc").HasValue("a"); }) + .Map(mc => { mc.Requires("MyDisc").HasValue("b"); }) + .Map(mc => { mc.Requires("MyDisc").HasValue(null); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert() + .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData", "LeafData", "MyDisc"); + databaseMapping.Assert("TPHBases") + .Column("MyDisc") + .DbEqual(DatabaseMappingGenerator.DiscriminatorMaxLength, f => f.MaxLength); + databaseMapping.AssertMapping("TPHBases", false) + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "a"); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "b"); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasNullabilityColumnCondition("MyDisc", true); + } + + [Fact] + public void NotNull_condition_does_not_require_IsRequired_property() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mc => mc.Requires("DerivedData").HasValue(null)); + modelBuilder.Entity().Map(mc => mc.Requires(b => b.DerivedData).HasValue()); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + Assert.False( + databaseMapping.Model.EntityTypes.Single(et => et.Name == "TPHDerived").Properties.Single( + p => p.Name == "DerivedData").Nullable); + + databaseMapping.Assert() + .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData"); + databaseMapping.Assert("TPHBases") + .Column("DerivedData") + .DbEqual(null, f => f.MaxLength); + databaseMapping.AssertMapping("TPHBases", false) + .HasNoPropertyConditions() + .HasNullabilityColumnCondition("DerivedData", false); + databaseMapping.AssertMapping("TPHBases", false) + .HasNoPropertyConditions() + .HasNullabilityColumnCondition("DerivedData", true); + } + + [Fact] + public void NotNull_condition_works_with_IsRequired() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mc => mc.Requires("DerivedData").HasValue(null)); + modelBuilder.Entity().Map(mc => mc.Requires(b => b.DerivedData).HasValue()); + modelBuilder.Entity().Property(b => b.DerivedData).IsRequired(); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + Assert.False( + databaseMapping.Model.EntityTypes.Single(et => et.Name == "TPHDerived").Properties.Single( + p => p.Name == "DerivedData").Nullable); + databaseMapping.Assert() + .HasColumns("Id", "BaseData", "IntProp", "NullableIntProp", "DerivedData"); + databaseMapping.Assert("TPHBases") + .Column("DerivedData") + .DbEqual(null, f => f.MaxLength); + databaseMapping.AssertMapping("TPHBases") + .HasNoPropertyConditions() + .HasNullabilityColumnCondition("DerivedData", false); + databaseMapping.AssertMapping("TPHBases", false) + .HasNoPropertyConditions() + .HasNullabilityColumnCondition("DerivedData", true); + } + + [Fact] + public void NotNull_condition_on_derived_with_abstract_base_in_TPH_and_base_condition_ignored() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mc => mc.Requires("L1Data").HasValue(null)); + modelBuilder.Entity().Map(mc => mc.Requires(e => e.L1Data).HasValue()); + modelBuilder.Entity().Property(b => b.L1Data); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.AssertMapping("AbsAtBases").HasNoColumnConditions(); + databaseMapping.AssertMapping("AbsAtBases").HasNullabilityColumnCondition("L1Data", false); + } + + [Fact] + public void NotNull_condition_with_IsOptional_throws() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mc => mc.Requires("DerivedData").HasValue(null)); + modelBuilder.Entity().Map(mc => mc.Requires(b => b.DerivedData).HasValue()); + modelBuilder.Entity().Property(b => b.DerivedData).IsOptional(); + modelBuilder.Ignore(); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Tree_hierarchy_can_map_to_same_table() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + mc => + { + mc.Requires("MyDisc").HasValue("a"); + mc.ToTable("Woof"); + }) + .Map( + mc => + { + mc.Requires("MyDisc").HasValue("b"); + mc.ToTable("Woof"); + }) + .Map( + mc => + { + mc.Requires("MyDisc").HasValue("c"); + mc.ToTable("Woof"); + }); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Woof") + .HasColumns("Id", "RootData", "AData", "BData", "MyDisc"); + databaseMapping.Assert("Woof") + .Column("MyDisc") + .DbEqual(DatabaseMappingGenerator.DiscriminatorMaxLength, f => f.MaxLength); + databaseMapping.AssertMapping("Woof", false) + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "a"); + databaseMapping.AssertMapping("Woof") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "b"); + databaseMapping.AssertMapping("Woof") + .HasNoPropertyConditions() + .HasColumnCondition("MyDisc", "c"); + } + + [Fact] + public void Changing_only_root_table_moves_all_TPH_hierarchy() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.ToTable("Woof"); }); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Woof") + .HasColumns("Id", "RootData", "AData", "BData", "Discriminator"); + databaseMapping.Assert("Woof") + .Column("Discriminator") + .DbEqual(DatabaseMappingGenerator.DiscriminatorMaxLength, f => f.MaxLength); + databaseMapping.AssertMapping("Woof", false) + .HasNoPropertyConditions() + .HasColumnCondition("Discriminator", "TPHRoot"); + databaseMapping.AssertMapping("Woof") + .HasNoPropertyConditions() + .HasColumnCondition("Discriminator", "TPHNodeA"); + databaseMapping.AssertMapping("Woof") + .HasNoPropertyConditions() + .HasColumnCondition("Discriminator", "TPHNodeB"); + } + + [Fact] + public void Null_discriminator_value_gets_string_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("disc").HasValue(null); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert() + .HasColumns("Id", "Name", "disc") + .DbEqual("nvarchar", tm => tm.Properties.Single(c => c.Name == "disc").TypeName) + .DbEqual(128, tm => tm.Properties.Single(c => c.Name == "disc").MaxLength); + databaseMapping.AssertMapping("IsolatedIslands") + .HasNullabilityColumnCondition("disc", true); + } + + [Fact] + public void Null_discriminator_value_with_specified_length_gets_string_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { mc.Requires("disc").HasValue(null).HasMaxLength(100); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert() + .HasColumns("Id", "Name", "disc") + .DbEqual("nvarchar", tm => tm.Properties.Single(c => c.Name == "disc").TypeName) + .DbEqual(100, tm => tm.Properties.Single(c => c.Name == "disc").MaxLength); + databaseMapping.AssertMapping("IsolatedIslands") + .HasNullabilityColumnCondition("disc", true); + } + + [Fact] + public void FKs_in_base_type_remain_non_nullable_with_nullability_condition() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasKey( + e => new + { + e.Key1, + e.Key2, + }); + modelBuilder.Entity().Map( + mapping => { mapping.Requires(e => e.Discriminator1).HasValue(); }); + modelBuilder.Entity().Map( + mapping => { mapping.Requires("Discriminator1").HasValue(null); }); + modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany(). + HasForeignKey( + dependent => new + { + dependent.PrincipalKey1, + dependent.PrincipalKey2, + }); + modelBuilder.Entity().Property(p => p.PrincipalKey1).IsRequired(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert() + .DbEqual(false, tm => tm.Properties.Single(c => c.Name == "PrincipalKey1").Nullable) + .DbEqual(false, tm => tm.Properties.Single(c => c.Name == "PrincipalKey2").Nullable); + } + + [Fact] + public void FKs_in_base_type_remain_non_nullable_with_nullability_condition_when_base_defined_first() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasKey( + e => new + { + e.Key1, + e.Key2, + }); + modelBuilder.Entity().Map( + mapping => { mapping.Requires("Discriminator1").HasValue(null); }); + modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany(). + HasForeignKey( + dependent => new + { + dependent.PrincipalKey1, + dependent.PrincipalKey2, + }); + modelBuilder.Entity().Property(p => p.PrincipalKey1).IsRequired(); + modelBuilder.Entity().Map( + mapping => { mapping.Requires(e => e.Discriminator1).HasValue(); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert() + .DbEqual(false, tm => tm.Properties.Single(c => c.Name == "PrincipalKey1").Nullable) + .DbEqual(false, tm => tm.Properties.Single(c => c.Name == "PrincipalKey2").Nullable); + } + + [Fact] + // Repro for pending 136283 + public void Three_level_TPH_with_abstract_middle_has_nullable_discriminatorx() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .HasKey(e => e.Key1); + modelBuilder.Entity().Map( + mapping => + { + mapping.Requires("Discriminator2") + .HasValue("zbpmhdbllp") + .IsRequired() + .HasColumnType("nchar") + .HasMaxLength(30) + .IsUnicode() + .IsFixedLength(); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.Requires("Discriminator2").HasValue(""); + mapping.Requires("Discriminator1").HasValue( + "analysismapping").HasColumnType("varchar"). + HasMaxLength(20).IsVariableLength(); + }); + modelBuilder.Entity() + .HasMany(e => e.DependentNavigation) + .WithOptional() + .Map(m => m.MapKey(new[] { "IndependentColumn1" })); + + modelBuilder.Entity().Map( + mapping => + { + mapping.Requires("Discriminator2") + .HasValue(""); + mapping.Requires("Discriminator1") + .HasValue("authenticode"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert() + .DbEqual(false, tm => tm.Properties.Single(c => c.Name == "Discriminator2").Nullable) + .DbEqual(true, tm => tm.Properties.Single(c => c.Name == "Discriminator1").Nullable); + } + + [Fact] + public void Three_level_TPH_with_abstract_middle_with_IA_self_ref() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map( + mapping => + { + mapping.Requires("Discriminator2").HasValue("zbpmhdbllp").IsRequired().HasColumnType("nchar"). + HasMaxLength(30).IsUnicode().IsFixedLength(); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.Requires("Discriminator2").HasValue(""); + mapping.Requires("Discriminator1").HasValue( + "analysismapping").HasColumnType("varchar"). + HasMaxLength(20).IsVariableLength(); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.Requires("Discriminator2").HasValue(""); + mapping.Requires("Discriminator1").HasValue("authenticode"); + }); + modelBuilder.Entity().HasKey(e => e.Key1); + modelBuilder.Entity() + .HasMany(e => e.DependentNavigation) + .WithOptional() + .Map(m => m.MapKey(new[] { "IndependentColumn1" })); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("ThreeLevelBases") + .HasColumns( + "Key1", "BaseProperty", "DerivedProperty1", "IndependentColumn1", "Discriminator2", + "Discriminator1"); + + databaseMapping.AssertMapping("ThreeLevelBases", false) + .HasColumnCondition("Discriminator2", "zbpmhdbllp"); + + databaseMapping.AssertNoMapping(); + + databaseMapping.AssertMapping("ThreeLevelBases") + .HasColumnCondition("Discriminator2", "") + .HasColumnCondition("Discriminator1", "authenticode"); + } + + [Fact] + public void Derived_association_creates_nullable_FKs_in_TPH() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + + modelBuilder.Entity().HasOptional(e => e.DependentNavigation).WithRequired( + e => e.PrincipalNavigation); + modelBuilder.Entity().Property(p => p.BaseProperty).HasColumnType("time"); + modelBuilder.Entity().HasKey( + e => new + { + e.Key1, + e.Key2, + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert() + .DbEqual(true, tm => tm.Properties.Single(c => c.Name == "PrincipalNavigation_Key1").Nullable) + .DbEqual(true, tm => tm.Properties.Single(c => c.Name == "PrincipalNavigation_Key1").Nullable); + } + + [Fact] + public void Base_FK_association_to_abstract_dependent_in_TPH() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasKey(e => e.Key1); + modelBuilder.Entity() + .HasRequired(e => e.PrincipalNavigation) + .WithMany(e => e.DependentNavigation) + .HasForeignKey( + dependent => new + { + dependent.PrincipalKey1 + }); + modelBuilder.Entity().Map( + mapping => { mapping.Requires("Discriminator1").HasValue("kssfjohr"); }); + modelBuilder.Entity().Map( + mapping => + { + mapping.Requires("Discriminator1").HasValue("qrpnfdzhixxjujsgfsryoffpelbaxhtankvxlz").IsRequired(). + HasColumnType("nvarchar").HasMaxLength(40).IsUnicode().IsVariableLength(); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("AbsDep_Principal") + .HasColumns("Key1") + .HasNoForeignKeyColumns(); + + databaseMapping.Assert("AbsDep_Dependent") + .HasColumns("Id", "PrincipalKey1", "DerivedProperty1", "Discriminator1") + .HasForeignKeyColumn("PrincipalKey1", "AbsDep_Principal"); + } + + [Fact] + public void Base_IA_association_to_abstract_dependent_in_TPH() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasKey(e => e.Key1); + modelBuilder.Entity() + .HasRequired(e => e.PrincipalNavigation) + .WithMany(e => e.DependentNavigation) + .Map(im => im.MapKey("IndependentKey1")); + modelBuilder.Entity().Map( + mapping => { mapping.Requires("Discriminator1").HasValue("kssfjohr"); }); + modelBuilder.Entity().Map( + mapping => + { + mapping.Requires("Discriminator1").HasValue("qrpnfdzhixxjujsgfsryoffpelbaxhtankvxlz").IsRequired(). + HasColumnType("nvarchar").HasMaxLength(40).IsUnicode().IsVariableLength(); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("AbsDep_Principal") + .HasColumns("Key1") + .HasNoForeignKeyColumns(); + + databaseMapping.Assert("AbsDep_Dependent") + .HasColumns("Id", "PrincipalKey1", "DerivedProperty1", "IndependentKey1", "Discriminator1") + .HasForeignKeyColumn("IndependentKey1", "AbsDep_Principal"); + } + + [Fact] + public void Requires_property_is_sufficient_for_base() + { + var modelBuilder = new AdventureWorksModelBuilder(); + modelBuilder.Entity(); + modelBuilder.Entity().Map( + mapping => { mapping.Requires(e => e.DiscriminatorNotNull).HasValue(); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + } + + [Fact] + public void Condition_column_configuration_on_abstract_base_applied_to_column() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map( + mapping => + { + mapping.Requires("DiscriminatorValue").HasValue("2").IsRequired().HasColumnType("nchar"). + HasMaxLength(30).IsUnicode().IsFixedLength(); + }); + modelBuilder.Entity().Map( + mapping => { mapping.Requires("DiscriminatorValue").HasValue("1"); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert() + .DbEqual("nchar", t => t.Properties.Single(c => c.Name == "DiscriminatorValue").TypeName) + .DbEqual(30, t => t.Properties.Single(c => c.Name == "DiscriminatorValue").MaxLength); + } + + [Fact] + public void TPH_with_an_IA_from_abstract_non_root_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany( + e => e.DependentNavigation); + modelBuilder.Entity().Map( + mapping => { mapping.Requires("DiscriminatorValue").HasValue("2"); }); + modelBuilder.Entity().Map( + mapping => { mapping.Requires("DiscriminatorValue").HasValue("1"); }); + modelBuilder.Entity().Map( + mapping => + { + mapping.Requires("DiscriminatorValue").HasValue("3").IsRequired().HasColumnType("nvarchar(max)"). + IsUnicode(); + }); + modelBuilder.Entity().HasKey(e => e.Key1); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + } + + [Fact] + public void TPH_with_an_FK_from_abstract_root_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasKey(e => e.Key1); + modelBuilder.Entity().HasKey(e => e.Key1); + modelBuilder.Entity().HasOptional(e => e.DependentNavigation).WithRequired( + e => e.PrincipalNavigation); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("BasePrincipal"); }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + } + + [Fact] + public void TPH_with_self_ref_FK_on_derived_type_has_non_nullable_FK_when_base_type_is_abstract() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map( + mapping => { mapping.Requires("DiscriminatorValue").HasValue(1).HasColumnType("tinyint"); }); + modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany( + e => e.DependentNavigation).Map(m => { }); + modelBuilder.Entity().HasKey(e => e.Key1); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert() + .HasColumns("Key1", "BaseProperty", "PrincipalNavigation_Key1", "DiscriminatorValue") + .HasForeignKeyColumn("PrincipalNavigation_Key1") + .DbEqual(false, t => t.Properties.Single(c => c.Name == "PrincipalNavigation_Key1").Nullable); + } + + [Fact] + public void + TPH_with_self_ref_FK_on_derived_type_has_nullable_FK_when_base_type_is_abstract_but_there_are_other_nonrelated_derived_types() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map( + mapping => { mapping.Requires("DiscriminatorValue").HasValue(1).HasColumnType("tinyint"); }); + modelBuilder.Entity().Map( + mapping => { mapping.Requires("DiscriminatorValue").HasValue(0); }); + modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany( + e => e.DependentNavigation).Map(m => { }); + modelBuilder.Entity().HasKey(e => e.Key1); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert() + .HasColumns("Key1", "BaseProperty", "OtherData", "PrincipalNavigation_Key1", "DiscriminatorValue") + .HasForeignKeyColumn("PrincipalNavigation_Key1") + .DbEqual(true, t => t.Properties.Single(c => c.Name == "PrincipalNavigation_Key1").Nullable); + } + + [Fact] + public void TPH_with_self_ref_FK_on_derived_type_has_nullable_FK_when_base_type_is_concrete() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map( + mapping => { mapping.Requires("DiscriminatorValue").HasValue(0).HasColumnType("tinyint"); }); + modelBuilder.Entity().Map( + mapping => { mapping.Requires("DiscriminatorValue").HasValue(1); }); + modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany( + e => e.DependentNavigation).Map(m => { }); + modelBuilder.Entity().HasKey(e => e.Key1); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert() + .HasColumns("Key1", "BaseProperty", "PrincipalNavigation_Key1", "DiscriminatorValue") + .HasForeignKeyColumn("PrincipalNavigation_Key1") + .DbEqual(true, t => t.Properties.Single(c => c.Name == "PrincipalNavigation_Key1").Nullable); + } + + #endregion + + #region Basic TPT Tests + + [Fact] + public void ToTable_configures_basic_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Bases"); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Entity().ToTable("Deriveds"); + modelBuilder.Entity().Ignore(b => b.AssocRelated); + modelBuilder.Entity().Ignore(b => b.AssocRelatedId); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + Assert.Equal( + 2, + databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Single().EntityTypeMappings. + Count()); + + databaseMapping.Assert("Bases"); + databaseMapping.Assert("Deriveds"); + } + + [Fact] + public void ToTable_configures_TPT_with_unmapped_abstract_base_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("L1"); + modelBuilder.Entity().ToTable("L2"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + Assert.Equal( + 2, + databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Single().EntityTypeMappings. + Count()); + databaseMapping.Assert("L1"); + databaseMapping.Assert("L2"); + } + + [Fact] + public void ToTable_configures_TPT_with_mapped_abstract_base_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Bases"); + modelBuilder.Entity().ToTable("L1"); + modelBuilder.Entity().ToTable("L2"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + Assert.Equal( + 3, + databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Single().EntityTypeMappings. + Count()); + + databaseMapping.Assert("Bases"); + databaseMapping.Assert("L1"); + databaseMapping.Assert("L2"); + } + + [Fact] + public void ToTable_configures_TPT_with_FK_on_base_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Bases"); + modelBuilder.Entity().Ignore(b => b.AssocRelated); + modelBuilder.Entity().Ignore(b => b.AssocRelatedId); + modelBuilder.Entity().ToTable("Derived"); + modelBuilder.Entity().Ignore(r => r.Deriveds); + modelBuilder.Entity().Ignore(r => r.RefBase); + modelBuilder.Entity().Ignore(r => r.RefDerived); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Bases"); + databaseMapping.Assert("Derived"); + databaseMapping.Assert().HasForeignKeyColumn("AssocRelatedBaseId"); + } + + [Fact] + public void ToTable_configures_TPT_with_FK_on_derived_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Bases"); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Entity().ToTable("Derived"); + modelBuilder.Entity().Ignore(r => r.Bases); + modelBuilder.Entity().Ignore(r => r.RefBase); + modelBuilder.Entity().Ignore(r => r.RefDerived); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Bases"); + databaseMapping.Assert("Derived"); + databaseMapping.Assert().HasForeignKeyColumn("AssocRelatedId"); + } + + [Fact] + public void ToTable_configures_TPT_with_IA_on_base_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Bases"); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Entity().Ignore(b => b.AssocRelated); + modelBuilder.Entity().Ignore(b => b.AssocRelatedId); + modelBuilder.Entity().ToTable("Derived"); + modelBuilder.Entity().Ignore(r => r.Deriveds); + modelBuilder.Entity().Ignore(r => r.RefBase); + modelBuilder.Entity().Ignore(r => r.RefDerived); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Bases"); + databaseMapping.Assert("Derived"); + databaseMapping.Assert().HasForeignKeyColumn("AssocRelatedBase_Id"); + } + + [Fact] + public void ToTable_configures_TPT_with_IA_on_derived_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Bases"); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Entity().ToTable("Derived"); + modelBuilder.Entity().Ignore(x => x.AssocRelatedId); + modelBuilder.Entity().Ignore(r => r.Bases); + modelBuilder.Entity().Ignore(r => r.RefBase); + modelBuilder.Entity().Ignore(r => r.RefDerived); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Bases"); + databaseMapping.Assert("Derived"); + databaseMapping.Assert().HasForeignKeyColumn("AssocRelated_Id"); + } + + [Fact] + public void ToTable_configures_TPT_with_IA_on_derived_type_with_configured_relationship() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasRequired(e => e.AssocRelated).WithOptional(e => e.RefDerived); + + modelBuilder.Entity().ToTable("Bases"); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + + modelBuilder.Entity().ToTable("Derived"); + modelBuilder.Entity().Ignore(x => x.AssocRelatedId); + modelBuilder.Entity().Ignore(r => r.Bases); + modelBuilder.Entity().Ignore(r => r.RefBase); + modelBuilder.Entity().Ignore(r => r.Deriveds); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Bases"); + databaseMapping.Assert("Derived"); + // 1:0..1 makes Id the FK for the AssocRelated to AssocDerived relationship + databaseMapping.Assert().DbEqual(2, t => t.ForeignKeyBuilders.Count()); + databaseMapping.Assert().HasForeignKeyColumn("Id", "Bases"); + databaseMapping.Assert().HasForeignKeyColumn("Id", "AssocRelateds"); + } + + [Fact] + public void ToTable_configures_TPT_and_sets_FK_to_base_table() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("A"); + modelBuilder.Entity().ToTable("B"); + modelBuilder.Entity().ToTable("C"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert("B").HasForeignKeyColumn("Id", "A") + .DbEqual(1, t => t.ForeignKeyBuilders.Count()); + databaseMapping.Assert("C").HasForeignKeyColumn("Id", "B") + .DbEqual(1, t => t.ForeignKeyBuilders.Count()); + } + + [Fact] + public void ToTable_configures_TPT_and_creates_single_FK_to_related() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Property(p => p.Key1).HasColumnType("uniqueidentifier"); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); + modelBuilder.Entity().HasKey( + e => new + { + e.Key1, + e.Key2, + }); + + modelBuilder.Entity().Property(p => p.Key1).HasColumnType("uniqueidentifier"); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Images"); }); + modelBuilder.Entity().HasKey( + e => new + { + e.Key1, + e.Key2, + }); + + modelBuilder.Entity().HasRequired(e => e.CKCategory).WithOptional().WillCascadeOnDelete(true); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); + modelBuilder.Entity().HasKey( + e => new + { + e.CKCategoryKey1, + e.CKCategoryKey2, + }); + + modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); + modelBuilder.Entity().HasRequired(dp => dp.Image).WithOptional(); + + modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent2"); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert() + .DbEqual(0, t => t.ForeignKeyBuilders.Count()); + + databaseMapping.Assert() + .DbEqual(1, t => t.ForeignKeyBuilders.Count()) + .HasForeignKey(new[] { "CKCategoryKey1", "CKCategoryKey2" }, "Principal"); + + databaseMapping.Assert() + .DbEqual(2, t => t.ForeignKeyBuilders.Count()) + .HasForeignKey(new[] { "CKCategoryKey1", "CKCategoryKey2" }, "Dependent") + .HasForeignKey(new[] { "CKCategoryKey1", "CKCategoryKey2" }, "Images"); + + databaseMapping.Assert() + .DbEqual(1, t => t.ForeignKeyBuilders.Count()) + .HasForeignKey(new[] { "CKCategoryKey1", "CKCategoryKey2" }, "DerivedDependent"); + } + + [Fact] + public void ToTable_configures_TPT_and_creates_single_FK_to_self_reference() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasKey(e => e.Key1); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("SelfRefBase"); }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("SelfRefDerived"); }); + modelBuilder.Entity().HasOptional(e => e.SelfRefNavigation).WithMany().HasForeignKey( + d => new + { + d.DependentKey1 + }).WillCascadeOnDelete(false); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert() + .DbEqual(0, t => t.ForeignKeyBuilders.Count()); + + databaseMapping.Assert() + .DbEqual(2, t => t.ForeignKeyBuilders.Count()) + .HasForeignKeyColumn("Key1", "SelfRefBase") + .HasForeignKeyColumn("DependentKey1", "SelfRefDerived"); + } + + [Fact] + public void TPT_moves_FKs_pointing_to_moved_table() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("A"); + modelBuilder.Entity().ToTable("B"); + modelBuilder.Entity().ToTable("C"); + modelBuilder.Entity().HasRequired(c => c.Repro136761_B).WithMany().HasForeignKey( + c => c.Repro136761_BId); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert() + .DbEqual(0, t => t.ForeignKeyBuilders.Count()); + + databaseMapping.Assert() + .DbEqual(1, t => t.ForeignKeyBuilders.Count()) + .HasForeignKeyColumn("Repro136761_AId", "A"); + + databaseMapping.Assert() + .DbEqual(1, t => t.ForeignKeyBuilders.Count()) + .HasForeignKeyColumn("Repro136761_BId", "B"); + } + + [Fact] + public void FKs_in_base_type_remain_non_nullable_with_nullability_condition_in_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Property(p => p.DerivedProperty1).HasColumnType("bit"); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); + modelBuilder.Entity().Property(p => p.Key1).HasColumnType("smalldatetime"); + modelBuilder.Entity().HasKey(e => e.Key1); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert() + .DbEqual(false, tm => tm.Properties.Single(c => c.Name == "Key1").Nullable); + } + + [Fact] + public void FKs_in_base_type_remain_non_nullable_with_nullability_condition_when_base_defined_first_in_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); + modelBuilder.Entity().Property(p => p.DerivedProperty1).HasColumnType("bit"); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); + modelBuilder.Entity().Property(p => p.Key1).HasColumnType("smalldatetime"); + modelBuilder.Entity().HasKey(e => e.Key1); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert() + .DbEqual(false, tm => tm.Properties.Single(c => c.Name == "Key1").Nullable); + } + + [Fact] + public void IA_Association_between_subtypes_with_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasKey(e => e.Key1); + modelBuilder.Entity().HasMany(e => e.THABS_DependentNavigation); + modelBuilder.Entity().HasOptional(e => e.THABS_PrincipalNavigation); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("BasePrincipal"); }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("BasePrincipal") + .HasColumns("Key1", "BaseProperty") + .HasNoForeignKeyColumns(); + + databaseMapping.Assert("Principal") + .HasColumns("Key1") + .HasForeignKeyColumn("Key1", "BasePrincipal"); + + databaseMapping.Assert("Dependent") + .HasColumns("Id", "THABS_PrincipalNavigation_Key1") + .HasForeignKeyColumn("THABS_PrincipalNavigation_Key1", "Principal"); + + databaseMapping.Assert("DerivedDependent") + .HasColumns("Id", "DerivedProperty1") + .HasForeignKeyColumn("Id", "Dependent"); + } + + [Fact] + public void Self_referencing_relationship_on_derived_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Base"); }); + modelBuilder.Entity().HasKey( + e => new + { + e.Key1, + e.Key2, + }); + modelBuilder.Entity().HasMany(e => e.Navigation).WithMany(); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Derived"); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Base") + .HasColumns("Key1", "Key2", "BaseProperty") + .HasNoForeignKeyColumns(); + + databaseMapping.Assert("Derived") + .HasColumns("Key1", "Key2") + .HasForeignKey(new[] { "Key1", "Key2" }, "Base"); + + var joinTable = databaseMapping.Database.EntityTypes.ElementAt(1); + Assert.Equal("SRDerivedSRDeriveds", databaseMapping.Database.GetEntitySet(joinTable).Table); + Assert.True( + joinTable.Properties.Select(x => x.Name).SequenceEqual( + new[] + { + "SRDerived_Key1", "SRDerived_Key2", + "SRDerived_Key11", "SRDerived_Key21" + })); + Assert.Equal(2, joinTable.ForeignKeyBuilders.Count()); + Assert.True( + joinTable.ForeignKeyBuilders.All( + fk => databaseMapping.Database.GetEntitySet(fk.PrincipalTable).Table == "Derived")); + } + + [Fact] + public void ToTable_TPT_to_same_base_table_results_in_default_TPH() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("A1"); + modelBuilder.Entity().ToTable("A1"); + modelBuilder.Entity().ToTable("A1"); + modelBuilder.Entity().ToTable("A1"); + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.AssertMapping("A1", false) + .HasColumnCondition("Discriminator", "Repro137329_A1"); + } + + [Fact] + public void IA_between_TPT_subtypes_has_FK_to_sub_table() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("BaseEntities"); + modelBuilder.Entity().ToTable("Entity1s"); + modelBuilder.Entity().Ignore(x => x.Repro109944_Entity2ID); + modelBuilder.Entity().ToTable("Entity2s"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert() + .HasNoForeignKeyColumns(); + databaseMapping.Assert() + .HasForeignKeyColumn("ID", "BaseEntities") + .HasForeignKeyColumn("Repro109944_Entity2_ID", "Entity2s"); + databaseMapping.Assert() + .HasForeignKeyColumn("ID", "BaseEntities"); + } + + [Fact] + public void FK_between_TPT_subtypes_has_FK_to_sub_table() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("BaseEntities"); + modelBuilder.Entity().ToTable("Entity1s"); + modelBuilder.Entity().ToTable("Entity2s"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert() + .HasNoForeignKeyColumns(); + databaseMapping.Assert() + .HasForeignKeyColumn("ID", "BaseEntities") + .HasForeignKeyColumn("Repro109944_Entity2ID", "Entity2s"); + databaseMapping.Assert() + .HasForeignKeyColumn("ID", "BaseEntities"); + } + + [Fact] + public void FK_between_TPT_base_types_has_FK_to_base_table() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedPrincipal"); }); + modelBuilder.Entity().HasKey(e => e.Key1); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert("Dependent") + .HasForeignKeyColumn("Key1", "Principal"); + } + + [Fact] + public void IA_between_TPT_base_types_has_FK_to_base_table() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); + modelBuilder.Entity().Ignore(x => x.Key1); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("DerivedPrincipal"); }); + modelBuilder.Entity().HasKey(e => e.Key1); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert("Dependent") + .HasForeignKeyColumn("PrincipalNavigation_Key1", "Principal"); + } + + [Fact] + public void TPT_with_multiple_associations_in_hierarchy() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("BaseEntities"); + modelBuilder.Entity().ToTable("SomeEntities"); + modelBuilder.Entity().ToTable("SomeMores"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + } + + [Fact] + public void TPT_with_asociation_between_middle_types() + { + var builder = new AdventureWorksModelBuilder(); + + builder.Entity().HasMany(e => e.DependentNavigation); + // Works if this line is commented out. + builder.Entity().Property(p => p.DerivedProperty1).HasColumnType( + "nvarchar(max)").IsUnicode(); + builder.Entity().HasRequired(e => e.PrincipalNavigation); + builder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); + builder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); + builder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); + builder.Entity().Property(p => p.BaseProperty).HasColumnType("date"); + builder.Entity().Map(mapping => { mapping.ToTable("BaseDependent"); }); + builder.Entity().Property(p => p.DerivedProperty1).HasColumnType("smallmoney"); + builder.Entity().Map(mapping => { mapping.ToTable("DerivedPrincipal"); }); + builder.Entity().HasKey(e => e.Key1); + builder.Entity().Property(p => p.PrincipalKey1).IsRequired(); + + var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + } + + [Fact] + public void TPT_with_no_asociation_between_middle_types() + { + var builder = new AdventureWorksModelBuilder(); + + builder.Entity().Ignore(e => e.DependentNavigation); + // Works if this line is commented out. + builder.Entity().Property(p => p.DerivedProperty1).HasColumnType( + "nvarchar(max)").IsUnicode(); + builder.Entity().Ignore(e => e.PrincipalNavigation); + builder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); + builder.Entity().Map(mapping => { mapping.ToTable("DerivedDependent"); }); + builder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); + builder.Entity().Property(p => p.BaseProperty).HasColumnType("date"); + builder.Entity().Map(mapping => { mapping.ToTable("BaseDependent"); }); + builder.Entity().Property(p => p.DerivedProperty1).HasColumnType("smallmoney"); + builder.Entity().Map(mapping => { mapping.ToTable("DerivedPrincipal"); }); + builder.Entity().HasKey(e => e.Key1); + builder.Entity().Property(p => p.PrincipalKey1).IsRequired(); + + var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + } + + [Fact] + public void TPT_with_required_to_optional_IA_on_derived_type_creates_non_nullable_FK() + { + var builder = new AdventureWorksModelBuilder(); + + builder.Entity().HasKey( + e => new + { + e.Key1, + e.Key2, + }); + builder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); + builder.Entity().Map(mapping => { mapping.ToTable("BaseDependent"); }); + builder.Entity().HasRequired(e => e.PrincipalNavigation).WithOptional( + e => e.DependentNavigation) + .Map(_ => { }).WillCascadeOnDelete(false); + + builder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); + builder.Ignore(); + + var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert("Dependent") + .DbEqual(false, t => t.Properties.Single(x => x.Name == "PrincipalNavigation_Id").Nullable); + } + + [Fact] + public void TPT_with_required_to_optional_IA_on_derived_middle_type_creates_non_nullable_FK() + { + var builder = new AdventureWorksModelBuilder(); + + builder.Entity().HasKey( + e => new + { + e.Key1, + e.Key2, + }); + builder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); + builder.Entity().Map(mapping => { mapping.ToTable("BaseDependent"); }); + builder.Entity().HasRequired(e => e.PrincipalNavigation).WithOptional( + e => e.DependentNavigation) + .Map(_ => { }).WillCascadeOnDelete(false); + + builder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); + builder.Entity().ToTable("DerivedDependent"); + + var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert("Dependent") + .DbEqual(false, t => t.Properties.Single(x => x.Name == "PrincipalNavigation_Id").Nullable); + } + + [Fact] + public void Uniquification_happens_correctly_when_relationship_with_same_name_exists_in_two_derived_types() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().ToTable("BaseEmployee"); + modelBuilder.Entity().ToTable("TargetEmployee"); + modelBuilder.Entity().ToTable("Note"); + modelBuilder.Entity().ToTable("NoteWithRelationship1"); + modelBuilder.Entity().HasRequired(x => x.TargetEmployee); + modelBuilder.Entity().ToTable("NoteWithRelationship2"); + modelBuilder.Entity().HasRequired(x => x.TargetEmployee); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Uniquification_happens_correctly_when_complex_type_reused_in_derived_types() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + #endregion + + #region Basic TPC Tests + + [Fact] + public void Two_entity_TPC() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => mc.ToTable("Bases")); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Entity() + .Map( + mc => + { + mc.MapInheritedProperties(); + mc.ToTable("Deriveds"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelated); + modelBuilder.Entity().Ignore(b => b.AssocRelatedId); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + Assert.Equal( + 2, + databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Single().EntityTypeMappings. + Count()); + databaseMapping.Assert("Bases").HasColumns("Id", "Name", "BaseData"); + databaseMapping.AssertMapping("Bases", false); + databaseMapping.Assert("Deriveds").HasColumns( + "Id", "Name", "BaseData", "DerivedData1", + "DerivedData2"); + databaseMapping.AssertMapping("Deriveds", false); + } + + [Fact] + public void Two_entity_TPC_with_multiple_nonconflicting_configurations() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => mc.ToTable("Bases")); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + + Assert.Throws( + () => + modelBuilder.Entity() + .Map(mc => { mc.Properties(d => d.DerivedData1); }) + .Map(mc => { mc.Properties(d => d.DerivedData2); }) + .Map(mc => { mc.MapInheritedProperties(); }) + .Map(mc => { mc.ToTable("Deriveds"); })); + } + + [Fact] + public void Two_entity_TPC_with_column_override() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => mc.ToTable("Bases")) + .Property(a => a.Name).HasColumnType("char"); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Entity() + .Map( + mc => + { + mc.MapInheritedProperties(); + mc.ToTable("Deriveds"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelated); + modelBuilder.Entity().Ignore(b => b.AssocRelatedId); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + Assert.Equal( + 2, + databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Single().EntityTypeMappings. + Count()); + databaseMapping.Assert("Bases").HasColumns("Id", "Name", "BaseData"); + databaseMapping.Assert("Bases").DbEqual( + "char", + x => x.Properties.Single(c => c.Name == "Name").TypeName); + databaseMapping.Assert("Deriveds").HasColumns( + "Id", "Name", "BaseData", "DerivedData1", + "DerivedData2"); + databaseMapping.Assert("Deriveds").DbEqual( + "char", + x => + x.Properties.Single(c => c.Name == "Name").TypeName); + } + + //[Fact] + //public void ToTable_configures_TPT_with_unmapped_abstract_base_type() + //{ + // var modelBuilder = new AdventureWorksModelBuilder(); + + // modelBuilder.Entity().ToTable("L1"); + // modelBuilder.Entity().ToTable("L2"); + + // var databaseMapping = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; + + // Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + // Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Single().EntityTypeMappings.Count); + // Assert.True(databaseMapping.Database.Schemas.Single().Tables.Any(t => t.Name == "L1")); + // Assert.True(databaseMapping.Database.Schemas.Single().Tables.Any(t => t.Name == "L2")); + //} + + //[Fact] + //public void ToTable_configures_TPT_with_mapped_abstract_base_type() + //{ + // var modelBuilder = new AdventureWorksModelBuilder(); + + // modelBuilder.Entity().ToTable("Bases"); + // modelBuilder.Entity().ToTable("L1"); + // modelBuilder.Entity().ToTable("L2"); + + // var databaseMapping = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; + + // Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + // Assert.Equal(3, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Single().EntityTypeMappings.Count); + // Assert.True(databaseMapping.Database.Schemas.Single().Tables.Any(t => t.Name == "Bases")); + // Assert.True(databaseMapping.Database.Schemas.Single().Tables.Any(t => t.Name == "L1")); + // Assert.True(databaseMapping.Database.Schemas.Single().Tables.Any(t => t.Name == "L2")); + //} + + [Fact] + public void ToTable_configures_TPC_with_FK_on_base_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Bases"); + modelBuilder.Entity().Ignore(b => b.AssocRelated); + modelBuilder.Entity().Ignore(b => b.AssocRelatedId); + modelBuilder.Entity() + .Map( + mc => + { + mc.MapInheritedProperties(); + mc.ToTable("Deriveds"); + }); + modelBuilder.Entity().Ignore(r => r.Deriveds); + modelBuilder.Entity().Ignore(r => r.RefBase); + modelBuilder.Entity().Ignore(r => r.RefDerived); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Bases").HasColumns("Id", "Name", "BaseData", "AssocRelatedBaseId"); + databaseMapping.Assert("Deriveds").HasColumns( + "Id", "Name", "BaseData", "AssocRelatedBaseId", + "DerivedData1", "DerivedData2"); + databaseMapping.Assert("Bases").HasForeignKeyColumn("AssocRelatedBaseId"); + databaseMapping.Assert("Deriveds").HasForeignKeyColumn("AssocRelatedBaseId"); + } + + [Fact] + public void ToTable_configures_TPC_with_FK_on_derived_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Bases"); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Entity() + .Map( + mc => + { + mc.MapInheritedProperties(); + mc.ToTable("Deriveds"); + }); + modelBuilder.Entity().Ignore(r => r.Bases); + modelBuilder.Entity().Ignore(r => r.RefBase); + modelBuilder.Entity().Ignore(r => r.RefDerived); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Bases").HasColumns("Id", "Name", "BaseData"); + databaseMapping.Assert("Deriveds").HasColumns( + "Id", "Name", "BaseData", "AssocRelatedId", + "DerivedData1", "DerivedData2"); + databaseMapping.Assert("Deriveds").HasForeignKeyColumn("AssocRelatedId"); + } + + [Fact] + public void ToTable_configures_TPC_with_IA_on_derived_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Bases"); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Entity() + .Map( + mc => + { + mc.MapInheritedProperties(); + mc.ToTable("Deriveds"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelatedId); + modelBuilder.Entity().Ignore(r => r.Bases); + modelBuilder.Entity().Ignore(r => r.RefBase); + modelBuilder.Entity().Ignore(r => r.RefDerived); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Bases").HasColumns("Id", "Name", "BaseData"); + databaseMapping.Assert("Deriveds").HasColumns( + "Id", "AssocRelated_Id", "Name", "BaseData", + "DerivedData1", "DerivedData2"); + databaseMapping.Assert("Deriveds").HasForeignKeyColumn("AssocRelated_Id"); + } + + [Fact] + public void ToTable_configures_TPC_and_creates_single_FK_to_related() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Property(p => p.Key1).HasColumnType("uniqueidentifier"); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Principal"); }); + modelBuilder.Entity().HasKey( + e => new + { + e.Key1, + e.Key2, + }); + modelBuilder.Entity().HasRequired(e => e.CKCategory).WithOptional().WillCascadeOnDelete(true); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Dependent"); }); + modelBuilder.Entity().HasKey( + e => new + { + e.CKCategoryKey1, + e.CKCategoryKey2, + }); + + modelBuilder.Entity().Map( + mapping => + { + mapping.MapInheritedProperties(); + mapping.ToTable("DerivedDependent"); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.MapInheritedProperties(); + mapping.ToTable("DerivedDependent2"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert() + .DbEqual(0, t => t.ForeignKeyBuilders.Count()); + + databaseMapping.Assert() + .DbEqual(1, t => t.ForeignKeyBuilders.Count()) + .HasForeignKey(new[] { "CKCategoryKey1", "CKCategoryKey2" }, "Principal"); + + databaseMapping.Assert() + .DbEqual(1, t => t.ForeignKeyBuilders.Count()) + .HasForeignKey(new[] { "CKCategoryKey1", "CKCategoryKey2" }, "Principal"); + + databaseMapping.Assert() + .DbEqual(1, t => t.ForeignKeyBuilders.Count()) + .HasForeignKey(new[] { "CKCategoryKey1", "CKCategoryKey2" }, "Principal"); + } + + [Fact] + public void Mapping_store_type_propagates_to_derived_TPC_table() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().Property(x => x.DerivedData).HasColumnType("image"); + modelBuilder.Entity() + .Map( + mc => + { + mc.ToTable("Derived"); + mc.MapInheritedProperties(); + }); + modelBuilder.Entity() + .Map( + mc => + { + mc.ToTable("Derived2"); + mc.MapInheritedProperties(); + }); + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + databaseMapping.Assert().DbEqual( + "image", + t => t.Properties.Single(c => c.Name == "DerivedData").TypeName); + databaseMapping.Assert().DbEqual( + "image", + t => t.Properties.Single(c => c.Name == "DerivedData").TypeName); + } + + [Fact] + public void Mapping_store_type_propagates_to_dependent_IA() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Property(p => p.Key1).HasColumnType("date"); + modelBuilder.Entity().Property(p => p.Key2).HasColumnType("numeric").HasPrecision(15, 5); + modelBuilder.Entity().Map( + mapping => + { + mapping.MapInheritedProperties(); + mapping.ToTable("Repro165020_BaseDependent"); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.MapInheritedProperties(); + mapping.ToTable("Repro165020_BasePrincipal"); + }); + modelBuilder.Entity().HasKey( + e => new + { + e.Key1, + e.Key2, + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.MapInheritedProperties(); + mapping.ToTable("Repro165020_DerivedPrincipal"); + }); + + modelBuilder.Entity().Map( + mapping => + { + mapping.MapInheritedProperties(); + mapping.ToTable("Repro165020_DerivedDependent"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + databaseMapping.Assert().DbEqual( + "date", t => t.Properties.Single(c => c.Name == "PrincipalNavigation_Key1").TypeName); + databaseMapping.Assert().DbEqual( + "numeric", t => t.Properties.Single(c => c.Name == "PrincipalNavigation_Key2").TypeName); + } + + [Fact] + public void FK_association_to_principal_base_should_not_make_FK_in_TPC() + { + var modelBuilder = new AdventureWorksModelBuilder(); + modelBuilder.Entity(); + + modelBuilder.Entity() + .Map(m => m.ToTable("Department")) + .Map( + m => + { + m.MapInheritedProperties(); + m.ToTable("OldDepartment"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert().HasNoForeignKeyColumns(); + databaseMapping.Assert().HasNoForeignKeyColumns(); + databaseMapping.Assert().HasNoForeignKeyColumns(); + } + + [Fact] + public void Self_referencing_relationship_on_derived_TPC() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Base"); }); + modelBuilder.Entity().HasKey( + e => new + { + e.Key1, + e.Key2, + }); + modelBuilder.Entity().HasMany(e => e.Navigation).WithMany(); + modelBuilder.Entity().Map( + mapping => + { + mapping.MapInheritedProperties(); + mapping.ToTable("Derived"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Base") + .HasColumns("Key1", "Key2", "BaseProperty") + .HasNoForeignKeyColumns(); + + databaseMapping.Assert("Derived") + .HasColumns("Key1", "Key2", "BaseProperty") + .HasNoForeignKeyColumns(); + + var joinTable = databaseMapping.Database.EntityTypes.ElementAt(1); + Assert.Equal("SRDerivedSRDeriveds", databaseMapping.Database.GetEntitySet(joinTable).Table); + Assert.True( + joinTable.Properties.Select(x => x.Name).SequenceEqual( + new[] + { + "SRDerived_Key1", "SRDerived_Key2", + "SRDerived_Key11", "SRDerived_Key21" + })); + } + + [Fact] + public void TPC_with_abstract_base_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + m => + { + m.MapInheritedProperties(); + m.ToTable("Agencies"); + }) + .Map( + m => + { + m.MapInheritedProperties(); + m.ToTable("People"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Column_type_configuration_on_non_root_type_is_propagated_to_derived_types() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Property(e => e.Info).HasColumnType("varchar(max)"); + modelBuilder.Entity().Map( + m => { m.ToTable("Table1"); }); + modelBuilder.Entity().Map( + m => + { + m.MapInheritedProperties(); + m.ToTable("Table2"); + }); + modelBuilder.Entity().Map( + m => + { + m.MapInheritedProperties(); + m.ToTable("Table3"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Table2") + .DbEqual("varchar(max)", t => t.Properties.Single(c => c.Name == "Info").TypeName); + databaseMapping.Assert("Table3") + .DbEqual("varchar(max)", t => t.Properties.Single(c => c.Name == "Info").TypeName); + } + + [Fact] + public void Column_name_configuration_on_non_root_type_is_propagated_to_derived_types() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Property(e => e.Name).HasColumnName("NameOfProduct"); + modelBuilder.Entity().ToTable("Products"); + modelBuilder.Entity().Map(mapping => { mapping.MapInheritedProperties(); }). + ToTable("ClearanceProduct"); + modelBuilder.Entity().Map(mapping => { mapping.MapInheritedProperties(); }) + .ToTable("DiscontinuedProduct"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Products") + .DbEqual(true, t => t.Properties.Any(c => c.Name == "NameOfProduct")); + databaseMapping.Assert("ClearanceProduct") + .DbEqual(true, t => t.Properties.Any(c => c.Name == "NameOfProduct")); + } + + [Fact] + public void Abstract_principal_can_be_mapped_with_TPC() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + modelBuilder.Entity() + .Map(mc => { mc.MapInheritedProperties(); }) + .ToTable("Accounts"); + + modelBuilder.Entity() + .Map(mc => { mc.MapInheritedProperties(); }) + .ToTable("Contacts"); + + modelBuilder.Entity().HasRequired(o => o.BillToCustomer).WithMany(c => c.Orders). + HasForeignKey(o => o.BillToCustomerId); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + } + + #endregion + + #region Hybrid + + [Fact] + public void Can_move_one_type_to_TPT_in_TPH_hierarchy() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Woof"); + modelBuilder.Entity().ToTable("TableC"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Woof") + .HasColumns("Id", "RootData", "AData", "BData", "Discriminator"); + databaseMapping.Assert("TableC") + .HasColumns("Id", "CData") + .HasForeignKeyColumn("Id"); + databaseMapping.AssertMapping("Woof", true) + .HasNoPropertyConditions() + .HasNoColumnConditions(); + databaseMapping.AssertMapping("Woof", false) + .HasNoPropertyConditions() + .HasColumnCondition("Discriminator", "TPHRoot"); + databaseMapping.AssertMapping("Woof") + .HasNoPropertyConditions() + .HasColumnCondition("Discriminator", "TPHNodeA"); + databaseMapping.AssertMapping("Woof") + .HasNoPropertyConditions() + .HasColumnCondition("Discriminator", "TPHNodeB"); + databaseMapping.AssertMapping("TableC") + .HasNoPropertyConditions() + .HasNoColumnConditions(); + } + + [Fact] + public void Mix_TPH_and_TPT_by_mapping_one_middle_type_to_TPH() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Base"); + modelBuilder.Entity(); + modelBuilder.Entity().ToTable("L1B"); + modelBuilder.Entity().ToTable("L2"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Base") + .HasColumns("Id", "BaseData", "L1AData", "Discriminator"); + databaseMapping.AssertMapping("Base", false) + .HasColumnCondition("Discriminator", "HybridBase"); + databaseMapping.Assert("Base") + .HasColumns("Id", "BaseData", "L1AData", "Discriminator"); + databaseMapping.AssertMapping("Base") + .HasColumnCondition("Discriminator", "HybridL1A"); + + databaseMapping.Assert("L1B") + .HasColumns("Id", "L1BData"); + databaseMapping.AssertMapping("L1B") + .HasNoColumnConditions(); + + databaseMapping.Assert("L2") + .HasColumns("Id", "L2Data"); + databaseMapping.AssertMapping("L2") + .HasNoColumnConditions(); + } + + [Fact] + public void Mix_TPH_and_TPT_by_mapping_one_middle_type_to_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Base"); + modelBuilder.Entity().ToTable("A"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Base") + .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); + databaseMapping.AssertMapping("Base", false) + .HasColumnCondition("Discriminator", "HybridBase"); + + databaseMapping.Assert("A") + .HasColumns("Id", "L1AData"); + databaseMapping.AssertMapping("A") + .HasNoColumnConditions(); + + databaseMapping.Assert("Base") + .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); + databaseMapping.AssertMapping("Base") + .HasColumnCondition("Discriminator", "HybridL1B"); + + databaseMapping.Assert("Base") + .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); + databaseMapping.AssertMapping("Base") + .HasColumnCondition("Discriminator", "HybridL2"); + } + + [Fact] + public void Mix_TPH_and_TPT_by_mapping_one_middle_type_to_TPT_with_derived_type_configuration() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Base"); + modelBuilder.Entity().ToTable("A"); + modelBuilder.Entity().Map(mc => { }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Base") + .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); + databaseMapping.AssertMapping("Base", false) + .HasColumnCondition("Discriminator", "HybridBase"); + + databaseMapping.Assert("A") + .HasColumns("Id", "L1AData"); + databaseMapping.AssertMapping("A") + .HasNoColumnConditions(); + + databaseMapping.Assert("Base") + .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); + databaseMapping.AssertMapping("Base") + .HasColumnCondition("Discriminator", "HybridL1B"); + + databaseMapping.Assert("Base") + .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); + databaseMapping.AssertMapping("Base") + .HasColumnCondition("Discriminator", "HybridL2"); + } + + [Fact] + public void Mix_TPH_and_TPT_by_mapping_one_middle_type_to_TPT_using_attribute() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mapping => { mapping.Requires("luqkau").HasValue("1"); }) + .Map(mapping => { mapping.Requires("luqkau").HasValue("2"); }) + .Map(mapping => { mapping.Requires("luqkau").HasValue("3"); }) + .ToTable("A1"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Mix_TPH_and_TPC_by_mapping_one_middle_type_to_TPC() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity() + .Map( + mc => + { + mc.MapInheritedProperties(); + mc.ToTable("L1"); + }); + modelBuilder.Entity(); + modelBuilder.Entity(); + + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Mix_TPH_and_TPC_by_mapping_both_middle_types_to_TPC() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity() + .Map( + mc => + { + mc.MapInheritedProperties(); + mc.ToTable("L1A"); + }); + modelBuilder.Entity() + .Map( + mc => + { + mc.MapInheritedProperties(); + mc.ToTable("L1B"); + }); + modelBuilder.Entity(); + + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Mix_TPH_and_TPC_and_TPT_by_mapping_one_middle_type_to_TPC_and_one_middle_type_to_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity() + .Map( + mc => + { + mc.MapInheritedProperties(); + mc.ToTable("L1A"); + }); + modelBuilder.Entity() + .Map(mc => { mc.ToTable("L1B"); }); + modelBuilder.Entity(); + + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Mix_TPH_and_TPT_by_mapping_middle_type_to_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity() + .Map(mc => { mc.ToTable("L1"); }); + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("HybridBases") + .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); + databaseMapping.AssertMapping("HybridBases", true) + .HasNoColumnConditions(); + databaseMapping.AssertMapping("HybridBases", false) + .HasColumnCondition("Discriminator", "HybridBase"); + databaseMapping.Assert("L1") + .HasColumns("Id", "L1AData"); + databaseMapping.AssertMapping("L1") + .HasNoColumnConditions(); + databaseMapping.Assert("HybridBases") + .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); + databaseMapping.AssertMapping("HybridBases") + .HasColumnCondition("Discriminator", "HybridL1B"); + databaseMapping.Assert("HybridBases") + .HasColumns("Id", "BaseData", "L2Data", "L1BData", "Discriminator"); + databaseMapping.AssertMapping("HybridBases") + .HasColumnCondition("Discriminator", "HybridL2"); + } + + [Fact] + public void Can_alternate_abstract_in_TPH_hierarchy() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("ACrazies") + .HasColumns("Id", "A", "B", "C", "D", "E", "Discriminator"); + + databaseMapping.AssertMapping("ACrazies", false) + .HasColumnCondition("Discriminator", "ACrazy"); + + databaseMapping.AssertNoMapping(); + + databaseMapping.AssertMapping("ACrazies", false) + .HasColumnCondition("Discriminator", "CCrazy"); + + databaseMapping.AssertNoMapping(); + + databaseMapping.AssertMapping("ACrazies", false) + .HasColumnCondition("Discriminator", "ECrazy"); + } + + [Fact] + public void Can_alternate_abstract_in_TPH_hierarchy_with_extra_TPT_leaf() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity().ToTable("Tx"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("ACrazies") + .HasColumns("Id", "A", "B", "C", "D", "E", "Discriminator"); + + databaseMapping.Assert("Tx") + .HasColumns("Id", "X"); + + databaseMapping.AssertMapping("ACrazies", true) + .HasNoColumnConditions(); + databaseMapping.AssertMapping("ACrazies", false) + .HasColumnCondition("Discriminator", "ACrazy"); + + databaseMapping.AssertNoMapping(); + + databaseMapping.AssertMapping("ACrazies", false) + .HasColumnCondition("Discriminator", "CCrazy"); + + databaseMapping.AssertNoMapping(); + + databaseMapping.AssertMapping("ACrazies", false) + .HasColumnCondition("Discriminator", "ECrazy"); + + databaseMapping.AssertMapping("Tx", false) + .HasNoColumnConditions(); + } + + [Fact] + // Regression for 142318 + public void Can_have_TPH_alone_at_base_of_3_level_heirarchy() + { + // E1 -- TPH alone + // / | \ + // E2 E3 E4 -- all TPC + // / + // E5 -- TPT to E2 + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Entity1"); + mapping.Requires( + "aduvbkqcgjqomqpyniiftbsqzzeehyhyddqlbdtmhvmdnoktgjbylbqumovbhn") + .HasValue("true").HasColumnType("varchar(max)"); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Entity4"); + mapping.MapInheritedProperties(); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Entity2"); + mapping.MapInheritedProperties(); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Entity5"); + mapping.Requires("rdfmyypkivldry").HasValue(-10).HasColumnType( + "bigint"); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Entity3"); + mapping.MapInheritedProperties(); + }); + modelBuilder.Entity().Property(p => p.Entity1_Col1).HasColumnType("smallint"); + modelBuilder.Entity().Property(p => p.Entity1_Col2).HasColumnType("datetime2"); + modelBuilder.Entity().Property(p => p.Entity1_Col3).HasColumnType("binary").HasMaxLength(10). + IsFixedLength(); + modelBuilder.Entity().Property(p => p.Id).IsRequired().HasColumnType("char").HasMaxLength(20). + IsFixedLength(); + modelBuilder.Entity().Property(p => p.Entity2_Col1).HasColumnType("smalldatetime"); + modelBuilder.Entity().Property(p => p.Entity3_Col1).IsRequired().HasColumnType("ntext").IsUnicode(); + modelBuilder.Entity().Property(p => p.Entity3_Col2).HasColumnType("datetimeoffset"); + modelBuilder.Entity().Property(p => p.Entity4_Col1).HasColumnType("bigint"); + modelBuilder.Entity().Property(p => p.Entity4_Col2).HasColumnType("varchar(max)"); + modelBuilder.Entity().Property(p => p.Entity5_Col1).HasColumnType("bit"); + modelBuilder.Entity().Property(p => p.Entity5_Col2).HasColumnType("smalldatetime"); + modelBuilder.Entity().Property(p => p.Entity5_Col3).HasColumnType("time"); + modelBuilder.Entity().Property(p => p.Entity5_Col4).HasColumnType("decimal").HasPrecision(28, 4); + modelBuilder.Entity().Property(p => p.Entity5_Col5).HasColumnType("date"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Mixed_TPH_and_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mapping => { mapping.ToTable("A1"); }) + .Map(mapping => { mapping.ToTable("A3"); }) + .Map(mapping => { mapping.ToTable("A4"); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Mixed_TPH_and_TPC_with_TPC_has_nullable_discriminator() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mapping => { mapping.ToTable("A1"); }).Map( + mapping => + { + mapping.ToTable("A3"); + mapping.MapInheritedProperties(); + }).Map( + mapping => + { + mapping.ToTable("A4"); + mapping.MapInheritedProperties(); + }); + + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Mixed_TPH_and_TPC_and_TPT_has_nullable_discriminator() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mapping => { mapping.ToTable("A1"); }).Map( + mapping => + { + mapping.ToTable("A3"); + mapping.MapInheritedProperties(); + }).Map(mapping => { mapping.ToTable("A4"); }); + + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void TPC_under_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("T1"); + modelBuilder.Entity().ToTable("T2"); + modelBuilder.Entity().ToTable("T3"); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("T4"); + mapping.MapInheritedProperties(); + }); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + #endregion + + #region Entity Splitting + + [Fact] + public void Setting_all_Properties_does_not_trigger_entity_splitting() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.Name, + a.BaseData + }); + mc.ToTable("Tbl"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + Assert.Equal(1, databaseMapping.Database.EntityTypes.Count()); + } + + [Fact] + public void Entity_split_single_type_including_pks() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.Name + }); + mc.ToTable("NameTbl"); + }) + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.BaseData + }); + mc.ToTable("DataTbl"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("NameTbl") + .HasColumns("Id", "Name") + .DbEqual( + StoreGeneratedPattern.Identity, + t => t.Properties.Single(c => c.Name == "Id").StoreGeneratedPattern); + databaseMapping.Assert("DataTbl") + .HasColumns("Id", "BaseData") + .HasForeignKeyColumn("Id", "NameTbl") + .DbEqual(StoreGeneratedPattern.None, t => t.Properties.Single(c => c.Name == "Id").StoreGeneratedPattern); + } + + [Fact] + public void Entity_split_single_type_without_specifying_table_name() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + Assert.Throws( + () => + modelBuilder.Entity() + .Map( + mc => mc.Properties( + a => new + { + a.Id, + a.Name + })) + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.BaseData + }); + mc.ToTable("DataTbl"); + })); + } + + [Fact] + public void Entity_split_single_type_not_including_pks() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + a => new + { + a.Name + }); + mc.ToTable("NameTbl"); + }) + .Map( + mc => + { + mc.Properties( + a => new + { + a.BaseData + }); + mc.ToTable("DataTbl"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + Assert.Equal(2, databaseMapping.Database.EntityTypes.Count()); + Assert.Equal( + 2, + databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.ElementAt(0). + MappingFragments.Count); + databaseMapping.Assert("NameTbl").HasColumns("Id", "Name"); + databaseMapping.Assert("DataTbl").HasColumns("Id", "BaseData"); + } + + [Fact] + public void Empty_properties_call_in_middle_makes_extra_fragments() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.Name + }); + mc.ToTable("NameTbl"); + }) + .Map( + mc => + { + mc.Properties( + a => new + { + }); + mc.ToTable("Empty"); + }) + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.BaseData + }); + mc.ToTable("DataTbl"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + Assert.Equal(3, databaseMapping.Database.EntityTypes.Count()); + Assert.Equal( + 3, + databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.ElementAt(0). + MappingFragments.Count); + databaseMapping.Assert("NameTbl").HasColumns("Id", "Name"); + databaseMapping.Assert("DataTbl").HasColumns("Id", "BaseData"); + databaseMapping.Assert("Empty").HasColumns("Id"); + } + + [Fact] + public void Mapping_property_twice_throws() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.Name + }); + mc.ToTable("NameTbl"); + }) + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.BaseData, + a.Name + }); + mc.ToTable("DataTbl"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Ignore(); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Mapping_subtype_twice_chained_throws() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => { }); + + Assert.Throws( + () => + modelBuilder.Entity() + .Map(mc => { })); + + modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + } + + [Fact] + public void Mapping_subtype_twice_throws() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => mc.ToTable("derived")); + + modelBuilder.Entity() + .Map(mc => mc.ToTable("deriveds")); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Mapping_property_again_after_everything_mapped_throws() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.Name, + a.BaseData + }); + mc.ToTable("AssocBase"); + }) + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.Name + }); + mc.ToTable("Other"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Ignore(); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Mapping_inherited_properties_after_everything_mapped_throws() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.Name, + a.BaseData + }); + mc.ToTable("AssocBase"); + }) + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.Name + }); + mc.ToTable("Other"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Ignore(); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Mapping_all_properties_after_everything_mapped_throws() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => mc.ToTable("AssocBase")) + .Map(mc => mc.ToTable("Other")); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Ignore(); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Mapping_inherited_properties_twice_throws() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + mc => + { + mc.MapInheritedProperties(); + mc.ToTable("One"); + }) + .Map( + mc => + { + mc.MapInheritedProperties(); + mc.ToTable("Two"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Entity().Ignore(b => b.AssocRelated); + modelBuilder.Entity().Ignore(b => b.AssocRelatedId); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Empty_properties_call_at_end_makes_extra_fragments() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.Name + }); + mc.ToTable("NameTbl"); + }) + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.BaseData + }); + mc.ToTable("DataTbl"); + }) + .Map( + mc => + { + mc.Properties( + a => new + { + }); + mc.ToTable("Empty"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + Assert.Equal(3, databaseMapping.Database.EntityTypes.Count()); + Assert.Equal( + 3, + databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.ElementAt(0). + MappingFragments.Count); + databaseMapping.Assert("NameTbl").HasColumns("Id", "Name"); + databaseMapping.Assert("DataTbl").HasColumns("Id", "BaseData"); + databaseMapping.Assert("Empty").HasColumns("Id"); + } + + [Fact] + public void Properties_with_only_PK_creates_extra_fragment() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.Name + }); + mc.ToTable("NameTbl"); + }) + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id + }); + mc.ToTable("Empty"); + }) + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.BaseData + }); + mc.ToTable("DataTbl"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("NameTbl").HasColumns("Id", "Name"); + databaseMapping.Assert("DataTbl").HasColumns("Id", "BaseData"); + databaseMapping.Assert("Empty").HasColumns("Id"); + } + + [Fact] + public void Entity_split_derived_type_with_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Bases"); + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.DerivedData1 + }); + mc.ToTable("Deriveds1"); + }) + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.DerivedData2 + }); + mc.ToTable("Deriveds2"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Entity().Ignore(d => d.AssocRelated); + modelBuilder.Entity().Ignore(d => d.AssocRelatedId); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert().HasColumns("Id", "Name", "BaseData"); + databaseMapping.Assert("Deriveds1").HasColumns("Id", "DerivedData1"); + databaseMapping.Assert("Deriveds2").HasColumns("Id", "DerivedData2"); + } + + [Fact] + public void Entity_split_base_type_with_derived_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.Name + }); + mc.ToTable("NameTbl"); + }) + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.BaseData + }); + mc.ToTable("DataTbl"); + }); + modelBuilder.Entity().ToTable("Deriveds"); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Entity().Ignore(d => d.AssocRelated); + modelBuilder.Entity().Ignore(d => d.AssocRelatedId); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert().HasColumns("Id", "DerivedData1", "DerivedData2"); + databaseMapping.Assert("NameTbl").HasColumns("Id", "Name"); + databaseMapping.Assert("DataTbl").HasColumns("Id", "BaseData"); + } + + [Fact] + public void Entity_split_derived_type_with_TPC() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Bases"); + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.DerivedData1 + }); + mc.ToTable("Deriveds1"); + }) + .Map( + mc => + { + mc.MapInheritedProperties(); + mc.Properties( + a => new + { + a.Id, + a.DerivedData2 + }); + mc.ToTable("Deriveds2"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Entity().Ignore(d => d.AssocRelated); + modelBuilder.Entity().Ignore(d => d.AssocRelatedId); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert().HasColumns("Id", "Name", "BaseData"); + databaseMapping.Assert("Deriveds1").HasColumns("Id", "DerivedData1"); + databaseMapping.Assert("Deriveds2").HasColumns("Id", "Name", "BaseData", "DerivedData2"); + } + + [Fact] + public void Entity_split_base_type_with_derived_TPC() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.Name + }); + mc.ToTable("NameTbl"); + }) + .Map( + mc => + { + mc.Properties( + a => new + { + a.Id, + a.BaseData + }); + mc.ToTable("DataTbl"); + }); + modelBuilder.Entity() + .Map( + mc => + { + mc.MapInheritedProperties(); + mc.ToTable("Deriveds"); + }); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBase); + modelBuilder.Entity().Ignore(b => b.AssocRelatedBaseId); + modelBuilder.Entity().Ignore(d => d.AssocRelated); + modelBuilder.Entity().Ignore(d => d.AssocRelatedId); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert().HasColumns("Id", "Name", "BaseData", "DerivedData1", "DerivedData2"); + databaseMapping.Assert("NameTbl").HasColumns("Id", "Name"); + databaseMapping.Assert("DataTbl").HasColumns("Id", "BaseData"); + } + + [Fact] + public void Entity_split_base_type_with_derived_TPT_with_abstract_middle_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Properties( + e => new + { + e.Name, + e.Description, + }); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table2"); + mapping.Properties(e => e.Photo); + }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Table3"); }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Table4"); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Table1") + .HasColumns("Id", "Description", "Name"); + databaseMapping.Assert("Table2") + .HasColumns("Id", "Photo") + .HasForeignKeyColumn("Id", "Table1"); + databaseMapping.Assert("Table3") + .HasColumns("Id", "Details") + .HasForeignKeyColumn("Id", "Table1"); + databaseMapping.Assert("Table4") + .HasColumns("Id", "Color") + .HasForeignKeyColumn("Id", "Table3"); + } + + [Fact] + public void Entity_split_base_type_with_derived_TPH_with_abstract_base_with_duplicate_property_throws() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Requires("discriminator").HasValue("Entity1_1"); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Properties(e => e.Property4); + mapping.Requires("discriminator").HasValue("Entity1_2"); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table2"); + mapping.Properties(e => e.Property6); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table3"); + mapping.Properties(e => e.Property6); + }); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Entity_split_base_type_with_derived_TPH_with_abstract_base() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Requires("discriminator").HasValue("Entity1_1"); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Properties(e => e.Property4); + mapping.Requires("discriminator").HasValue("Entity1_2"); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table2"); + mapping.Properties(e => e.Property5); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table3"); + mapping.Properties(e => e.Property6); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Table1") + .HasColumns( + "Id", "Photo", "Description", "Name", "Property1", "Property2", "Property3", "Property4", + "discriminator"); + databaseMapping.Assert("Table1") + .HasColumns( + "Id", "Photo", "Description", "Name", "Property1", "Property2", "Property3", "Property4", + "discriminator"); + databaseMapping.Assert("Table2") + .HasColumns("Id", "Property5"); + databaseMapping.Assert("Table3") + .HasColumns("Id", "Property6"); + } + + [Fact] + public void Entity_split_base_type_with_a_complex_type_in_TPH() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Requires("d").HasValue("EntityC1"); + mapping.Properties(e => e.Property2); + mapping.Properties(e => e.ComplexProperty1.P2); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table2"); + mapping.Properties(e => e.ComplexProperty1.P1); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Requires("d").HasValue("EntityC1_1"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Table1") + .HasColumns("Id", "ComplexProperty1_P2", "Property2", "Property3", "Property4", "d"); + + databaseMapping.Assert("Table2") + .HasColumns("Id", "ComplexProperty1_P1"); + + databaseMapping.AssertMapping("Table1", false) + .HasColumnCondition("d", "EntityC1"); + + databaseMapping.AssertMapping("Table1", true) + .HasNoColumnConditions(); + + databaseMapping.Assert("Table1") + .HasColumns("Id", "ComplexProperty1_P2", "Property2", "Property3", "Property4", "d"); + + databaseMapping.AssertMapping("Table1", false) + .HasColumnCondition("d", "EntityC1_1"); + } + + [Fact] + public void Entity_split_middle_type_in_TPH() + { + var builder = new AdventureWorksModelBuilder(); + + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Requires("d").HasValue("EntityB1"); + }); + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Properties(e => e.Property1); + mapping.Requires("d").HasValue("EntityB1_1"); + }); + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table2"); + mapping.Properties( + e => new + { + e.Property2, + e.Property3 + }); + }); + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Requires("d").HasValue("EntityB1_1_1"); + }); + + builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo, true); + } + + [Fact] + public void Entity_split_middle_type_in_TPH2() + { + var builder = new AdventureWorksModelBuilder(); + + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Requires("d").HasValue("EntityB1"); + }); + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Properties(e => e.Property1); + mapping.Requires("d").HasValue("EntityB1_1"); + }); + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table2"); + mapping.Properties( + e => new + { + e.Property2, + e.Property3 + }); + }); + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Requires("d").HasValue("EntityB1_1_1"); + }); + + var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Entity_splitting_maintains_configured_composite_key_ordering() + { + var builder = new AdventureWorksModelBuilder(); + + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Properties(e => e.Property1); + }); + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table2"); + mapping.Properties(e => e.Property2); + }); + builder.Entity().HasKey( + e => new + { + e.Key2, + e.Key1, + }); + + var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Table1") + .HasColumns("Key1", "Key2", "Property1"); + databaseMapping.Assert("Table2") + .HasColumns("Key1", "Key2", "Property2") + .HasForeignKey(new[] { "Key1", "Key2" }, "Table1"); + } + + [Fact] + public void Entity_splitting_derived_table_creates_FK_to_first_table() + { + var builder = new AdventureWorksModelBuilder(); + + builder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table2"); + mapping.Properties( + e => new + { + e.Property1, + e.Property2 + }); + mapping.Properties(e => e.Property3); + }); + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table3"); + mapping.Properties(e => e.Property4); + }); + + var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Table1") + .HasNoForeignKeyColumns(); + + databaseMapping.Assert("Table2") + .HasNoForeignKeyColumns(); + + databaseMapping.Assert("Table3") + .HasForeignKeyColumn("Id", "Table2"); + } + + [Fact] + public void Entity_splitting_derived_TPC_creates_FK_to_first_table() + { + var builder = new AdventureWorksModelBuilder(); + + builder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table2"); + mapping.Properties( + e => new + { + e.Property1, + e.Property3 + }); + }); + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table3"); + mapping.Properties( + e => new + { + e.Property2, + e.Property4 + }); + }); + + var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Table1") + .HasNoForeignKeyColumns(); + + databaseMapping.Assert("Table2") + .HasNoForeignKeyColumns(); + + databaseMapping.Assert("Table3") + .HasForeignKeyColumn("Id", "Table2"); + } + + [Fact] + public void Entity_splitting_all_inherited_props_in_derived_TPC_creates_FK_to_first_table() + { + var builder = new AdventureWorksModelBuilder(); + + builder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table2"); + mapping.Properties( + e => new + { + e.Property3, + e.Property4 + }); + }); + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table3"); + mapping.Properties( + e => new + { + e.Property1, + e.Property2 + }); + }); + + var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Table1") + .HasNoForeignKeyColumns(); + + databaseMapping.Assert("Table2") + .HasNoForeignKeyColumns(); + + databaseMapping.Assert("Table3") + .HasForeignKeyColumn("Id", "Table2"); + } + + [Fact] + public void Entity_splitting_derived_TPT_creates_FK_to_first_table() + { + var builder = new AdventureWorksModelBuilder(); + + builder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table2"); + mapping.Properties( + e => new + { + e.Property3 + }); + }); + builder.Entity().Map( + mapping => + { + mapping.ToTable("Table3"); + mapping.Properties( + e => new + { + e.Property4 + }); + }); + + var databaseMapping = builder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert("Table1") + .HasNoForeignKeyColumns(); + + databaseMapping.Assert("Table2") + .HasForeignKeyColumn("Id", "Table1") + .DbEqual(1, t => t.ForeignKeyBuilders.Count()); + + databaseMapping.Assert("Table3") + .HasForeignKeyColumn("Id", "Table2") + .DbEqual(1, t => t.ForeignKeyBuilders.Count()); + } + + [Fact] + public void Entity_splitting_names_store_entity_types_and_sets_properly() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + a => new + { + a.IntProp + }); + mc.ToTable("Tbl"); + }) + .Map( + mc => + { + mc.Properties( + a => new + { + a.StringProp + }); + mc.ToTable("Tbl2"); + }).Map( + mc => + { + mc.Properties( + a => new + { + a.ByteArrayProp, + a.DateTimeProp, + a.DecimalProp + }); + mc.ToTable("Tbl3"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + var mws = databaseMapping.ToMetadataWorkspace(); + + var itemCollection = mws.GetItemCollection(DataSpace.SSpace) as StoreItemCollection; + + Assert.NotNull(itemCollection.GetItem("CodeFirstDatabaseSchema.TypeClass")); + Assert.NotNull(itemCollection.GetItem("CodeFirstDatabaseSchema.TypeClass1")); + Assert.NotNull(itemCollection.GetItem("CodeFirstDatabaseSchema.TypeClass2")); + } + + #endregion + + #region Table Splitting + + [Fact] + public void One_to_one_relationship_can_share_table() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().Ignore(x => x.TSItemDetailDiffKey); + modelBuilder.Entity().Ignore(x => x.TSItemDetailOverlappingProperty); + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().HasRequired(i => i.TSItemDetail).WithRequiredPrincipal(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Items").DbEqual(3, t => t.Properties.Count); + databaseMapping.Assert("Items").DbEqual(0, t => t.ForeignKeyBuilders.Count()); + databaseMapping.Assert("Items").HasColumns("Id", "Name", "Detail"); + } + + [Fact] + // Regression test for Dev 11 bug 86852 + public void Table_split_with_conflicting_key_column_order_throws() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().Ignore(x => x.TSItemDetailDiffKey); + modelBuilder.Entity().Ignore(x => x.TSItemDetailOverlappingProperty); + modelBuilder.Entity().HasKey( + c => new + { + c.Id, + c.Name + }); + modelBuilder.Entity().Property(i => i.Id).HasColumnOrder(1); + modelBuilder.Entity().Property(i => i.Name).HasColumnOrder(2); + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().HasKey( + c => new + { + c.Id, + c.Detail + }); + modelBuilder.Entity().Property(i => i.Id).HasColumnOrder(2); + modelBuilder.Entity().Property(i => i.Detail).HasColumnOrder(1); + modelBuilder.Entity().HasRequired(i => i.TSItemDetail).WithRequiredPrincipal(); + + Assert.Throws( + () => + modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Table_split_with_conflicting_primary_key_columnType_throws() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().Ignore(x => x.TSItemDetailDiffKey); + modelBuilder.Entity().Ignore(x => x.TSItemDetailOverlappingProperty); + modelBuilder.Entity().Property(i => i.Id).HasColumnType("nvarchar(max)"); + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().Property(i => i.Id).HasColumnType("ntext"); + modelBuilder.Entity().HasRequired(i => i.TSItemDetail).WithRequiredPrincipal(); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Table_split_with_different_primary_key_name_uses_principal_name() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().Ignore(x => x.TSItemDetail); + modelBuilder.Entity().Ignore(x => x.TSItemDetailOverlappingProperty); + modelBuilder.Entity().HasKey(x => x.DiffId); + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().HasRequired(i => i.TSItemDetailDiffKey).WithRequiredPrincipal(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Items").DbEqual(3, t => t.Properties.Count); + databaseMapping.Assert("Items").DbEqual(0, t => t.ForeignKeyBuilders.Count()); + databaseMapping.Assert("Items").HasColumns("Id", "Name", "Detail"); + } + + [Fact] + public void Table_split_with_different_primary_key_property_name_that_is_mapped_to_same_column_name() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().Ignore(x => x.TSItemDetail); + modelBuilder.Entity().Ignore(x => x.TSItemDetailOverlappingProperty); + modelBuilder.Entity().HasKey(x => x.DiffId); + modelBuilder.Entity().Property(x => x.DiffId).HasColumnName("Id"); + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().HasRequired(i => i.TSItemDetailDiffKey).WithRequiredPrincipal(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Items").DbEqual(3, t => t.Properties.Count); + databaseMapping.Assert("Items").DbEqual(0, t => t.ForeignKeyBuilders.Count()); + databaseMapping.Assert("Items").HasColumns("Id", "Name", "Detail"); + } + + [Fact] + public void Table_split_with_different_primary_key_property_name_that_is_mapped_to_new_column_name() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().Ignore(x => x.TSItemDetail); + modelBuilder.Entity().Ignore(x => x.TSItemDetailOverlappingProperty); + modelBuilder.Entity().HasKey(x => x.DiffId); + modelBuilder.Entity().Property(x => x.DiffId).HasColumnName("Foo"); + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().HasRequired(i => i.TSItemDetailDiffKey).WithRequiredPrincipal(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Items").DbEqual(3, t => t.Properties.Count); + databaseMapping.Assert("Items").DbEqual(0, t => t.ForeignKeyBuilders.Count()); + databaseMapping.Assert("Items").HasColumns("Foo", "Name", "Detail"); + } + + [Fact] + public void Table_split_with_overlapping_property_name() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().Ignore(x => x.TSItemDetail); + modelBuilder.Entity().Ignore(x => x.TSItemDetailDiffKey); + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().HasRequired(i => i.TSItemDetailOverlappingProperty).WithRequiredPrincipal(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert("Items").HasColumns("Id", "Name", "Name1"); + } + + [Fact] + public void Table_split_with_overlapping_property_name_that_has_been_renamed() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().Ignore(x => x.TSItemDetail); + modelBuilder.Entity().Ignore(x => x.TSItemDetailDiffKey); + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().Property(x => x.Name).HasColumnName("OtherName"); + modelBuilder.Entity().HasRequired(i => i.TSItemDetailOverlappingProperty).WithRequiredPrincipal(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Items").DbEqual(3, t => t.Properties.Count); + databaseMapping.Assert("Items").DbEqual(0, t => t.ForeignKeyBuilders.Count()); + databaseMapping.Assert("Items").HasColumns("Id", "Name", "OtherName"); + } + + [Fact] + public void Table_split_with_IA_one_to_one_relationship_throws() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().ToTable("Items"); + modelBuilder.Entity().HasRequired(i => i.Detail).WithRequiredPrincipal(); + + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("EntityMappingConfiguration_InvalidTableSharing", "TSIAItemDetail", "TSIAItem", "Items"); + } + + [Fact] + public void Table_split_base_on_TPH() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map( + mc => + { + mc.ToTable("TS"); + mc.Requires("disc").HasValue("TSBase"); + }); + modelBuilder.Entity().Map( + mc => + { + mc.ToTable("TS"); + mc.Requires("disc").HasValue("TSDerived"); + }); + modelBuilder.Entity().Ignore(x => x.Detail); + modelBuilder.Entity().Map(mc => { mc.ToTable("TS"); }); + modelBuilder.Entity().HasRequired(i => i.BaseDetail).WithRequiredPrincipal(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + databaseMapping.Assert("TS").HasColumns("Id", "BaseData", "DerivedData", "disc", "BaseDetail"); + databaseMapping.Assert("TS").HasColumns("Id", "BaseData", "DerivedData", "disc", "BaseDetail"); + databaseMapping.Assert("TS").HasColumns("Id", "BaseData", "DerivedData", "disc", "BaseDetail"); + } + + [Fact] + public void Table_split_base_on_default_TPH() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity().Ignore(x => x.Detail); + modelBuilder.Entity().Map(mc => { mc.ToTable("TSBase"); }); + modelBuilder.Entity().HasRequired(i => i.BaseDetail).WithRequiredPrincipal(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + databaseMapping.Assert("TSBase").HasColumns( + "Id", "BaseData", "DerivedData", "Discriminator", + "BaseDetail"); + databaseMapping.Assert("TSBase").HasColumns( + "Id", "BaseData", "DerivedData", "Discriminator", + "BaseDetail"); + databaseMapping.Assert("TSBase").HasColumns( + "Id", "BaseData", "DerivedData", "Discriminator", + "BaseDetail"); + } + + [Fact] + public void Table_split_base_on_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mc => { mc.ToTable("A"); }); + modelBuilder.Entity().Map(mc => { mc.ToTable("A"); }); + modelBuilder.Entity().Map(mc => { mc.ToTable("B"); }); + modelBuilder.Entity().Ignore(x => x.Detail); + modelBuilder.Entity().HasRequired(i => i.BaseDetail).WithRequiredPrincipal(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + databaseMapping.Assert("A").HasColumns("Id", "BaseData", "BaseDetail"); + databaseMapping.Assert("B").HasColumns("Id", "DerivedData"); + databaseMapping.Assert("A").HasColumns("Id", "BaseData", "BaseDetail"); + } + + [Fact] + public void Table_split_base_on_TPT_2() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Vehicle"); }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Car"); }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Vehicle"); }); + modelBuilder.Entity().HasRequired(e => e.Repro140107_Model).WithRequiredPrincipal( + e => e.Repro140107_Vehicle); + modelBuilder.Entity().HasRequired(e => e.Repro140107_Vehicle).WithRequiredDependent( + e => e.Repro140107_Model); + modelBuilder.Entity().Property(p => p.Repro140107_VehicleId).HasColumnType("int"); + modelBuilder.Entity().Property(p => p.Name).HasColumnType("smallint"); + modelBuilder.Entity().Property(p => p.Type).HasColumnType("bigint"); + modelBuilder.Entity().Property(p => p.Repro140107_ModelId).HasColumnType("int"); + modelBuilder.Entity().Property(p => p.Description).HasColumnType("bit"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + } + + [Fact] + // Doesn't work due to an EF bug + public void Table_split_base_on_TPC() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mc => { mc.ToTable("A"); }); + modelBuilder.Entity().Map(mc => { mc.ToTable("A"); }); + modelBuilder.Entity().Map( + mc => + { + mc.MapInheritedProperties(); + mc.ToTable("B"); + }); + modelBuilder.Entity().Ignore(x => x.Detail); + + modelBuilder.Entity().HasRequired(i => i.BaseDetail).WithRequiredPrincipal(); + + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo, true)); + } + + [Fact] + // Doesn't work due to an EF bug + public void Table_split_base_on_TPC_2() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Vehicle"); }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Car"); + mapping.MapInheritedProperties(); + }); + modelBuilder.Entity().ToTable("Vehicle"); + modelBuilder.Entity().HasRequired(e => e.Model).WithRequiredPrincipal( + e => e.Repro140106_Vehicle); + modelBuilder.Entity().HasRequired(e => e.Repro140106_Vehicle).WithRequiredDependent( + e => e.Model); + modelBuilder.Entity().Property(p => p.Repro140106_VehicleId).IsRequired().HasColumnType + ("nvarchar").HasMaxLength(40).IsUnicode().IsVariableLength(); + modelBuilder.Entity().Property(p => p.Name).HasColumnType("nvarchar(max)").IsUnicode(); + modelBuilder.Entity().Property(p => p.Type).IsRequired().HasColumnType("text"); + modelBuilder.Entity().Property(p => p.Repro140106_ModelId).IsRequired().HasColumnType( + "nvarchar").HasMaxLength(40).IsUnicode().IsVariableLength(); + modelBuilder.Entity().Property(p => p.Description).HasColumnType("numeric").HasPrecision( + 15, 5); + + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo, true)); + } + + [Fact] + // Doesn't work due to an EF bug + public void Table_split_base_on_TPC_has_no_FK_to_base_and_table_split_entity_props_not_inherited() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Vehicle"); }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Car"); + mapping.MapInheritedProperties(); + }); + modelBuilder.Entity().ToTable("Vehicle"); + modelBuilder.Entity().HasRequired(e => e.TPCModel).WithRequiredPrincipal(e => e.TPCVehicle); + modelBuilder.Entity().HasRequired(e => e.TPCVehicle).WithRequiredDependent(e => e.TPCModel); + modelBuilder.Entity().Property(p => p.TPCVehicleId).IsRequired().HasColumnType("nvarchar"). + HasMaxLength(40).IsUnicode().IsVariableLength(); + modelBuilder.Entity().Property(p => p.Name).HasColumnType("nvarchar(max)").IsUnicode(); + modelBuilder.Entity().Property(p => p.Type).IsRequired().HasColumnType("text"); + modelBuilder.Entity().Property(p => p.TPCModelId).IsRequired().HasColumnType("nvarchar"). + HasMaxLength(40).IsUnicode().IsVariableLength(); + modelBuilder.Entity().Property(p => p.Description).HasColumnType("numeric").HasPrecision(15, 5); + + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo, true)); + } + + #endregion + + #region Complex Types + + [Fact] + public void ComplexType_Properties_Can_Be_Entity_Split() + { + var modelBuilder = new AdventureWorksModelBuilder(); + modelBuilder.Ignore(); + modelBuilder.ComplexType().Ignore(c => c.Region); + + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + p => new + { + p.Id, + p.HomeAddress + }); + mc.ToTable("Home"); + }) + .Map( + mc => + { + mc.Properties( + p => new + { + p.Id, + p.WorkAddress + }); + mc.ToTable("Work"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Home").HasColumns("Id", "HomeAddress_Street", "HomeAddress_City"); + databaseMapping.Assert("Work").HasColumns("Id", "WorkAddress_Street", "WorkAddress_City"); + } + + [Fact] + public void Scalars_Inside_ComplexType_Properties_Can_Be_Entity_Split() + { + var modelBuilder = new AdventureWorksModelBuilder(); + modelBuilder.Ignore(); + modelBuilder.Entity().Ignore(b => b.WorkAddress); + modelBuilder.ComplexType().Ignore(c => c.Region); + + modelBuilder.Entity() + .Map( + mc => + { + mc.Properties( + p => new + { + p.Id, + p.HomeAddress.Street + }); + mc.ToTable("HomeStreet"); + }) + .Map( + mc => + { + mc.Properties( + p => new + { + p.Id, + p.HomeAddress.City + }); + mc.ToTable("HomeCity"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("HomeStreet").HasColumns("Id", "HomeAddress_Street"); + databaseMapping.Assert("HomeCity").HasColumns("Id", "HomeAddress_City"); + } + + #endregion + + #region Abstract In Middle + + [Fact] + public void Abstract_in_middle_of_hierarchy_with_TPH() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("AbsInMiddles").HasColumns( + "Id", "Data", "L1Data", "L2Data", + "Discriminator"); + databaseMapping.AssertNoMapping(); + databaseMapping.Assert("AbsInMiddles").HasColumns( + "Id", "Data", "L1Data", "L2Data", + "Discriminator"); + } + + [Fact] + public void Abstract_in_middle_of_hierarchy_with_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Base"); + modelBuilder.Entity().ToTable("L1"); + modelBuilder.Entity().ToTable("L2"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.Assert("Base").HasColumns("Id", "Data"); + databaseMapping.Assert("L1").HasColumns("Id", "L1Data"); + databaseMapping.Assert("L2").HasColumns("Id", "L2Data"); + } + + [Fact] + public void Abstract_in_middle_of_hierarchy_with_TPC() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Base"); + modelBuilder.Entity( + + ).Map( + mc => + { + mc.ToTable("L2"); + mc.MapInheritedProperties(); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + Assert.Equal(2, databaseMapping.Database.EntityTypes.Count()); + databaseMapping.Assert("Base").HasColumns("Id", "Data"); + databaseMapping.Assert("L2").HasColumns("Id", "Data", "L1Data", "L2Data"); + } + + [Fact] + public void Entity_split_abstract_middle_in_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table2"); + mapping.Properties( + e => new + { + e.Property2, + }); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table3"); + mapping.Properties( + e => new + { + e.Property2_1, + }); + }); + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Table4"); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Entity_split_abstract_middle_in_TPH() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mapping => { mapping.ToTable("Table1"); }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Properties( + e => new + { + e.Id, + e.Property1, + e.Property1_1, + e.Property2, + }); + }); + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table2"); + mapping.Properties( + e => new + { + e.Id, + e.Property2_1, + }); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + #endregion + + #region Abstract At Base + + [Fact] + public void Can_specify_not_null_condition_on_derived_with_abstract_base_in_TPH() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().Map(mc => { mc.Requires(e => e.L1Data).HasValue(); }); + modelBuilder.Entity().Property(p => p.L1Data).IsRequired(); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.AssertMapping("AbsAtBases", true).HasNoColumnConditions(); + databaseMapping.AssertMapping("AbsAtBases").HasNullabilityColumnCondition("L1Data", false); + } + + [Fact] + public void Can_specify_not_null_condition_on_derived_and_null_value_on_base_with_abstract_base_in_TPH_throws() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map(mc => { mc.Requires("L1Data").HasValue(null); }); + modelBuilder.Entity().Map(mc => { mc.Requires(e => e.L1Data).HasValue(); }); + modelBuilder.Entity().Property(p => p.L1Data).IsRequired(); + modelBuilder.Ignore(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + databaseMapping.AssertMapping("AbsAtBases").HasNoColumnConditions(); + databaseMapping.AssertMapping("AbsAtBases").HasNullabilityColumnCondition("L1Data", false); + } + + [Fact] + public void Entity_split_abstract_base_in_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map( + mc => + { + mc.ToTable("Base1"); + mc.Properties( + b => new + { + b.Id, + b.Prop1 + }); + }).Map( + mc => + { + mc.ToTable("Base2"); + mc.Properties( + b => new + { + b.Id, + b.Prop2 + }); + }); + + modelBuilder.Entity().Map(mc => { mc.ToTable("Derived"); }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Entity_split_abstract_base_in_TPH() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map( + mc => + { + mc.ToTable("Base1"); + mc.Properties( + b => new + { + b.Id, + b.Prop1 + }); + }).Map( + mc => + { + mc.ToTable("Base2"); + mc.Properties( + b => new + { + b.Id, + b.Prop2 + }); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + #endregion + } +} diff --git a/test/EntityFramework/FunctionalTests/CodeFirst/ComplexTypeScenarioTests.cs b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/ComplexTypeScenarioTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/CodeFirst/ComplexTypeScenarioTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/CodeFirst/ComplexTypeScenarioTests.cs index 24fedc25..07f44061 100644 --- a/test/EntityFramework/FunctionalTests/CodeFirst/ComplexTypeScenarioTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/ComplexTypeScenarioTests.cs @@ -1,653 +1,653 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests -{ - using System; - using System.Collections.Generic; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; - using System.Data.Entity; - using System.Data.Entity.Core; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.ModelConfiguration; - using System.Data.Entity.ModelConfiguration.Edm; - using System.Data.Entity.Utilities; - using System.Linq; - using FunctionalTests.Model; - using Xunit; - - public sealed class ComplexTypeScenarioTests : TestBase - { - [Fact] - public void Can_configure_complex_column_name_after_entity_splitting() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.ComplexType(); - - modelBuilder.Entity() - .Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Properties(e => e.Property1); - }); - - modelBuilder.Entity() - .Map( - mapping => - { - mapping.ToTable("Table2"); - mapping.Properties(e => e.Property2); - mapping.Properties(e => e.ComplexProp); - }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert("Table2").HasColumn("ColumnFor_Details"); - } - - [Fact] - public void Complex_types_in_tpt_should_have_configuration_applied() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().ToTable("People"); - modelBuilder.Entity().ToTable("Employees"); - modelBuilder.ComplexType().Property(a => a.Street).HasColumnName("test"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(c => c.Street).DbEqual("test", c => c.Name); - } - - [Fact] - public void Complex_types_discovered_by_convention_should_have_configuration_applied() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(c => c.Property).DbEqual("Foo", c => c.Name).DbEqual( - false, - c => - c.Nullable); - } - - [Fact] - public void Complex_property_configuration_should_configure_complex_types() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Property(e => e.ChildComplex.Property).HasColumnName( - "Foo1"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(2, databaseMapping.Model.ComplexTypes.Count()); - - databaseMapping.Assert("EntityWithNestedComplexTypes").HasColumns( - "Id", "Bar", - "Foo", "Foo1"); - } - - [Fact] - public void Nested_complex_types_are_discovered() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Ignore(e => e.ChildComplex); - modelBuilder.ComplexType(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(2, databaseMapping.Model.ComplexTypes.Count()); - - databaseMapping.Assert("EntityWithNestedComplexTypes").HasColumns( - "Id", "Bar", - "Foo"); - } - - [Fact] - public void Complex_type_and_nested_complex_type_can_have_column_names_configured() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .Property(e => e.ChildComplex.Property) - .HasColumnName("Foo1"); - - modelBuilder.Entity() - .Property(e => e.Complex.Nested.Property) - .HasColumnName("Foo2"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(2, databaseMapping.Model.ComplexTypes.Count()); - databaseMapping.Assert("EntityWithNestedComplexTypes").HasColumns( - "Id", "Bar", - "Foo2", - "Foo1"); - } - - [Fact] - public void Complex_type_can_have_column_names_configured_whithout_altering_order() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .Property(e => e.ChildComplex.Property) - .HasColumnName("Foo1"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(2, databaseMapping.Model.ComplexTypes.Count()); - databaseMapping.Assert("EntityWithNestedComplexTypes").HasColumns( - "Id", "Bar", - "Foo", "Foo1"); - } - - [Fact] - public void Complex_type_and_nested_complex_type_column_names_configured_using_complex_type_configuration_throws() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.ComplexType() - .Property(c => c.Property) - .HasColumnName("Foo"); - - Assert.Throws(() => BuildMapping(modelBuilder)); - } - - [Fact] - public void Complex_type_column_names_use_property_path() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.ComplexType().Ignore(c => c.NestedComplexProperty); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping - .Assert() - .HasColumns("Id", "ComplexPropertyA_Property", "ComplexPropertyB_Property"); - } - - [Fact] - public void Self_referencing_complex_type_throws_exception() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.ComplexType(); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("CircularComplexTypeHierarchy"); - } - - [Fact] - public void Build_model_for_type_with_a_non_public_complex_type_property() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .HasKey(th => th.TransactionID); - modelBuilder.ComplexType(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert(th => th.RowDetails); - } - - [Fact] - public void Build_model_for_a_single_type_with_a_complex_type() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.ComplexType(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - Assert.Equal(1, databaseMapping.Model.ComplexTypes.Count()); - } - - [Fact] - public void Build_model_containing_a_complex_type_with_annotations() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate( - ProviderRegistry.Sql2008_ProviderInfo, - typeof(RowDetails)); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - Assert.Equal(1, databaseMapping.Model.ComplexTypes.Count()); - } - - [Fact] - public void Build_model_containing_a_complex_type_by_convention() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate( - ProviderRegistry.Sql2008_ProviderInfo, - typeof(UnitMeasure)); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - Assert.Equal(1, databaseMapping.Model.ComplexTypes.Count()); - } - - [Fact] - public void Build_model_containing_a_complex_type_with_configuration() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder - .ComplexType() - .Property(rd => rd.rowguid) - .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed) - .HasColumnName("ROW_GUID"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_containing_a_complex_type_with_instance_configuration() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Property(pd => pd.RowDetails.rowguid) - .HasColumnName("ROW_GUID"); - modelBuilder.ComplexType() - .Property(rd => rd.rowguid) - .HasColumnName("row_guid"); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_containing_a_complex_type_with_instance_cspace_configuration() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Property(pd => pd.RowDetails.rowguid) - .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed); - modelBuilder.ComplexType(); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_containing_a_complex_type_with_has_max_length_configuration() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.ComplexType(); - modelBuilder.Entity() - .Property(p => p.LargePhoto.Photo) - .HasColumnType("binary") - .HasMaxLength(42); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert(l => l.Photo) - .FacetEqual(42, f => f.MaxLength) - .DbEqual(42, f => f.MaxLength); - } - - [Fact] - public void Build_model_containing_a_complex_type_with_instance_cspace_configuration_override() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Property(pd => pd.RowDetails.rowguid) - .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed); - modelBuilder.ComplexType() - .Property(rd => rd.rowguid) - .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void ComplexType_nullable_is_not_propagated_when_using_TPH() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.ComplexType
() - .Property(a => a.Line1) - .IsRequired(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - // Not propagated - - Assert.Equal( - false, - databaseMapping.Database.EntityTypes.ElementAt(0).Properties.Single(c => c.Name == "HomeAddress_Line1") - .Nullable); - EdmModel tempQualifier1 = databaseMapping.Database; - DebugCheck.NotNull(tempQualifier1); - Assert.Equal( - true, - tempQualifier1.EntityTypes.ElementAt(0).Properties.Single(c => c.Name == "WorkAddress_Line1") - .Nullable); - - EdmModel tempQualifier2 = databaseMapping.Database; - DebugCheck.NotNull(tempQualifier2); - Assert.Equal( - true, - tempQualifier2.EntityTypes.ElementAt(0).Properties.Single(c => c.Name == "HomeAddress_Line2") - .Nullable); - EdmModel tempQualifier3 = databaseMapping.Database; - DebugCheck.NotNull(tempQualifier3); - Assert.Equal( - true, - tempQualifier3.EntityTypes.ElementAt(0).Properties.Single(c => c.Name == "WorkAddress_Line2") - .Nullable); - } - - [Fact] - public void ComplexType_nullable_is_propagated_when_using_TPT() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().ToTable("Employees"); - modelBuilder.Entity().ToTable("OffSiteEmployees"); - modelBuilder.ComplexType
() - .Property(a => a.Line1) - .IsRequired(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - Assert.Equal( - false, - databaseMapping.Database.EntityTypes.ElementAt(0).Properties.Single(c => c.Name == "HomeAddress_Line1") - .Nullable); - EdmModel tempQualifier1 = databaseMapping.Database; - DebugCheck.NotNull(tempQualifier1); - Assert.Equal( - false, - tempQualifier1.EntityTypes.ElementAt(1).Properties.Single(c => c.Name == "WorkAddress_Line1") - .Nullable); - - EdmModel tempQualifier2 = databaseMapping.Database; - DebugCheck.NotNull(tempQualifier2); - Assert.Equal( - true, - tempQualifier2.EntityTypes.ElementAt(0).Properties.Single(c => c.Name == "HomeAddress_Line2") - .Nullable); - EdmModel tempQualifier3 = databaseMapping.Database; - DebugCheck.NotNull(tempQualifier3); - Assert.Equal( - true, - tempQualifier3.EntityTypes.ElementAt(1).Properties.Single(c => c.Name == "WorkAddress_Line2") - .Nullable); - } - - [Fact] - public void Model_with_multiple_complex_types_and_entities_finds_complex_types_by_convention() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasKey(b => b.Number); - - modelBuilder.Entity() - .HasKey(b => b.EmployeeNumber); - - modelBuilder.Entity() - .HasKey(o => o.Number); - - modelBuilder.Entity() - .HasKey( - p => new - { - p.EmployeeNo, - p.PhotoId - }); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - Assert.Equal(2, databaseMapping.Model.ComplexTypes.Count()); - } - - [Fact] - public void Annotations_on_complex_type_classes_are_not_present_on_properties() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - // Not propagated - var annotations = databaseMapping.Model - .EntityTypes.Single(x => x.Name == "CTEmployee") - .Properties.Single(p => p.Name == "HomeAddress") - .Annotations; - Assert.Equal( - 0, - ((ICollection)annotations.SingleOrDefault(a => a.Name == "ClrAttributes").Value). - Count); - } - - [Fact] - public void Property_max_length_convention_applied_to_complex_types() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Ignore(); - modelBuilder.ComplexType
(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - databaseMapping.Assert
(a => a.Line1).FacetEqual(true, f => f.IsMaxLength); - } - } - - #region Fixtures - - [ComplexType] - public class Address - { - public string Line1 { get; set; } - public string Line2 { get; set; } - } - - public class CTEmployee - { - public int CTEmployeeId { get; set; } - public Address HomeAddress { get; set; } - } - - public class OffSiteEmployee : CTEmployee - { - public Address WorkAddress { get; set; } - } - - public class Building - { - public int Id { get; set; } - public Address Address { get; set; } - } - - public class LoCTBuilding - { - public int Number { get; set; } - public string Name { get; set; } - public LoCTAddress Address { get; set; } - - public ICollection LoCTOffices { get; set; } - } - - public class LoCTOffice - { - public int BuildingNumber { get; set; } - public string Number { get; set; } - - public LoCTBuilding LoCTBuilding { get; set; } - public ICollection Occupants { get; set; } - } - - public class LoCTEmployee - { - public int EmployeeNumber { get; set; } - public LoCTName Name { get; set; } - public LoCTAddress HomeAddress { get; set; } - - public LoCTOffice Office { get; set; } - public ICollection Photos { get; set; } - } - - public class LoCTEmployeePhoto - { - public int PhotoId { get; set; } - public int EmployeeNo { get; set; } - - public byte[] Photo { get; set; } - } - - public class LoCTName - { - public string FirstName { get; set; } - public string LastName { get; set; } - public string Title { get; set; } - } - - public class LoCTAddress - { - public string Line1 { get; set; } - public string Line2 { get; set; } - public string City { get; set; } - public string State { get; set; } - public string Zip { get; set; } - } - - public class ComplexTypeEntity - { - public int Id { get; set; } - public ComplexType ComplexPropertyA { get; set; } - public ComplexType ComplexPropertyB { get; set; } - } - - public class ComplexType - { - public string Property { get; set; } - public ComplexType NestedComplexProperty { get; set; } - } - - public class ParentComplexType - { - [Column("Bar")] - [Required] - public string Property { get; set; } - - public ChildComplexType Nested { get; set; } - } - - public class ChildComplexType - { - [Column("Foo")] - [Required] - public string Property { get; set; } - } - - public class EntityWithByConventionComplexType - { - public int Id { get; set; } - public ChildComplexType Complex { get; set; } - } - - public class EntityWithNestedComplexType - { - public int Id { get; set; } - public ParentComplexType Complex { get; set; } - public ChildComplexType ChildComplex { get; set; } - } - - public class Person_166889 - { - [Key] - public int PersonId { get; set; } - - public string Name { get; set; } - } - - public class Employee_166889 : Person_166889 - { - public string EmployeeNo { get; set; } - public Address_166889 Address { get; set; } - } - - public class Address_166889 - { - public string Street { get; set; } - public string City { get; set; } - public string ZipCode { get; set; } - } - - public class ComplexTypeWithColumnRename - { - [Column("ColumnFor_Details")] - public string Details { get; set; } - } - - public class EntityWithColumnsRename - { - public int Id { get; set; } - - [Column("ColumnFor_Property1")] - public byte[] Property1 { get; set; } - - [Column("ColumnFor_Property2")] - public string Property2 { get; set; } - - public ComplexTypeWithColumnRename ComplexProp { get; set; } - } - - #endregion -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests +{ + using System; + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + using System.ComponentModel.DataAnnotations.Schema; + using System.Data.Entity; + using System.Data.Entity.Core; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.ModelConfiguration; + using System.Data.Entity.ModelConfiguration.Edm; + using System.Data.Entity.Utilities; + using System.Linq; + using FunctionalTests.Model; + using Xunit; + + public sealed class ComplexTypeScenarioTests : TestBase + { + [Fact] + public void Can_configure_complex_column_name_after_entity_splitting() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.ComplexType(); + + modelBuilder.Entity() + .Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Properties(e => e.Property1); + }); + + modelBuilder.Entity() + .Map( + mapping => + { + mapping.ToTable("Table2"); + mapping.Properties(e => e.Property2); + mapping.Properties(e => e.ComplexProp); + }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert("Table2").HasColumn("ColumnFor_Details"); + } + + [Fact] + public void Complex_types_in_tpt_should_have_configuration_applied() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().ToTable("People"); + modelBuilder.Entity().ToTable("Employees"); + modelBuilder.ComplexType().Property(a => a.Street).HasColumnName("test"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(c => c.Street).DbEqual("test", c => c.Name); + } + + [Fact] + public void Complex_types_discovered_by_convention_should_have_configuration_applied() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(c => c.Property).DbEqual("Foo", c => c.Name).DbEqual( + false, + c => + c.Nullable); + } + + [Fact] + public void Complex_property_configuration_should_configure_complex_types() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Property(e => e.ChildComplex.Property).HasColumnName( + "Foo1"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(2, databaseMapping.Model.ComplexTypes.Count()); + + databaseMapping.Assert("EntityWithNestedComplexTypes").HasColumns( + "Id", "Bar", + "Foo", "Foo1"); + } + + [Fact] + public void Nested_complex_types_are_discovered() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Ignore(e => e.ChildComplex); + modelBuilder.ComplexType(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(2, databaseMapping.Model.ComplexTypes.Count()); + + databaseMapping.Assert("EntityWithNestedComplexTypes").HasColumns( + "Id", "Bar", + "Foo"); + } + + [Fact] + public void Complex_type_and_nested_complex_type_can_have_column_names_configured() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .Property(e => e.ChildComplex.Property) + .HasColumnName("Foo1"); + + modelBuilder.Entity() + .Property(e => e.Complex.Nested.Property) + .HasColumnName("Foo2"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(2, databaseMapping.Model.ComplexTypes.Count()); + databaseMapping.Assert("EntityWithNestedComplexTypes").HasColumns( + "Id", "Bar", + "Foo2", + "Foo1"); + } + + [Fact] + public void Complex_type_can_have_column_names_configured_whithout_altering_order() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .Property(e => e.ChildComplex.Property) + .HasColumnName("Foo1"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(2, databaseMapping.Model.ComplexTypes.Count()); + databaseMapping.Assert("EntityWithNestedComplexTypes").HasColumns( + "Id", "Bar", + "Foo", "Foo1"); + } + + [Fact] + public void Complex_type_and_nested_complex_type_column_names_configured_using_complex_type_configuration_throws() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.ComplexType() + .Property(c => c.Property) + .HasColumnName("Foo"); + + Assert.Throws(() => BuildMapping(modelBuilder)); + } + + [Fact] + public void Complex_type_column_names_use_property_path() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.ComplexType().Ignore(c => c.NestedComplexProperty); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping + .Assert() + .HasColumns("Id", "ComplexPropertyA_Property", "ComplexPropertyB_Property"); + } + + [Fact] + public void Self_referencing_complex_type_throws_exception() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.ComplexType(); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("CircularComplexTypeHierarchy"); + } + + [Fact] + public void Build_model_for_type_with_a_non_public_complex_type_property() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .HasKey(th => th.TransactionID); + modelBuilder.ComplexType(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert(th => th.RowDetails); + } + + [Fact] + public void Build_model_for_a_single_type_with_a_complex_type() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.ComplexType(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + Assert.Equal(1, databaseMapping.Model.ComplexTypes.Count()); + } + + [Fact] + public void Build_model_containing_a_complex_type_with_annotations() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate( + ProviderRegistry.Sql2008_ProviderInfo, + typeof(RowDetails)); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + Assert.Equal(1, databaseMapping.Model.ComplexTypes.Count()); + } + + [Fact] + public void Build_model_containing_a_complex_type_by_convention() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate( + ProviderRegistry.Sql2008_ProviderInfo, + typeof(UnitMeasure)); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + Assert.Equal(1, databaseMapping.Model.ComplexTypes.Count()); + } + + [Fact] + public void Build_model_containing_a_complex_type_with_configuration() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder + .ComplexType() + .Property(rd => rd.rowguid) + .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed) + .HasColumnName("ROW_GUID"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_containing_a_complex_type_with_instance_configuration() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Property(pd => pd.RowDetails.rowguid) + .HasColumnName("ROW_GUID"); + modelBuilder.ComplexType() + .Property(rd => rd.rowguid) + .HasColumnName("row_guid"); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_containing_a_complex_type_with_instance_cspace_configuration() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Property(pd => pd.RowDetails.rowguid) + .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed); + modelBuilder.ComplexType(); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(2, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_containing_a_complex_type_with_has_max_length_configuration() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.ComplexType(); + modelBuilder.Entity() + .Property(p => p.LargePhoto.Photo) + .HasColumnType("binary") + .HasMaxLength(42); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert(l => l.Photo) + .FacetEqual(42, f => f.MaxLength) + .DbEqual(42, f => f.MaxLength); + } + + [Fact] + public void Build_model_containing_a_complex_type_with_instance_cspace_configuration_override() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Property(pd => pd.RowDetails.rowguid) + .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed); + modelBuilder.ComplexType() + .Property(rd => rd.rowguid) + .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void ComplexType_nullable_is_not_propagated_when_using_TPH() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.ComplexType
() + .Property(a => a.Line1) + .IsRequired(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + // Not propagated + + Assert.Equal( + false, + databaseMapping.Database.EntityTypes.ElementAt(0).Properties.Single(c => c.Name == "HomeAddress_Line1") + .Nullable); + EdmModel tempQualifier1 = databaseMapping.Database; + DebugCheck.NotNull(tempQualifier1); + Assert.Equal( + true, + tempQualifier1.EntityTypes.ElementAt(0).Properties.Single(c => c.Name == "WorkAddress_Line1") + .Nullable); + + EdmModel tempQualifier2 = databaseMapping.Database; + DebugCheck.NotNull(tempQualifier2); + Assert.Equal( + true, + tempQualifier2.EntityTypes.ElementAt(0).Properties.Single(c => c.Name == "HomeAddress_Line2") + .Nullable); + EdmModel tempQualifier3 = databaseMapping.Database; + DebugCheck.NotNull(tempQualifier3); + Assert.Equal( + true, + tempQualifier3.EntityTypes.ElementAt(0).Properties.Single(c => c.Name == "WorkAddress_Line2") + .Nullable); + } + + [Fact] + public void ComplexType_nullable_is_propagated_when_using_TPT() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().ToTable("Employees"); + modelBuilder.Entity().ToTable("OffSiteEmployees"); + modelBuilder.ComplexType
() + .Property(a => a.Line1) + .IsRequired(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + Assert.Equal( + false, + databaseMapping.Database.EntityTypes.ElementAt(0).Properties.Single(c => c.Name == "HomeAddress_Line1") + .Nullable); + EdmModel tempQualifier1 = databaseMapping.Database; + DebugCheck.NotNull(tempQualifier1); + Assert.Equal( + false, + tempQualifier1.EntityTypes.ElementAt(1).Properties.Single(c => c.Name == "WorkAddress_Line1") + .Nullable); + + EdmModel tempQualifier2 = databaseMapping.Database; + DebugCheck.NotNull(tempQualifier2); + Assert.Equal( + true, + tempQualifier2.EntityTypes.ElementAt(0).Properties.Single(c => c.Name == "HomeAddress_Line2") + .Nullable); + EdmModel tempQualifier3 = databaseMapping.Database; + DebugCheck.NotNull(tempQualifier3); + Assert.Equal( + true, + tempQualifier3.EntityTypes.ElementAt(1).Properties.Single(c => c.Name == "WorkAddress_Line2") + .Nullable); + } + + [Fact] + public void Model_with_multiple_complex_types_and_entities_finds_complex_types_by_convention() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasKey(b => b.Number); + + modelBuilder.Entity() + .HasKey(b => b.EmployeeNumber); + + modelBuilder.Entity() + .HasKey(o => o.Number); + + modelBuilder.Entity() + .HasKey( + p => new + { + p.EmployeeNo, + p.PhotoId + }); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + Assert.Equal(2, databaseMapping.Model.ComplexTypes.Count()); + } + + [Fact] + public void Annotations_on_complex_type_classes_are_not_present_on_properties() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + // Not propagated + var annotations = databaseMapping.Model + .EntityTypes.Single(x => x.Name == "CTEmployee") + .Properties.Single(p => p.Name == "HomeAddress") + .Annotations; + Assert.Equal( + 0, + ((ICollection)annotations.SingleOrDefault(a => a.Name == "ClrAttributes").Value). + Count); + } + + [Fact] + public void Property_max_length_convention_applied_to_complex_types() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Ignore(); + modelBuilder.ComplexType
(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + databaseMapping.Assert
(a => a.Line1).FacetEqual(true, f => f.IsMaxLength); + } + } + + #region Fixtures + + [ComplexType] + public class Address + { + public string Line1 { get; set; } + public string Line2 { get; set; } + } + + public class CTEmployee + { + public int CTEmployeeId { get; set; } + public Address HomeAddress { get; set; } + } + + public class OffSiteEmployee : CTEmployee + { + public Address WorkAddress { get; set; } + } + + public class Building + { + public int Id { get; set; } + public Address Address { get; set; } + } + + public class LoCTBuilding + { + public int Number { get; set; } + public string Name { get; set; } + public LoCTAddress Address { get; set; } + + public ICollection LoCTOffices { get; set; } + } + + public class LoCTOffice + { + public int BuildingNumber { get; set; } + public string Number { get; set; } + + public LoCTBuilding LoCTBuilding { get; set; } + public ICollection Occupants { get; set; } + } + + public class LoCTEmployee + { + public int EmployeeNumber { get; set; } + public LoCTName Name { get; set; } + public LoCTAddress HomeAddress { get; set; } + + public LoCTOffice Office { get; set; } + public ICollection Photos { get; set; } + } + + public class LoCTEmployeePhoto + { + public int PhotoId { get; set; } + public int EmployeeNo { get; set; } + + public byte[] Photo { get; set; } + } + + public class LoCTName + { + public string FirstName { get; set; } + public string LastName { get; set; } + public string Title { get; set; } + } + + public class LoCTAddress + { + public string Line1 { get; set; } + public string Line2 { get; set; } + public string City { get; set; } + public string State { get; set; } + public string Zip { get; set; } + } + + public class ComplexTypeEntity + { + public int Id { get; set; } + public ComplexType ComplexPropertyA { get; set; } + public ComplexType ComplexPropertyB { get; set; } + } + + public class ComplexType + { + public string Property { get; set; } + public ComplexType NestedComplexProperty { get; set; } + } + + public class ParentComplexType + { + [Column("Bar")] + [Required] + public string Property { get; set; } + + public ChildComplexType Nested { get; set; } + } + + public class ChildComplexType + { + [Column("Foo")] + [Required] + public string Property { get; set; } + } + + public class EntityWithByConventionComplexType + { + public int Id { get; set; } + public ChildComplexType Complex { get; set; } + } + + public class EntityWithNestedComplexType + { + public int Id { get; set; } + public ParentComplexType Complex { get; set; } + public ChildComplexType ChildComplex { get; set; } + } + + public class Person_166889 + { + [Key] + public int PersonId { get; set; } + + public string Name { get; set; } + } + + public class Employee_166889 : Person_166889 + { + public string EmployeeNo { get; set; } + public Address_166889 Address { get; set; } + } + + public class Address_166889 + { + public string Street { get; set; } + public string City { get; set; } + public string ZipCode { get; set; } + } + + public class ComplexTypeWithColumnRename + { + [Column("ColumnFor_Details")] + public string Details { get; set; } + } + + public class EntityWithColumnsRename + { + public int Id { get; set; } + + [Column("ColumnFor_Property1")] + public byte[] Property1 { get; set; } + + [Column("ColumnFor_Property2")] + public string Property2 { get; set; } + + public ComplexTypeWithColumnRename ComplexProp { get; set; } + } + + #endregion +} diff --git a/test/EntityFramework/FunctionalTests/CodeFirst/ConfigurationScenarioTests.cs b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/ConfigurationScenarioTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/CodeFirst/ConfigurationScenarioTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/CodeFirst/ConfigurationScenarioTests.cs index b0948011..a65bd206 100644 --- a/test/EntityFramework/FunctionalTests/CodeFirst/ConfigurationScenarioTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/ConfigurationScenarioTests.cs @@ -1,348 +1,348 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests -{ - using System; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; - using System.Data.Entity; - using System.Data.Entity.Infrastructure; - using System.Data.Entity.ModelConfiguration; - using System.Linq; - using FunctionalTests.Model; - using Xunit; - - public sealed class ConfigurationScenarioTests : TestBase - { - [Fact] - public void Can_set_store_type_with_column_annotation_on_base_property() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(e => e.Property1).DbEqual("timestamp", c => c.TypeName); - } - - public void TestCompositeKeyOrder( - Action configure, string[] expectedPropertyOrder, - string[] expectedColumnOrder) - { - var modelBuilder = new DbModelBuilder(); - - configure(modelBuilder); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.True( - expectedPropertyOrder.SequenceEqual( - databaseMapping.Model.EntityTypes.Single().DeclaredKeyProperties.Select( - p => p.Name))); - - databaseMapping.Assert("CompositeKeyNoOrders").HasColumns(expectedColumnOrder); - } - - [Fact] - public void Composite_key_should_result_in_correct_order_when_key_and_order_configured_using_api() - { - TestCompositeKeyOrder( - modelBuilder => - { - modelBuilder.Entity().Property(c => c.Id2).HasColumnOrder(1); - modelBuilder.Entity().Property(c => c.Id1).HasColumnOrder(2); - modelBuilder.Entity().HasKey( - c => new - { - c.Id1, - c.Id2 - }); - }, - new[] { "Id1", "Id2" }, - new[] { "Id2", "Id1" }); - } - - [Fact] - public void Composite_key_should_result_in_correct_order_when_key_configured_using_api() - { - TestCompositeKeyOrder( - modelBuilder => modelBuilder.Entity().HasKey( - c => new - { - c.Id2, - c.Id1 - }), - new[] { "Id2", "Id1" }, - new[] { "Id2", "Id1" }); - } - - [Fact] - public void Composite_key_should_result_in_correct_order_when_order_configured_using_api() - { - TestCompositeKeyOrder( - modelBuilder => - { - modelBuilder.Entity().Property(c => c.Id2).HasColumnOrder(1); - modelBuilder.Entity().Property(c => c.Id1).HasColumnOrder(2); - }, - new[] { "Id2", "Id1" }, - new[] { "Id2", "Id1" }); - } - - [Fact] - public void Composite_key_should_result_in_correct_order_when_key_and_order_configured_using_configuration() - { - TestCompositeKeyOrder( - modelBuilder => - { - var configuration = new EntityTypeConfiguration(); - - configuration.Property(c => c.Id2).HasColumnOrder(1); - configuration.Property(c => c.Id1).HasColumnOrder(2); - configuration.HasKey( - c => new - { - c.Id1, - c.Id2 - }); - - modelBuilder.Configurations.Add(configuration); - }, - new[] { "Id1", "Id2" }, - new[] { "Id2", "Id1" }); - } - - [Fact] - public void Composite_key_should_result_in_correct_order_when_key_configured_using_configuration() - { - TestCompositeKeyOrder( - modelBuilder => - { - var configuration = new EntityTypeConfiguration(); - - configuration.HasKey( - c => new - { - c.Id2, - c.Id1 - }); - - modelBuilder.Configurations.Add(configuration); - }, - new[] { "Id2", "Id1" }, - new[] { "Id2", "Id1" }); - } - - [Fact] - public void Composite_key_should_result_in_correct_order_when_order_configured_using_configuration() - { - TestCompositeKeyOrder( - modelBuilder => - { - var configuration = new EntityTypeConfiguration(); - - configuration.Property(c => c.Id2).HasColumnOrder(1); - configuration.Property(c => c.Id1).HasColumnOrder(2); - - modelBuilder.Configurations.Add(configuration); - }, - new[] { "Id2", "Id1" }, - new[] { "Id2", "Id1" }); - } - - [Fact] - public void Composite_key_should_throw_when_no_order_configured() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("ModelGeneration_UnableToDetermineKeyOrder", typeof(CompositeKeyNoOrder)); - } - - [Fact] - public void HasEntitySetName_configured_using_api() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasKey(u => u.UnitMeasureCode); - modelBuilder.Entity().HasEntitySetName("Units"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal("Units", databaseMapping.Model.Containers.Single().EntitySets.Single().Name); - } - - [Fact] - public void HasEntitySetName_configured_using_configuration() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - var configuration = new EntityTypeConfiguration(); - - configuration.HasKey(u => u.UnitMeasureCode); - configuration.HasEntitySetName("Units"); - - modelBuilder.Configurations.Add(configuration); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal("Units", databaseMapping.Model.Containers.Single().EntitySets.Single().Name); - } - - [Fact] - public void External_duplicate_association_configuration() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Configurations - .Add(new ProductCategoryConfiguration()) - .Add(new ProductSubcategoryConfiguration()); - - modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - } - - private class ProductCategoryConfiguration : EntityTypeConfiguration - { - public ProductCategoryConfiguration() - { - HasMany(p => p.ProductSubcategories) - .WithRequired(s => s.ProductCategory) - .HasForeignKey(s => s.ProductCategoryID); - } - } - - private class ProductSubcategoryConfiguration : EntityTypeConfiguration - { - public ProductSubcategoryConfiguration() - { - HasRequired(s => s.ProductCategory) - .WithMany(p => p.ProductSubcategories) - .HasForeignKey(s => s.ProductCategoryID); - } - } - - [Fact] - public void Can_call_Entity_after_adding_custom_configuration_class_during_OnModelCreating() - { - Database.SetInitializer(null); - using (var ctx = new BasicTypeContext()) - { - var oc = ((IObjectContextAdapter)ctx).ObjectContext; - } - } - - [Fact] - public void HasKey_throws_on_collection_nav_prop() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - Assert.Throws( - () => modelBuilder.Entity().HasKey(c => c.CustomerAddresses)) - .ValidateMessage("ModelBuilder_KeyPropertiesMustBePrimitive", "CustomerAddresses", typeof(Customer)); - } - - [Fact] - public void HasKey_throws_on_reference_nav_prop() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - Assert.Throws( - () => modelBuilder.Entity().HasKey(c => c.CustomerDiscount)) - .ValidateMessage("ModelBuilder_KeyPropertiesMustBePrimitive", "CustomerDiscount", typeof(Customer)); - } - - [Fact] - public void HasKey_throws_on_complex_property() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.ComplexType(); - - Assert.Throws( - () => modelBuilder.Entity().HasKey(c => c.CustomerDiscount)) - .ValidateMessage("ModelBuilder_KeyPropertiesMustBePrimitive", "CustomerDiscount", typeof(Customer)); - } - - [Fact] - public void Nested_config_class_with_private_property() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Configurations.Add(new CreditCard.CreditCardConfiguration()); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert().HasColumn("CardNumber"); - } - } - - #region Fixtures - - public class BasicType - { - public int Id { get; set; } - } - - public class BasicTypeConfiguration : EntityTypeConfiguration - { - public BasicTypeConfiguration() - { - ToTable("Blah"); - } - } - - public class BasicTypeContext : DbContext - { - public DbSet BasicTypes { get; set; } - - private readonly BasicTypeConfiguration _basicTypeConfiguration = new BasicTypeConfiguration(); - - internal BasicTypeConfiguration BasicTypeConfiguration - { - get { return _basicTypeConfiguration; } - } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - modelBuilder.Configurations.Add(BasicTypeConfiguration); - modelBuilder.Entity(); - Assert.Equal("BasicTypes", modelBuilder.ModelConfiguration.Entity(typeof(BasicType)).EntitySetName); - Assert.Equal("Blah", modelBuilder.ModelConfiguration.Entity(typeof(BasicType)).GetTableName().Name); - } - } - - public class CompositeKeyNoOrder - { - [Key] - public int Id1 { get; set; } - - [Key] - public int Id2 { get; set; } - } - - public abstract class BaseEntity_155894 - { - public int Id { get; set; } - - [Column(TypeName = "timestamp")] - public byte[] Property1 { get; set; } - } - - public class DerivedEntity_155894 : BaseEntity_155894 - { - public string Property2 { get; set; } - } - - #endregion -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests +{ + using System; + using System.ComponentModel.DataAnnotations; + using System.ComponentModel.DataAnnotations.Schema; + using System.Data.Entity; + using System.Data.Entity.Infrastructure; + using System.Data.Entity.ModelConfiguration; + using System.Linq; + using FunctionalTests.Model; + using Xunit; + + public sealed class ConfigurationScenarioTests : TestBase + { + [Fact] + public void Can_set_store_type_with_column_annotation_on_base_property() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(e => e.Property1).DbEqual("timestamp", c => c.TypeName); + } + + public void TestCompositeKeyOrder( + Action configure, string[] expectedPropertyOrder, + string[] expectedColumnOrder) + { + var modelBuilder = new DbModelBuilder(); + + configure(modelBuilder); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.True( + expectedPropertyOrder.SequenceEqual( + databaseMapping.Model.EntityTypes.Single().DeclaredKeyProperties.Select( + p => p.Name))); + + databaseMapping.Assert("CompositeKeyNoOrders").HasColumns(expectedColumnOrder); + } + + [Fact] + public void Composite_key_should_result_in_correct_order_when_key_and_order_configured_using_api() + { + TestCompositeKeyOrder( + modelBuilder => + { + modelBuilder.Entity().Property(c => c.Id2).HasColumnOrder(1); + modelBuilder.Entity().Property(c => c.Id1).HasColumnOrder(2); + modelBuilder.Entity().HasKey( + c => new + { + c.Id1, + c.Id2 + }); + }, + new[] { "Id1", "Id2" }, + new[] { "Id2", "Id1" }); + } + + [Fact] + public void Composite_key_should_result_in_correct_order_when_key_configured_using_api() + { + TestCompositeKeyOrder( + modelBuilder => modelBuilder.Entity().HasKey( + c => new + { + c.Id2, + c.Id1 + }), + new[] { "Id2", "Id1" }, + new[] { "Id2", "Id1" }); + } + + [Fact] + public void Composite_key_should_result_in_correct_order_when_order_configured_using_api() + { + TestCompositeKeyOrder( + modelBuilder => + { + modelBuilder.Entity().Property(c => c.Id2).HasColumnOrder(1); + modelBuilder.Entity().Property(c => c.Id1).HasColumnOrder(2); + }, + new[] { "Id2", "Id1" }, + new[] { "Id2", "Id1" }); + } + + [Fact] + public void Composite_key_should_result_in_correct_order_when_key_and_order_configured_using_configuration() + { + TestCompositeKeyOrder( + modelBuilder => + { + var configuration = new EntityTypeConfiguration(); + + configuration.Property(c => c.Id2).HasColumnOrder(1); + configuration.Property(c => c.Id1).HasColumnOrder(2); + configuration.HasKey( + c => new + { + c.Id1, + c.Id2 + }); + + modelBuilder.Configurations.Add(configuration); + }, + new[] { "Id1", "Id2" }, + new[] { "Id2", "Id1" }); + } + + [Fact] + public void Composite_key_should_result_in_correct_order_when_key_configured_using_configuration() + { + TestCompositeKeyOrder( + modelBuilder => + { + var configuration = new EntityTypeConfiguration(); + + configuration.HasKey( + c => new + { + c.Id2, + c.Id1 + }); + + modelBuilder.Configurations.Add(configuration); + }, + new[] { "Id2", "Id1" }, + new[] { "Id2", "Id1" }); + } + + [Fact] + public void Composite_key_should_result_in_correct_order_when_order_configured_using_configuration() + { + TestCompositeKeyOrder( + modelBuilder => + { + var configuration = new EntityTypeConfiguration(); + + configuration.Property(c => c.Id2).HasColumnOrder(1); + configuration.Property(c => c.Id1).HasColumnOrder(2); + + modelBuilder.Configurations.Add(configuration); + }, + new[] { "Id2", "Id1" }, + new[] { "Id2", "Id1" }); + } + + [Fact] + public void Composite_key_should_throw_when_no_order_configured() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("ModelGeneration_UnableToDetermineKeyOrder", typeof(CompositeKeyNoOrder)); + } + + [Fact] + public void HasEntitySetName_configured_using_api() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasKey(u => u.UnitMeasureCode); + modelBuilder.Entity().HasEntitySetName("Units"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal("Units", databaseMapping.Model.Containers.Single().EntitySets.Single().Name); + } + + [Fact] + public void HasEntitySetName_configured_using_configuration() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + var configuration = new EntityTypeConfiguration(); + + configuration.HasKey(u => u.UnitMeasureCode); + configuration.HasEntitySetName("Units"); + + modelBuilder.Configurations.Add(configuration); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal("Units", databaseMapping.Model.Containers.Single().EntitySets.Single().Name); + } + + [Fact] + public void External_duplicate_association_configuration() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Configurations + .Add(new ProductCategoryConfiguration()) + .Add(new ProductSubcategoryConfiguration()); + + modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + } + + private class ProductCategoryConfiguration : EntityTypeConfiguration + { + public ProductCategoryConfiguration() + { + HasMany(p => p.ProductSubcategories) + .WithRequired(s => s.ProductCategory) + .HasForeignKey(s => s.ProductCategoryID); + } + } + + private class ProductSubcategoryConfiguration : EntityTypeConfiguration + { + public ProductSubcategoryConfiguration() + { + HasRequired(s => s.ProductCategory) + .WithMany(p => p.ProductSubcategories) + .HasForeignKey(s => s.ProductCategoryID); + } + } + + [Fact] + public void Can_call_Entity_after_adding_custom_configuration_class_during_OnModelCreating() + { + Database.SetInitializer(null); + using (var ctx = new BasicTypeContext()) + { + var oc = ((IObjectContextAdapter)ctx).ObjectContext; + } + } + + [Fact] + public void HasKey_throws_on_collection_nav_prop() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + Assert.Throws( + () => modelBuilder.Entity().HasKey(c => c.CustomerAddresses)) + .ValidateMessage("ModelBuilder_KeyPropertiesMustBePrimitive", "CustomerAddresses", typeof(Customer)); + } + + [Fact] + public void HasKey_throws_on_reference_nav_prop() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + Assert.Throws( + () => modelBuilder.Entity().HasKey(c => c.CustomerDiscount)) + .ValidateMessage("ModelBuilder_KeyPropertiesMustBePrimitive", "CustomerDiscount", typeof(Customer)); + } + + [Fact] + public void HasKey_throws_on_complex_property() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.ComplexType(); + + Assert.Throws( + () => modelBuilder.Entity().HasKey(c => c.CustomerDiscount)) + .ValidateMessage("ModelBuilder_KeyPropertiesMustBePrimitive", "CustomerDiscount", typeof(Customer)); + } + + [Fact] + public void Nested_config_class_with_private_property() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Configurations.Add(new CreditCard.CreditCardConfiguration()); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert().HasColumn("CardNumber"); + } + } + + #region Fixtures + + public class BasicType + { + public int Id { get; set; } + } + + public class BasicTypeConfiguration : EntityTypeConfiguration + { + public BasicTypeConfiguration() + { + ToTable("Blah"); + } + } + + public class BasicTypeContext : DbContext + { + public DbSet BasicTypes { get; set; } + + private readonly BasicTypeConfiguration _basicTypeConfiguration = new BasicTypeConfiguration(); + + internal BasicTypeConfiguration BasicTypeConfiguration + { + get { return _basicTypeConfiguration; } + } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + modelBuilder.Configurations.Add(BasicTypeConfiguration); + modelBuilder.Entity(); + Assert.Equal("BasicTypes", modelBuilder.ModelConfiguration.Entity(typeof(BasicType)).EntitySetName); + Assert.Equal("Blah", modelBuilder.ModelConfiguration.Entity(typeof(BasicType)).GetTableName().Name); + } + } + + public class CompositeKeyNoOrder + { + [Key] + public int Id1 { get; set; } + + [Key] + public int Id2 { get; set; } + } + + public abstract class BaseEntity_155894 + { + public int Id { get; set; } + + [Column(TypeName = "timestamp")] + public byte[] Property1 { get; set; } + } + + public class DerivedEntity_155894 : BaseEntity_155894 + { + public string Property2 { get; set; } + } + + #endregion +} diff --git a/test/EntityFramework/FunctionalTests/CodeFirst/ConventionsScenarioTests.cs b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/ConventionsScenarioTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/CodeFirst/ConventionsScenarioTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/CodeFirst/ConventionsScenarioTests.cs index 37a79895..13713be9 100644 --- a/test/EntityFramework/FunctionalTests/CodeFirst/ConventionsScenarioTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/ConventionsScenarioTests.cs @@ -1,317 +1,317 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests -{ - using System; - using System.Collections.Generic; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; - using System.Data.Entity; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.Migrations; - using System.Data.Entity.ModelConfiguration; - using System.Data.Entity.ModelConfiguration.Conventions; - using System.Data.Entity.ModelConfiguration.Edm; - using System.Data.Entity.Utilities; - using System.Linq; - using FunctionalTests.Model; - using Xunit; - - public sealed class ConventionsScenarioTests : TestBase - { - [Fact] - public void Add_custom_model_convention() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Conventions.Add(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal( - 1, - databaseMapping.Model.GetEntitySets().Count( - t => t.Name == "CustomersFoo")); - } - - private sealed class EntitySetNamingConvention : IEdmConvention - { - public void Apply(EntitySet entitySet, EdmModel model) - { - entitySet.Name = entitySet.Name + "Foo"; - } - } - - [Fact] - public void Add_custom_model_convention_with_ordering() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Conventions.AddAfter(new CodeKeyDiscoveryConvention()); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - private sealed class CodeKeyDiscoveryConvention : KeyDiscoveryConvention - { - private const string Code = "Code"; - - protected override EdmProperty MatchKeyProperty( - EntityType entityType, - IEnumerable primitiveProperties) - { - return primitiveProperties - .SingleOrDefault(p => Code.Equals(p.Name, StringComparison.OrdinalIgnoreCase)) - ?? primitiveProperties - .SingleOrDefault( - p => (entityType.Name + Code).Equals(p.Name, StringComparison.OrdinalIgnoreCase)); - } - } - - [Fact] - public void Remove_an_existing_convention() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Conventions.Remove(); - - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Add_lightweight_convention() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entities() - .Where(t => t == typeof(LightweightEntity)) - .Configure(e => e.ToTable("TheTable")); - - var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.True( - model.DatabaseMapping.Database.GetEntitySets().All(t => t.Table == "TheTable")); - } - - [Fact] - public void Lightweight_convention_does_not_override_explicit_configurations() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Configurations.Add(new LightweightEntityWithConfiguration.Configuration()); - modelBuilder.Properties() - .Configure(p => p.HasMaxLength(256)); - - var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); - - var table - = model.DatabaseMapping.Database.EntityTypes - .Single(t => t.Name == "LightweightEntityWithConfiguration"); - - var attributeColumn = table.Properties.Single(c => c.Name == "PropertyConfiguredByAttribute"); - Assert.Equal(64, attributeColumn.MaxLength); - - var fluentColumn = table.Properties.Single(c => c.Name == "PropertyConfiguredByFluent"); - Assert.Equal(128, fluentColumn.MaxLength); - - var unconfiguredColumn = table.Properties.Single(c => c.Name == "PropertyNotConfigured"); - Assert.Equal(256, unconfiguredColumn.MaxLength); - } - - [Fact] - public void Can_configure_complex_type_properties() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Properties() - .Configure(p => p.HasMaxLength(256)); - - var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); - - var column = model.DatabaseMapping.Database.EntityTypes - .Single() - .Properties.Single(c => c.Name == "ComplexProperty_StringProperty"); - Assert.Equal(256, column.MaxLength); - } - - [Fact] - public void Lightweight_conventions_can_filter_by_interface() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entities() - .Configure(c => c.HasKey(e => e.IntProperty)); - - var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); - - var entity = model.DatabaseMapping.Model.EntityTypes.Single(); - Assert.Equal(1, entity.DeclaredKeyProperties.Count()); - Assert.Equal("IntProperty", entity.DeclaredKeyProperties.Single().Name); - } - - [Fact] - public void Lightweight_conventions_can_filter_by_object() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entities() - .Configure(c => c.HasKey(e => e.IntProperty)); - - var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); - - var entity = model.DatabaseMapping.Model.EntityTypes.Single(); - Assert.Equal(1, entity.DeclaredKeyProperties.Count()); - Assert.Equal("IntProperty", entity.DeclaredKeyProperties.Single().Name); - } - - [Fact] - public void Single_key_configurable_with_isKey() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Properties() - .Where(p => p.Name == "IntProperty") - .Configure(c => c.IsKey()); - - var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); - - var entity = model.DatabaseMapping.Model.EntityTypes.Single(); - Assert.Equal(1, entity.DeclaredKeyProperties.Count()); - Assert.Equal("IntProperty", entity.DeclaredKeyProperties.Single().Name); - } - - [Fact] - public void Composite_key_configurable_with_isKey() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Properties() - .Where(p => p.Name == "IntProperty") - .Configure(c => c.HasColumnOrder(0).IsKey()); - - modelBuilder.Properties() - .Where(p => p.Name == "IntProperty1") - .Configure(c => c.HasColumnOrder(1).IsKey()); - - var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); - - var entity = model.DatabaseMapping.Model.EntityTypes.Single(); - var keys = entity.DeclaredKeyProperties; - Assert.Equal(2, keys.Count()); - Assert.Equal("IntProperty", keys.ElementAt(0).Name); - Assert.Equal("IntProperty1", keys.ElementAt(1).Name); - } - - [Fact] - public void Is_key_is_ignored_if_key_is_already_set() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Properties() - .Where(p => p.Name == "IntProperty1") - .Configure(c => c.HasColumnOrder(1).IsKey()); - - var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); - - var entity = model.DatabaseMapping.Model.EntityTypes.Single(); - var keys = entity.DeclaredKeyProperties; - Assert.Equal(1, keys.Count()); - Assert.Equal("IntProperty", keys.ElementAt(0).Name); - } - - [Fact] - public void HasKey_can_build_composite_keys_filtered_by_interface() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entities() - .Configure(c => c.HasKey(e => new { e.IntProperty, e.IntProperty1 })); - - var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); - - var entity = model.DatabaseMapping.Model.EntityTypes.Single(); - var keys = entity.DeclaredKeyProperties; - Assert.Equal(2, keys.Count()); - Assert.Equal("IntProperty", keys.First().Name); - Assert.Equal("IntProperty1", keys.Last().Name); - } - - [Fact] - public void HasKey_ignores_rule_if_key_configured_with_annotations() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entities() - .Configure(c => c.HasKey(e => e.IntProperty)); - - var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); - - var entity = model.DatabaseMapping.Model.EntityTypes.Single(); - var keys = entity.DeclaredKeyProperties; - Assert.Equal(1, keys.Count()); - Assert.Equal("IntProperty", keys.First().Name); - } - } - - public class LightweightEntityWithConfiguration - { - public int Id { get; set; } - - [StringLength(64)] - public string PropertyConfiguredByAttribute { get; set; } - - public string PropertyConfiguredByFluent { get; set; } - public string PropertyNotConfigured { get; set; } - - internal class Configuration : EntityTypeConfiguration - { - public Configuration() - { - Property(e => e.PropertyConfiguredByFluent).HasMaxLength(128); - } - } - } - - public class LightweightComplexType - { - public string StringProperty { get; set; } - } - - public interface ILightweightEntity - { - int IntProperty { get; set; } - int IntProperty1 { get; set; } - } - - public class LightweightEntity : ILightweightEntity - { - public int Id { get; set; } - public int IntProperty { get; set; } - public int IntProperty1 { get; set; } - public LightweightComplexType ComplexProperty { get; set; } - } - - public class LightweightEntityWithKeyConfiguration : ILightweightEntity - { - public int Id { get; set; } - [Key, Column(Order = 0)] - public int IntProperty { get; set; } - public int IntProperty1 { get; set; } - public LightweightComplexType ComplexProperty { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests +{ + using System; + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + using System.ComponentModel.DataAnnotations.Schema; + using System.Data.Entity; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.Migrations; + using System.Data.Entity.ModelConfiguration; + using System.Data.Entity.ModelConfiguration.Conventions; + using System.Data.Entity.ModelConfiguration.Edm; + using System.Data.Entity.Utilities; + using System.Linq; + using FunctionalTests.Model; + using Xunit; + + public sealed class ConventionsScenarioTests : TestBase + { + [Fact] + public void Add_custom_model_convention() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Conventions.Add(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal( + 1, + databaseMapping.Model.GetEntitySets().Count( + t => t.Name == "CustomersFoo")); + } + + private sealed class EntitySetNamingConvention : IEdmConvention + { + public void Apply(EntitySet entitySet, EdmModel model) + { + entitySet.Name = entitySet.Name + "Foo"; + } + } + + [Fact] + public void Add_custom_model_convention_with_ordering() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Conventions.AddAfter(new CodeKeyDiscoveryConvention()); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + private sealed class CodeKeyDiscoveryConvention : KeyDiscoveryConvention + { + private const string Code = "Code"; + + protected override EdmProperty MatchKeyProperty( + EntityType entityType, + IEnumerable primitiveProperties) + { + return primitiveProperties + .SingleOrDefault(p => Code.Equals(p.Name, StringComparison.OrdinalIgnoreCase)) + ?? primitiveProperties + .SingleOrDefault( + p => (entityType.Name + Code).Equals(p.Name, StringComparison.OrdinalIgnoreCase)); + } + } + + [Fact] + public void Remove_an_existing_convention() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Conventions.Remove(); + + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Add_lightweight_convention() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entities() + .Where(t => t == typeof(LightweightEntity)) + .Configure(e => e.ToTable("TheTable")); + + var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.True( + model.DatabaseMapping.Database.GetEntitySets().All(t => t.Table == "TheTable")); + } + + [Fact] + public void Lightweight_convention_does_not_override_explicit_configurations() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Configurations.Add(new LightweightEntityWithConfiguration.Configuration()); + modelBuilder.Properties() + .Configure(p => p.HasMaxLength(256)); + + var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); + + var table + = model.DatabaseMapping.Database.EntityTypes + .Single(t => t.Name == "LightweightEntityWithConfiguration"); + + var attributeColumn = table.Properties.Single(c => c.Name == "PropertyConfiguredByAttribute"); + Assert.Equal(64, attributeColumn.MaxLength); + + var fluentColumn = table.Properties.Single(c => c.Name == "PropertyConfiguredByFluent"); + Assert.Equal(128, fluentColumn.MaxLength); + + var unconfiguredColumn = table.Properties.Single(c => c.Name == "PropertyNotConfigured"); + Assert.Equal(256, unconfiguredColumn.MaxLength); + } + + [Fact] + public void Can_configure_complex_type_properties() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Properties() + .Configure(p => p.HasMaxLength(256)); + + var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); + + var column = model.DatabaseMapping.Database.EntityTypes + .Single() + .Properties.Single(c => c.Name == "ComplexProperty_StringProperty"); + Assert.Equal(256, column.MaxLength); + } + + [Fact] + public void Lightweight_conventions_can_filter_by_interface() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entities() + .Configure(c => c.HasKey(e => e.IntProperty)); + + var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); + + var entity = model.DatabaseMapping.Model.EntityTypes.Single(); + Assert.Equal(1, entity.DeclaredKeyProperties.Count()); + Assert.Equal("IntProperty", entity.DeclaredKeyProperties.Single().Name); + } + + [Fact] + public void Lightweight_conventions_can_filter_by_object() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entities() + .Configure(c => c.HasKey(e => e.IntProperty)); + + var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); + + var entity = model.DatabaseMapping.Model.EntityTypes.Single(); + Assert.Equal(1, entity.DeclaredKeyProperties.Count()); + Assert.Equal("IntProperty", entity.DeclaredKeyProperties.Single().Name); + } + + [Fact] + public void Single_key_configurable_with_isKey() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Properties() + .Where(p => p.Name == "IntProperty") + .Configure(c => c.IsKey()); + + var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); + + var entity = model.DatabaseMapping.Model.EntityTypes.Single(); + Assert.Equal(1, entity.DeclaredKeyProperties.Count()); + Assert.Equal("IntProperty", entity.DeclaredKeyProperties.Single().Name); + } + + [Fact] + public void Composite_key_configurable_with_isKey() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Properties() + .Where(p => p.Name == "IntProperty") + .Configure(c => c.HasColumnOrder(0).IsKey()); + + modelBuilder.Properties() + .Where(p => p.Name == "IntProperty1") + .Configure(c => c.HasColumnOrder(1).IsKey()); + + var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); + + var entity = model.DatabaseMapping.Model.EntityTypes.Single(); + var keys = entity.DeclaredKeyProperties; + Assert.Equal(2, keys.Count()); + Assert.Equal("IntProperty", keys.ElementAt(0).Name); + Assert.Equal("IntProperty1", keys.ElementAt(1).Name); + } + + [Fact] + public void Is_key_is_ignored_if_key_is_already_set() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Properties() + .Where(p => p.Name == "IntProperty1") + .Configure(c => c.HasColumnOrder(1).IsKey()); + + var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); + + var entity = model.DatabaseMapping.Model.EntityTypes.Single(); + var keys = entity.DeclaredKeyProperties; + Assert.Equal(1, keys.Count()); + Assert.Equal("IntProperty", keys.ElementAt(0).Name); + } + + [Fact] + public void HasKey_can_build_composite_keys_filtered_by_interface() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entities() + .Configure(c => c.HasKey(e => new { e.IntProperty, e.IntProperty1 })); + + var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); + + var entity = model.DatabaseMapping.Model.EntityTypes.Single(); + var keys = entity.DeclaredKeyProperties; + Assert.Equal(2, keys.Count()); + Assert.Equal("IntProperty", keys.First().Name); + Assert.Equal("IntProperty1", keys.Last().Name); + } + + [Fact] + public void HasKey_ignores_rule_if_key_configured_with_annotations() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entities() + .Configure(c => c.HasKey(e => e.IntProperty)); + + var model = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); + + var entity = model.DatabaseMapping.Model.EntityTypes.Single(); + var keys = entity.DeclaredKeyProperties; + Assert.Equal(1, keys.Count()); + Assert.Equal("IntProperty", keys.First().Name); + } + } + + public class LightweightEntityWithConfiguration + { + public int Id { get; set; } + + [StringLength(64)] + public string PropertyConfiguredByAttribute { get; set; } + + public string PropertyConfiguredByFluent { get; set; } + public string PropertyNotConfigured { get; set; } + + internal class Configuration : EntityTypeConfiguration + { + public Configuration() + { + Property(e => e.PropertyConfiguredByFluent).HasMaxLength(128); + } + } + } + + public class LightweightComplexType + { + public string StringProperty { get; set; } + } + + public interface ILightweightEntity + { + int IntProperty { get; set; } + int IntProperty1 { get; set; } + } + + public class LightweightEntity : ILightweightEntity + { + public int Id { get; set; } + public int IntProperty { get; set; } + public int IntProperty1 { get; set; } + public LightweightComplexType ComplexProperty { get; set; } + } + + public class LightweightEntityWithKeyConfiguration : ILightweightEntity + { + public int Id { get; set; } + [Key, Column(Order = 0)] + public int IntProperty { get; set; } + public int IntProperty1 { get; set; } + public LightweightComplexType ComplexProperty { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/CodeFirst/DataAnnotationScenarioTests.cs b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/DataAnnotationScenarioTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/CodeFirst/DataAnnotationScenarioTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/CodeFirst/DataAnnotationScenarioTests.cs index 060e755d..2f8c792d 100644 --- a/test/EntityFramework/FunctionalTests/CodeFirst/DataAnnotationScenarioTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/DataAnnotationScenarioTests.cs @@ -1,984 +1,984 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests -{ - using System; - using System.Collections.Generic; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; - using System.Data.Entity; - using System.Data.Entity.Core.Metadata.Edm; - using System.Linq; - using System.Linq.Expressions; - using FunctionalTests.Model; - using Xunit; - - public sealed class DataAnnotationScenarioTests : TestBase - { - [Fact] - public void Duplicate_column_order_should_not_throw_when_v1_convention_set() - { - var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Duplicate_column_order_should_throw_when_v2_convention_set() - { - var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V5_0); - - modelBuilder.Entity(); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("DuplicateConfiguredColumnOrder", "Entity_10558"); - } - - [Fact] - public void Non_public_annotations_are_enabled() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Property( - PrivateMemberAnnotationClass.PersonFirstNameExpr); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert(PrivateMemberAnnotationClass.PersonFirstNameObjectExpr) - .DbEqual("dsdsd", c => c.Name) - .DbEqual("nvarchar", c => c.TypeName) - .DbEqual(128, f => f.MaxLength) - .DbEqual(true, c => c.IsPrimaryKeyColumn); - } - - [Fact] - public void NotMapped_should_propagate_down_inheritance_hierachy() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("InvalidEntityType", typeof(NotMappedDerived)); - } - - [Fact] - public void NotMapped_on_base_class_property_ignores_it() - { - using (var baseEntityConfiguration = new DynamicTypeDescriptionConfiguration()) - { - var modelBuilder = new DbModelBuilder(); - - baseEntityConfiguration.SetPropertyAttributes(b => b.BaseClassProperty, new NotMappedAttribute()); - baseEntityConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.False( - databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) - .Any(p => p.Name == "BaseClassProperty")); - Assert.False( - databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) - .Any(p => p.Name == "VirtualBaseClassProperty")); - } - } - - [Fact] - public void NotMapped_on_base_class_property_and_overriden_property_ignores_them() - { - using (var baseEntityConfiguration = new DynamicTypeDescriptionConfiguration()) - { - using (var unitConfiguration = new DynamicTypeDescriptionConfiguration()) - { - var modelBuilder = new DbModelBuilder(); - - unitConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); - baseEntityConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.False( - databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) - .Any(p => p.Name == "VirtualBaseClassProperty")); - } - } - } - - [Fact] - public void NotMapped_on_base_class_property_discovered_through_navigation_ignores_it() - { - using (var abstractBaseEntityConfiguration = new DynamicTypeDescriptionConfiguration()) - { - var modelBuilder = new DbModelBuilder(); - - abstractBaseEntityConfiguration.SetPropertyAttributes(b => b.AbstractBaseClassProperty, new NotMappedAttribute()); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.True(databaseMapping.Model.EntityTypes.Any(e => e.Name == "AbstractBaseEntity")); - Assert.False( - databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) - .Any(p => p.Name == "AbstractBaseClassProperty")); - } - } - - [Fact] - public void NotMapped_on_abstract_base_class_property_ignores_it() - { - using (var abstractBaseEntityConfiguration = new DynamicTypeDescriptionConfiguration()) - { - var modelBuilder = new DbModelBuilder(); - - abstractBaseEntityConfiguration.SetPropertyAttributes(b => b.AbstractBaseClassProperty, new NotMappedAttribute()); - - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.False( - databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) - .Any(p => p.Name == "AbstractBaseClassProperty")); - } - } - - [Fact] - public void NotMapped_on_overriden_mapped_base_class_property_throws() - { - using (var unitConfiguration = new DynamicTypeDescriptionConfiguration()) - { - var modelBuilder = new DbModelBuilder(); - - unitConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); - - modelBuilder.Ignore(); - modelBuilder.Entity(); - modelBuilder.Entity(); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage( - "CannotIgnoreMappedBaseProperty", - "VirtualBaseClassProperty", "FunctionalTests.Unit", - "FunctionalTests.BaseEntity"); - } - } - - [Fact] - public void NotMapped_on_unmapped_derived_property_ignores_it() - { - using (var unitConfiguration = new DynamicTypeDescriptionConfiguration()) - { - var modelBuilder = new DbModelBuilder(); - - unitConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); - - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.False( - databaseMapping.Model.EntityTypes.Single().Properties.Any( - p => p.Name == "VirtualBaseClassProperty")); - } - } - - [Fact] - public void NotMapped_on_unmapped_base_class_property_and_overriden_property_ignores_it() - { - using (var unitConfiguration = new DynamicTypeDescriptionConfiguration()) - { - using (var baseEntityConfiguration = new DynamicTypeDescriptionConfiguration()) - { - var modelBuilder = new DbModelBuilder(); - - baseEntityConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); - unitConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); - - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.False( - databaseMapping.Model.EntityTypes.Single().Properties.Any( - p => p.Name == "VirtualBaseClassProperty")); - } - } - } - - [Fact] - public void NotMapped_on_unmapped_base_class_property_ignores_it() - { - using (var baseEntityConfiguration = new DynamicTypeDescriptionConfiguration()) - { - var modelBuilder = new DbModelBuilder(); - - baseEntityConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); - - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.False( - databaseMapping.Model.EntityTypes.Single().Properties.Any( - p => p.Name == "VirtualBaseClassProperty")); - } - } - - [Fact] - public void NotMapped_on_new_property_with_same_name_as_in_unmapped_base_class_ignores_it() - { - using (var differentUnitConfiguration = new DynamicTypeDescriptionConfiguration()) - { - var modelBuilder = new DbModelBuilder(); - - differentUnitConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.False( - databaseMapping.Model.EntityTypes.Single().Properties.Any( - p => p.Name == "VirtualBaseClassProperty")); - } - } - - [Fact] - public void MaxLength_takes_presedence_over_StringLength() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert(x => x.PersonFirstName).FacetEqual(true, a => a.IsMaxLength); - } - - [Fact] - public void MaxLength_with_length_takes_precedence_over_StringLength() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert(x => x.PersonFirstName).FacetEqual( - 30, - a => - a.MaxLength); - } - - [Fact] - public void Default_length_for_key_string_column() - { - using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) - { - loginConfiguration.SetPropertyAttributes(l => l.UserName, new KeyAttribute()); - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Ignore(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert(x => x.UserName) - .DbEqual("nvarchar", c => c.TypeName) - .DbEqual(128, f => f.MaxLength); - } - } - - [Fact] - public void Key_and_column_work_together() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert(x => x.PersonFirstName) - .DbEqual("dsdsd", c => c.Name) - .DbEqual("nvarchar", c => c.TypeName) - .DbEqual(128, f => f.MaxLength) - .DbEqual(true, c => c.IsPrimaryKeyColumn); - } - - [Fact] - // Regression test for Dev11 Bug 87347 - public void Key_and_column_work_together_in_an_IA() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert(x => x.PersonFirstName) - .DbEqual("dsdsd", c => c.Name) - .DbEqual("nvarchar", c => c.TypeName) - .DbEqual(128, f => f.MaxLength) - .DbEqual(true, c => c.IsPrimaryKeyColumn); - - Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); - databaseMapping.Assert().ForeignKeyColumn("Person_PersonFirstName") - .DbEqual("nvarchar", c => c.TypeName) - .DbEqual(128, f => f.MaxLength); - } - - [Fact] - public void Key_column_and_MaxLength_work_together() - { - using (var entityClassConfiguration = new DynamicTypeDescriptionConfiguration()) - { - entityClassConfiguration.SetPropertyAttributes(c => c.PersonFirstName, new MaxLengthAttribute(64)); - - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert(x => x.PersonFirstName) - .DbEqual("dsdsd", c => c.Name) - .DbEqual("nvarchar", c => c.TypeName) - .DbEqual(64, f => f.MaxLength) - .DbEqual(true, c => c.IsPrimaryKeyColumn); - } - } - - [Fact] - public void Key_column_and_MaxLength_work_together_in_an_IA() - { - using (var entityClassConfiguration = new DynamicTypeDescriptionConfiguration()) - { - entityClassConfiguration.SetPropertyAttributes(c => c.PersonFirstName, new MaxLengthAttribute(64)); - - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert(x => x.PersonFirstName) - .DbEqual("dsdsd", c => c.Name) - .DbEqual("nvarchar", c => c.TypeName) - .DbEqual(64, f => f.MaxLength) - .DbEqual(true, c => c.IsPrimaryKeyColumn); - - Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); - databaseMapping.Assert().ForeignKeyColumn("Person_PersonFirstName") - .DbEqual("nvarchar", c => c.TypeName) - .DbEqual(64, f => f.MaxLength); - } - } - - [Fact] - public void Key_from_base_type_is_recognized() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - // one thing configured because of key property - Assert.Equal(1, modelBuilder.ModelConfiguration.Entity(typeof(OKeyBase)).ConfiguredProperties.Count()); - - // should be nothing configured on derived type - Assert.Equal(0, modelBuilder.ModelConfiguration.Entity(typeof(DODerived)).ConfiguredProperties.Count()); - } - - [Fact] - public void Key_on_nav_prop_is_ignored() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert().DbEqual("Id", t => t.DeclaredKeyProperties.Single().Name); - } - - [Fact] - public void Timestamp_takes_precedence_over_MaxLength() - { - var modelBuilder = new DbModelBuilder(); - modelBuilder.Entity().Ignore(x => x.NonMaxTimestamp); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert().DbEqual( - "rowversion", - t => - t.Properties.Single(x => x.Name == "MaxTimestamp"). - TypeName); - - databaseMapping.Assert().DbEqual( - false, - t => - t.Properties.Single(x => x.Name == "MaxTimestamp").IsMaxLength); - - databaseMapping.Assert().DbEqual( - null, - t => - t.Properties.Single(x => x.Name == "MaxTimestamp").MaxLength); - } - - [Fact] - public void Timestamp_takes_precedence_over_MaxLength_with_value() - { - var modelBuilder = new DbModelBuilder(); - modelBuilder.Entity().Ignore(x => x.MaxTimestamp); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert().DbEqual( - "rowversion", - t => - t.Properties.Single(x => x.Name == "NonMaxTimestamp"). - TypeName); - - databaseMapping.Assert().DbEqual( - false, - t => - t.Properties.Single(x => x.Name == "NonMaxTimestamp").IsMaxLength); - - databaseMapping.Assert().DbEqual( - null, - t => - t.Properties.Single(x => x.Name == "NonMaxTimestamp").MaxLength); - } - - [Fact] - public void Annotation_in_derived_class_when_base_class_processed_after_derived_class() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert(s => s.Style).FacetEqual(150, f => f.MaxLength); - } - - [Fact] - public void Required_and_ForeignKey_to_Required() - { - using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) - { - using (var profileConfiguration = new DynamicTypeDescriptionConfiguration()) - { - loginConfiguration.SetPropertyAttributes( - l => l.Profile, new RequiredAttribute(), - new ForeignKeyAttribute("LoginId")); - profileConfiguration.SetPropertyAttributes(p => p.User, new RequiredAttribute()); - - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnableToDeterminePrincipal", typeof(Login), typeof(Profile)); - } - } - } - - [Fact] - // Regression test for Dev11 Bug 94993 - public void Required_to_Required_and_ForeignKey() - { - using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) - { - using (var profileConfiguration = new DynamicTypeDescriptionConfiguration()) - { - loginConfiguration.SetPropertyAttributes(l => l.Profile, new RequiredAttribute()); - profileConfiguration.SetPropertyAttributes( - p => p.User, new RequiredAttribute(), - new ForeignKeyAttribute("ProfileId")); - - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnableToDeterminePrincipal", typeof(Login), typeof(Profile)); - } - } - } - - [Fact] - public void Required_and_ForeignKey_to_Required_and_ForeignKey() - { - using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) - { - using (var profileConfiguration = new DynamicTypeDescriptionConfiguration()) - { - loginConfiguration.SetPropertyAttributes( - l => l.Profile, new RequiredAttribute(), - new ForeignKeyAttribute("LoginId")); - profileConfiguration.SetPropertyAttributes( - p => p.User, new RequiredAttribute(), - new ForeignKeyAttribute("ProfileId")); - - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnableToDeterminePrincipal", typeof(Login), typeof(Profile)); - } - } - } - - [Fact] - public void ForeignKey_to_nothing() - { - using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) - { - using (new DynamicTypeDescriptionConfiguration()) - { - loginConfiguration.SetPropertyAttributes(l => l.Profile, new ForeignKeyAttribute("LoginId")); - - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnableToDeterminePrincipal", typeof(Profile), typeof(Login)); - } - } - } - - [Fact] - public void Required_and_ForeignKey_to_nothing() - { - using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) - { - using (new DynamicTypeDescriptionConfiguration()) - { - loginConfiguration.SetPropertyAttributes(l => l.Profile, new ForeignKeyAttribute("LoginId")); - - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnableToDeterminePrincipal", typeof(Profile), typeof(Login)); - } - } - } - - [Fact] - public void Nothing_to_ForeignKey() - { - using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) - { - using (var profileConfiguration = new DynamicTypeDescriptionConfiguration()) - { - loginConfiguration.SetPropertyAttributes(l => l.Profile); - profileConfiguration.SetPropertyAttributes(p => p.User, new ForeignKeyAttribute("ProfileId")); - - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnableToDeterminePrincipal", typeof(Profile), typeof(Login)); - } - } - } - - [Fact] - public void Nothing_to_Required_and_ForeignKey() - { - using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) - { - using (var profileConfiguration = new DynamicTypeDescriptionConfiguration()) - { - loginConfiguration.SetPropertyAttributes(l => l.Profile); - profileConfiguration.SetPropertyAttributes( - p => p.User, new RequiredAttribute(), - new ForeignKeyAttribute("ProfileId")); - - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - var association = databaseMapping.Model.AssociationTypes.Single(); - Assert.Equal("Profile", association.SourceEnd.GetEntityType().Name); - Assert.Equal(RelationshipMultiplicity.ZeroOrOne, association.SourceEnd.RelationshipMultiplicity); - Assert.Equal("Login", association.TargetEnd.GetEntityType().Name); - Assert.Equal(RelationshipMultiplicity.One, association.TargetEnd.RelationshipMultiplicity); - Assert.Equal("Profile", association.Constraint.ToRole.GetEntityType().Name); - } - } - } - - [Fact] - public void ForeignKey_to_ForeignKey() - { - using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) - { - using (var profileConfiguration = new DynamicTypeDescriptionConfiguration()) - { - loginConfiguration.SetPropertyAttributes(l => l.Profile, new ForeignKeyAttribute("LoginId")); - profileConfiguration.SetPropertyAttributes(p => p.User, new ForeignKeyAttribute("ProfileId")); - - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnableToDeterminePrincipal", typeof(Profile), typeof(Login)); - } - } - } - - [Fact] - public void TableNameAttribute_affects_only_base_in_TPT() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => mc.ToTable("B")); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert("A"); - databaseMapping.Assert("B"); - } - - [Fact] - public void TableNameAttribute_affects_table_name_in_TPH() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map(mc => mc.Requires("disc").HasValue("A")) - .Map(mc => mc.Requires("disc").HasValue("B")); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert("A"); - databaseMapping.AssertMapping("A", false).HasColumnCondition("disc", "A"); - databaseMapping.Assert("A"); - databaseMapping.AssertMapping("A").HasColumnCondition("disc", "B"); - } - } - - #region Fixtures - - public class MaxLengthAnnotationClass - { - public int Id { get; set; } - - [StringLength(500)] - [MaxLength] - public string PersonFirstName { get; set; } - } - - public class MaxLengthWithLengthAnnotationClass - { - public int Id { get; set; } - - [StringLength(500)] - [MaxLength(30)] - public string PersonFirstName { get; set; } - } - - public class ColumnKeyAnnotationClass - { - [Key] - [Column("dsdsd", Order = 1, TypeName = "nvarchar")] - public string PersonFirstName { get; set; } - } - - public class ReferencingClass - { - public int Id { get; set; } - public ColumnKeyAnnotationClass Person { get; set; } - } - - public class DASimple - { - public int Id { get; set; } - } - - public class KeyOnNavProp - { - public int Id { get; set; } - - [Key] - public ICollection Simples { get; set; } - - [Key] - public DASimple SpecialSimple { get; set; } - } - - public class SRelated - { - public int SRelatedId { get; set; } - public ICollection DADeriveds { get; set; } - } - - public class OKeyBase - { - [Key] - public int OrderLineNo { get; set; } - - public int Quantity { get; set; } - } - - public class DODerived : OKeyBase - { - public SRelated DARelated { get; set; } - public string Special { get; set; } - } - - public class TimestampAndMaxlen - { - public int Id { get; set; } - - [MaxLength] - [Timestamp] - public byte[] MaxTimestamp { get; set; } - - [MaxLength(100)] - [Timestamp] - public byte[] NonMaxTimestamp { get; set; } - } - - public class Login - { - public int LoginId { get; set; } - public string UserName { get; set; } - public virtual Profile Profile { get; set; } - } - - public class Profile - { - public int ProfileId { get; set; } - public string Name { get; set; } - public string Email { get; set; } - public virtual Login User { get; set; } - } - - [Table("A")] - public class TNAttrBase - { - public int Id { get; set; } - public string BaseData { get; set; } - } - - public class TNAttrDerived : TNAttrBase - { - public string DerivedData { get; set; } - } - - [NotMapped] - public class NotMappedBase - { - public int Id { get; set; } - } - - public class NotMappedDerived : NotMappedBase - { - } - - public class PrivateMemberAnnotationClass - { - public static Expression> PersonFirstNameExpr = - p => p.PersonFirstName; - - public static Expression> PersonFirstNameObjectExpr = - p => p.PersonFirstName; - - [Key] - [Column("dsdsd", Order = 1, TypeName = "nvarchar")] - private string PersonFirstName { get; set; } - } - - public class Entity_10558 - { - [Key] - [Column(Order = 1)] - public int Key1 { get; set; } - - [Key] - [Column(Order = 1)] - public int Key2 { get; set; } - - public string Name { get; set; } - } - - #endregion - - #region Bug324763 - - namespace Bug324763 - { - using System.Data.Entity.ModelConfiguration.Conventions; - - public class Product - { - [Timestamp] - public byte[] Version { get; set; } - - [Key] - [Column(Order = 0)] - public int ProductId { get; set; } - - [Key] - [Column(Order = 1)] - [MaxLength(128)] - public string Sku { get; set; } - - [Required] - [StringLength(15)] - public string Name { get; set; } - - public byte[] Image { get; set; } - - [InverseProperty("Product")] - public ICollection OrderLines { get; set; } - } - - public class OrderLine - { - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] - public int Id { get; set; } - - public int OrderId { get; set; } - - [NotMapped] - public short Quantity { get; set; } - - public decimal Price { get; set; } - public decimal Total { get; set; } - public bool? IsShipped { get; set; } - - [ForeignKey("Product")] - [Column(Order = 0)] - public int ProductIdFk { get; set; } - - [ForeignKey("Product")] - [Column(Order = 1)] - public string ProductSkuFk { get; set; } - - [MaxLength(128)] - public string Sku { get; set; } - - [ConcurrencyCheck] - public int EngineSupplierId { get; set; } - - public Product Product { get; set; } - } - - public class Test324763 : FunctionalTestBase - { - [Fact] - public void Repro324763_Build_Is_Not_Idempotent() - { - var modelBuilder = new DbModelBuilder(); - modelBuilder.Entity(); - modelBuilder.Entity(); - - ValidateBuildIsIdempotent(modelBuilder); - } - - private void ValidateBuildIsIdempotent(DbModelBuilder modelBuilder) - { - var mapping1 = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; - var mapping2 = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; - Assert.True(mapping1.EdmxIsEqualTo(mapping2)); - } - - [Fact] - public void Repro324763_Build_Is_Not_Idempotent_Inverse() - { - var modelBuilder = new DbModelBuilder(); - modelBuilder.Conventions.Remove(); - modelBuilder.Entity(); - modelBuilder.Entity(); - - ValidateBuildIsIdempotent(modelBuilder); - } - } - } - - #endregion -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests +{ + using System; + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + using System.ComponentModel.DataAnnotations.Schema; + using System.Data.Entity; + using System.Data.Entity.Core.Metadata.Edm; + using System.Linq; + using System.Linq.Expressions; + using FunctionalTests.Model; + using Xunit; + + public sealed class DataAnnotationScenarioTests : TestBase + { + [Fact] + public void Duplicate_column_order_should_not_throw_when_v1_convention_set() + { + var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Duplicate_column_order_should_throw_when_v2_convention_set() + { + var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V5_0); + + modelBuilder.Entity(); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("DuplicateConfiguredColumnOrder", "Entity_10558"); + } + + [Fact] + public void Non_public_annotations_are_enabled() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Property( + PrivateMemberAnnotationClass.PersonFirstNameExpr); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert(PrivateMemberAnnotationClass.PersonFirstNameObjectExpr) + .DbEqual("dsdsd", c => c.Name) + .DbEqual("nvarchar", c => c.TypeName) + .DbEqual(128, f => f.MaxLength) + .DbEqual(true, c => c.IsPrimaryKeyColumn); + } + + [Fact] + public void NotMapped_should_propagate_down_inheritance_hierachy() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("InvalidEntityType", typeof(NotMappedDerived)); + } + + [Fact] + public void NotMapped_on_base_class_property_ignores_it() + { + using (var baseEntityConfiguration = new DynamicTypeDescriptionConfiguration()) + { + var modelBuilder = new DbModelBuilder(); + + baseEntityConfiguration.SetPropertyAttributes(b => b.BaseClassProperty, new NotMappedAttribute()); + baseEntityConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.False( + databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) + .Any(p => p.Name == "BaseClassProperty")); + Assert.False( + databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) + .Any(p => p.Name == "VirtualBaseClassProperty")); + } + } + + [Fact] + public void NotMapped_on_base_class_property_and_overriden_property_ignores_them() + { + using (var baseEntityConfiguration = new DynamicTypeDescriptionConfiguration()) + { + using (var unitConfiguration = new DynamicTypeDescriptionConfiguration()) + { + var modelBuilder = new DbModelBuilder(); + + unitConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); + baseEntityConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.False( + databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) + .Any(p => p.Name == "VirtualBaseClassProperty")); + } + } + } + + [Fact] + public void NotMapped_on_base_class_property_discovered_through_navigation_ignores_it() + { + using (var abstractBaseEntityConfiguration = new DynamicTypeDescriptionConfiguration()) + { + var modelBuilder = new DbModelBuilder(); + + abstractBaseEntityConfiguration.SetPropertyAttributes(b => b.AbstractBaseClassProperty, new NotMappedAttribute()); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.True(databaseMapping.Model.EntityTypes.Any(e => e.Name == "AbstractBaseEntity")); + Assert.False( + databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) + .Any(p => p.Name == "AbstractBaseClassProperty")); + } + } + + [Fact] + public void NotMapped_on_abstract_base_class_property_ignores_it() + { + using (var abstractBaseEntityConfiguration = new DynamicTypeDescriptionConfiguration()) + { + var modelBuilder = new DbModelBuilder(); + + abstractBaseEntityConfiguration.SetPropertyAttributes(b => b.AbstractBaseClassProperty, new NotMappedAttribute()); + + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.False( + databaseMapping.Model.EntityTypes.SelectMany(e => e.Properties) + .Any(p => p.Name == "AbstractBaseClassProperty")); + } + } + + [Fact] + public void NotMapped_on_overriden_mapped_base_class_property_throws() + { + using (var unitConfiguration = new DynamicTypeDescriptionConfiguration()) + { + var modelBuilder = new DbModelBuilder(); + + unitConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); + + modelBuilder.Ignore(); + modelBuilder.Entity(); + modelBuilder.Entity(); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage( + "CannotIgnoreMappedBaseProperty", + "VirtualBaseClassProperty", "FunctionalTests.Unit", + "FunctionalTests.BaseEntity"); + } + } + + [Fact] + public void NotMapped_on_unmapped_derived_property_ignores_it() + { + using (var unitConfiguration = new DynamicTypeDescriptionConfiguration()) + { + var modelBuilder = new DbModelBuilder(); + + unitConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); + + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.False( + databaseMapping.Model.EntityTypes.Single().Properties.Any( + p => p.Name == "VirtualBaseClassProperty")); + } + } + + [Fact] + public void NotMapped_on_unmapped_base_class_property_and_overriden_property_ignores_it() + { + using (var unitConfiguration = new DynamicTypeDescriptionConfiguration()) + { + using (var baseEntityConfiguration = new DynamicTypeDescriptionConfiguration()) + { + var modelBuilder = new DbModelBuilder(); + + baseEntityConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); + unitConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); + + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.False( + databaseMapping.Model.EntityTypes.Single().Properties.Any( + p => p.Name == "VirtualBaseClassProperty")); + } + } + } + + [Fact] + public void NotMapped_on_unmapped_base_class_property_ignores_it() + { + using (var baseEntityConfiguration = new DynamicTypeDescriptionConfiguration()) + { + var modelBuilder = new DbModelBuilder(); + + baseEntityConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); + + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.False( + databaseMapping.Model.EntityTypes.Single().Properties.Any( + p => p.Name == "VirtualBaseClassProperty")); + } + } + + [Fact] + public void NotMapped_on_new_property_with_same_name_as_in_unmapped_base_class_ignores_it() + { + using (var differentUnitConfiguration = new DynamicTypeDescriptionConfiguration()) + { + var modelBuilder = new DbModelBuilder(); + + differentUnitConfiguration.SetPropertyAttributes(b => b.VirtualBaseClassProperty, new NotMappedAttribute()); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.False( + databaseMapping.Model.EntityTypes.Single().Properties.Any( + p => p.Name == "VirtualBaseClassProperty")); + } + } + + [Fact] + public void MaxLength_takes_presedence_over_StringLength() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert(x => x.PersonFirstName).FacetEqual(true, a => a.IsMaxLength); + } + + [Fact] + public void MaxLength_with_length_takes_precedence_over_StringLength() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert(x => x.PersonFirstName).FacetEqual( + 30, + a => + a.MaxLength); + } + + [Fact] + public void Default_length_for_key_string_column() + { + using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) + { + loginConfiguration.SetPropertyAttributes(l => l.UserName, new KeyAttribute()); + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Ignore(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert(x => x.UserName) + .DbEqual("nvarchar", c => c.TypeName) + .DbEqual(128, f => f.MaxLength); + } + } + + [Fact] + public void Key_and_column_work_together() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert(x => x.PersonFirstName) + .DbEqual("dsdsd", c => c.Name) + .DbEqual("nvarchar", c => c.TypeName) + .DbEqual(128, f => f.MaxLength) + .DbEqual(true, c => c.IsPrimaryKeyColumn); + } + + [Fact] + // Regression test for Dev11 Bug 87347 + public void Key_and_column_work_together_in_an_IA() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert(x => x.PersonFirstName) + .DbEqual("dsdsd", c => c.Name) + .DbEqual("nvarchar", c => c.TypeName) + .DbEqual(128, f => f.MaxLength) + .DbEqual(true, c => c.IsPrimaryKeyColumn); + + Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); + databaseMapping.Assert().ForeignKeyColumn("Person_PersonFirstName") + .DbEqual("nvarchar", c => c.TypeName) + .DbEqual(128, f => f.MaxLength); + } + + [Fact] + public void Key_column_and_MaxLength_work_together() + { + using (var entityClassConfiguration = new DynamicTypeDescriptionConfiguration()) + { + entityClassConfiguration.SetPropertyAttributes(c => c.PersonFirstName, new MaxLengthAttribute(64)); + + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert(x => x.PersonFirstName) + .DbEqual("dsdsd", c => c.Name) + .DbEqual("nvarchar", c => c.TypeName) + .DbEqual(64, f => f.MaxLength) + .DbEqual(true, c => c.IsPrimaryKeyColumn); + } + } + + [Fact] + public void Key_column_and_MaxLength_work_together_in_an_IA() + { + using (var entityClassConfiguration = new DynamicTypeDescriptionConfiguration()) + { + entityClassConfiguration.SetPropertyAttributes(c => c.PersonFirstName, new MaxLengthAttribute(64)); + + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert(x => x.PersonFirstName) + .DbEqual("dsdsd", c => c.Name) + .DbEqual("nvarchar", c => c.TypeName) + .DbEqual(64, f => f.MaxLength) + .DbEqual(true, c => c.IsPrimaryKeyColumn); + + Assert.Equal(1, databaseMapping.Model.AssociationTypes.Count()); + databaseMapping.Assert().ForeignKeyColumn("Person_PersonFirstName") + .DbEqual("nvarchar", c => c.TypeName) + .DbEqual(64, f => f.MaxLength); + } + } + + [Fact] + public void Key_from_base_type_is_recognized() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + // one thing configured because of key property + Assert.Equal(1, modelBuilder.ModelConfiguration.Entity(typeof(OKeyBase)).ConfiguredProperties.Count()); + + // should be nothing configured on derived type + Assert.Equal(0, modelBuilder.ModelConfiguration.Entity(typeof(DODerived)).ConfiguredProperties.Count()); + } + + [Fact] + public void Key_on_nav_prop_is_ignored() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert().DbEqual("Id", t => t.DeclaredKeyProperties.Single().Name); + } + + [Fact] + public void Timestamp_takes_precedence_over_MaxLength() + { + var modelBuilder = new DbModelBuilder(); + modelBuilder.Entity().Ignore(x => x.NonMaxTimestamp); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert().DbEqual( + "rowversion", + t => + t.Properties.Single(x => x.Name == "MaxTimestamp"). + TypeName); + + databaseMapping.Assert().DbEqual( + false, + t => + t.Properties.Single(x => x.Name == "MaxTimestamp").IsMaxLength); + + databaseMapping.Assert().DbEqual( + null, + t => + t.Properties.Single(x => x.Name == "MaxTimestamp").MaxLength); + } + + [Fact] + public void Timestamp_takes_precedence_over_MaxLength_with_value() + { + var modelBuilder = new DbModelBuilder(); + modelBuilder.Entity().Ignore(x => x.MaxTimestamp); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert().DbEqual( + "rowversion", + t => + t.Properties.Single(x => x.Name == "NonMaxTimestamp"). + TypeName); + + databaseMapping.Assert().DbEqual( + false, + t => + t.Properties.Single(x => x.Name == "NonMaxTimestamp").IsMaxLength); + + databaseMapping.Assert().DbEqual( + null, + t => + t.Properties.Single(x => x.Name == "NonMaxTimestamp").MaxLength); + } + + [Fact] + public void Annotation_in_derived_class_when_base_class_processed_after_derived_class() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert(s => s.Style).FacetEqual(150, f => f.MaxLength); + } + + [Fact] + public void Required_and_ForeignKey_to_Required() + { + using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) + { + using (var profileConfiguration = new DynamicTypeDescriptionConfiguration()) + { + loginConfiguration.SetPropertyAttributes( + l => l.Profile, new RequiredAttribute(), + new ForeignKeyAttribute("LoginId")); + profileConfiguration.SetPropertyAttributes(p => p.User, new RequiredAttribute()); + + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnableToDeterminePrincipal", typeof(Login), typeof(Profile)); + } + } + } + + [Fact] + // Regression test for Dev11 Bug 94993 + public void Required_to_Required_and_ForeignKey() + { + using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) + { + using (var profileConfiguration = new DynamicTypeDescriptionConfiguration()) + { + loginConfiguration.SetPropertyAttributes(l => l.Profile, new RequiredAttribute()); + profileConfiguration.SetPropertyAttributes( + p => p.User, new RequiredAttribute(), + new ForeignKeyAttribute("ProfileId")); + + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnableToDeterminePrincipal", typeof(Login), typeof(Profile)); + } + } + } + + [Fact] + public void Required_and_ForeignKey_to_Required_and_ForeignKey() + { + using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) + { + using (var profileConfiguration = new DynamicTypeDescriptionConfiguration()) + { + loginConfiguration.SetPropertyAttributes( + l => l.Profile, new RequiredAttribute(), + new ForeignKeyAttribute("LoginId")); + profileConfiguration.SetPropertyAttributes( + p => p.User, new RequiredAttribute(), + new ForeignKeyAttribute("ProfileId")); + + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnableToDeterminePrincipal", typeof(Login), typeof(Profile)); + } + } + } + + [Fact] + public void ForeignKey_to_nothing() + { + using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) + { + using (new DynamicTypeDescriptionConfiguration()) + { + loginConfiguration.SetPropertyAttributes(l => l.Profile, new ForeignKeyAttribute("LoginId")); + + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnableToDeterminePrincipal", typeof(Profile), typeof(Login)); + } + } + } + + [Fact] + public void Required_and_ForeignKey_to_nothing() + { + using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) + { + using (new DynamicTypeDescriptionConfiguration()) + { + loginConfiguration.SetPropertyAttributes(l => l.Profile, new ForeignKeyAttribute("LoginId")); + + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnableToDeterminePrincipal", typeof(Profile), typeof(Login)); + } + } + } + + [Fact] + public void Nothing_to_ForeignKey() + { + using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) + { + using (var profileConfiguration = new DynamicTypeDescriptionConfiguration()) + { + loginConfiguration.SetPropertyAttributes(l => l.Profile); + profileConfiguration.SetPropertyAttributes(p => p.User, new ForeignKeyAttribute("ProfileId")); + + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnableToDeterminePrincipal", typeof(Profile), typeof(Login)); + } + } + } + + [Fact] + public void Nothing_to_Required_and_ForeignKey() + { + using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) + { + using (var profileConfiguration = new DynamicTypeDescriptionConfiguration()) + { + loginConfiguration.SetPropertyAttributes(l => l.Profile); + profileConfiguration.SetPropertyAttributes( + p => p.User, new RequiredAttribute(), + new ForeignKeyAttribute("ProfileId")); + + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + var association = databaseMapping.Model.AssociationTypes.Single(); + Assert.Equal("Profile", association.SourceEnd.GetEntityType().Name); + Assert.Equal(RelationshipMultiplicity.ZeroOrOne, association.SourceEnd.RelationshipMultiplicity); + Assert.Equal("Login", association.TargetEnd.GetEntityType().Name); + Assert.Equal(RelationshipMultiplicity.One, association.TargetEnd.RelationshipMultiplicity); + Assert.Equal("Profile", association.Constraint.ToRole.GetEntityType().Name); + } + } + } + + [Fact] + public void ForeignKey_to_ForeignKey() + { + using (var loginConfiguration = new DynamicTypeDescriptionConfiguration()) + { + using (var profileConfiguration = new DynamicTypeDescriptionConfiguration()) + { + loginConfiguration.SetPropertyAttributes(l => l.Profile, new ForeignKeyAttribute("LoginId")); + profileConfiguration.SetPropertyAttributes(p => p.User, new ForeignKeyAttribute("ProfileId")); + + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnableToDeterminePrincipal", typeof(Profile), typeof(Login)); + } + } + } + + [Fact] + public void TableNameAttribute_affects_only_base_in_TPT() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => mc.ToTable("B")); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert("A"); + databaseMapping.Assert("B"); + } + + [Fact] + public void TableNameAttribute_affects_table_name_in_TPH() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map(mc => mc.Requires("disc").HasValue("A")) + .Map(mc => mc.Requires("disc").HasValue("B")); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert("A"); + databaseMapping.AssertMapping("A", false).HasColumnCondition("disc", "A"); + databaseMapping.Assert("A"); + databaseMapping.AssertMapping("A").HasColumnCondition("disc", "B"); + } + } + + #region Fixtures + + public class MaxLengthAnnotationClass + { + public int Id { get; set; } + + [StringLength(500)] + [MaxLength] + public string PersonFirstName { get; set; } + } + + public class MaxLengthWithLengthAnnotationClass + { + public int Id { get; set; } + + [StringLength(500)] + [MaxLength(30)] + public string PersonFirstName { get; set; } + } + + public class ColumnKeyAnnotationClass + { + [Key] + [Column("dsdsd", Order = 1, TypeName = "nvarchar")] + public string PersonFirstName { get; set; } + } + + public class ReferencingClass + { + public int Id { get; set; } + public ColumnKeyAnnotationClass Person { get; set; } + } + + public class DASimple + { + public int Id { get; set; } + } + + public class KeyOnNavProp + { + public int Id { get; set; } + + [Key] + public ICollection Simples { get; set; } + + [Key] + public DASimple SpecialSimple { get; set; } + } + + public class SRelated + { + public int SRelatedId { get; set; } + public ICollection DADeriveds { get; set; } + } + + public class OKeyBase + { + [Key] + public int OrderLineNo { get; set; } + + public int Quantity { get; set; } + } + + public class DODerived : OKeyBase + { + public SRelated DARelated { get; set; } + public string Special { get; set; } + } + + public class TimestampAndMaxlen + { + public int Id { get; set; } + + [MaxLength] + [Timestamp] + public byte[] MaxTimestamp { get; set; } + + [MaxLength(100)] + [Timestamp] + public byte[] NonMaxTimestamp { get; set; } + } + + public class Login + { + public int LoginId { get; set; } + public string UserName { get; set; } + public virtual Profile Profile { get; set; } + } + + public class Profile + { + public int ProfileId { get; set; } + public string Name { get; set; } + public string Email { get; set; } + public virtual Login User { get; set; } + } + + [Table("A")] + public class TNAttrBase + { + public int Id { get; set; } + public string BaseData { get; set; } + } + + public class TNAttrDerived : TNAttrBase + { + public string DerivedData { get; set; } + } + + [NotMapped] + public class NotMappedBase + { + public int Id { get; set; } + } + + public class NotMappedDerived : NotMappedBase + { + } + + public class PrivateMemberAnnotationClass + { + public static Expression> PersonFirstNameExpr = + p => p.PersonFirstName; + + public static Expression> PersonFirstNameObjectExpr = + p => p.PersonFirstName; + + [Key] + [Column("dsdsd", Order = 1, TypeName = "nvarchar")] + private string PersonFirstName { get; set; } + } + + public class Entity_10558 + { + [Key] + [Column(Order = 1)] + public int Key1 { get; set; } + + [Key] + [Column(Order = 1)] + public int Key2 { get; set; } + + public string Name { get; set; } + } + + #endregion + + #region Bug324763 + + namespace Bug324763 + { + using System.Data.Entity.ModelConfiguration.Conventions; + + public class Product + { + [Timestamp] + public byte[] Version { get; set; } + + [Key] + [Column(Order = 0)] + public int ProductId { get; set; } + + [Key] + [Column(Order = 1)] + [MaxLength(128)] + public string Sku { get; set; } + + [Required] + [StringLength(15)] + public string Name { get; set; } + + public byte[] Image { get; set; } + + [InverseProperty("Product")] + public ICollection OrderLines { get; set; } + } + + public class OrderLine + { + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + + public int OrderId { get; set; } + + [NotMapped] + public short Quantity { get; set; } + + public decimal Price { get; set; } + public decimal Total { get; set; } + public bool? IsShipped { get; set; } + + [ForeignKey("Product")] + [Column(Order = 0)] + public int ProductIdFk { get; set; } + + [ForeignKey("Product")] + [Column(Order = 1)] + public string ProductSkuFk { get; set; } + + [MaxLength(128)] + public string Sku { get; set; } + + [ConcurrencyCheck] + public int EngineSupplierId { get; set; } + + public Product Product { get; set; } + } + + public class Test324763 : FunctionalTestBase + { + [Fact] + public void Repro324763_Build_Is_Not_Idempotent() + { + var modelBuilder = new DbModelBuilder(); + modelBuilder.Entity(); + modelBuilder.Entity(); + + ValidateBuildIsIdempotent(modelBuilder); + } + + private void ValidateBuildIsIdempotent(DbModelBuilder modelBuilder) + { + var mapping1 = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; + var mapping2 = modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; + Assert.True(mapping1.EdmxIsEqualTo(mapping2)); + } + + [Fact] + public void Repro324763_Build_Is_Not_Idempotent_Inverse() + { + var modelBuilder = new DbModelBuilder(); + modelBuilder.Conventions.Remove(); + modelBuilder.Entity(); + modelBuilder.Entity(); + + ValidateBuildIsIdempotent(modelBuilder); + } + } + } + + #endregion +} diff --git a/test/EntityFramework/FunctionalTests/CodeFirst/DataServicesTests.cs b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/DataServicesTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/CodeFirst/DataServicesTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/CodeFirst/DataServicesTests.cs index d4da8f9a..552daa8c 100644 --- a/test/EntityFramework/FunctionalTests/CodeFirst/DataServicesTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/DataServicesTests.cs @@ -1,66 +1,66 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests -{ - using System.Data.Entity; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.Infrastructure; - using System.Data.Entity.ModelConfiguration.Edm; - using System.Data.Services; - using System.Data.Services.Common; - using Xunit; - - public sealed class DataServicesTests : TestBase - { - [Fact] - public void Validate_Basic_DataServices_Attributes() - { - var modelBuilder = new DataServicesModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - var mws = databaseMapping.ToMetadataWorkspace(); - - var edmCollection = mws.GetItemCollection(DataSpace.CSpace); - edmCollection.GetItem("CodeFirstNamespace.DataServiceFoo"); - } - } - - public sealed class DataServicesModelBuilder : DbModelBuilder - { - internal DbDatabaseMapping BuildAndValidate(DbProviderInfo providerInfo) - { - var databaseMapping = base.Build(providerInfo).DatabaseMapping; - - databaseMapping.AssertValid(); - - return databaseMapping; - } - } - - [MimeType("MimeProp", "text/plain")] - [HasStream] - //[EntityPropertyMappingAttribute("OtherProp", SyndicationItemProperty.AuthorName, true, "critVal")] - [EntityPropertyMapping("OtherProp", SyndicationItemProperty.AuthorName, - SyndicationTextContentKind.Plaintext, true)] - [EntityPropertyMapping("OtherProp", "targetPath3", "prefix3", "http://my.org/", true)] - [EntityPropertyMapping("Inner/Data", SyndicationItemProperty.AuthorName, - SyndicationTextContentKind.Plaintext, true)] - public class DataServiceFoo - { - public int Id { get; set; } - - public string MimeProp { get; set; } - - public string OtherProp { get; set; } - - public Inner Inner { get; set; } - } - - public class Inner - { - public string Data { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests +{ + using System.Data.Entity; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.Infrastructure; + using System.Data.Entity.ModelConfiguration.Edm; + using System.Data.Services; + using System.Data.Services.Common; + using Xunit; + + public sealed class DataServicesTests : TestBase + { + [Fact] + public void Validate_Basic_DataServices_Attributes() + { + var modelBuilder = new DataServicesModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + var mws = databaseMapping.ToMetadataWorkspace(); + + var edmCollection = mws.GetItemCollection(DataSpace.CSpace); + edmCollection.GetItem("CodeFirstNamespace.DataServiceFoo"); + } + } + + public sealed class DataServicesModelBuilder : DbModelBuilder + { + internal DbDatabaseMapping BuildAndValidate(DbProviderInfo providerInfo) + { + var databaseMapping = base.Build(providerInfo).DatabaseMapping; + + databaseMapping.AssertValid(); + + return databaseMapping; + } + } + + [MimeType("MimeProp", "text/plain")] + [HasStream] + //[EntityPropertyMappingAttribute("OtherProp", SyndicationItemProperty.AuthorName, true, "critVal")] + [EntityPropertyMapping("OtherProp", SyndicationItemProperty.AuthorName, + SyndicationTextContentKind.Plaintext, true)] + [EntityPropertyMapping("OtherProp", "targetPath3", "prefix3", "http://my.org/", true)] + [EntityPropertyMapping("Inner/Data", SyndicationItemProperty.AuthorName, + SyndicationTextContentKind.Plaintext, true)] + public class DataServiceFoo + { + public int Id { get; set; } + + public string MimeProp { get; set; } + + public string OtherProp { get; set; } + + public Inner Inner { get; set; } + } + + public class Inner + { + public string Data { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/CodeFirst/EnumsScenarioTests.cs b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/EnumsScenarioTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/CodeFirst/EnumsScenarioTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/CodeFirst/EnumsScenarioTests.cs index 7423fa4b..eeac349e 100644 --- a/test/EntityFramework/FunctionalTests/CodeFirst/EnumsScenarioTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/EnumsScenarioTests.cs @@ -1,362 +1,362 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests -{ - using System; - using System.Data.Entity; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.ModelConfiguration.Edm; - using System.Linq; - using FunctionalTests.Fixtures; - using Xunit; - - public sealed class EnumsScenarioTests : TestBase - { - [Fact] - public void Simple_enum_mapping_scenario() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(p => p.CategoryId).IsTrue(t => t.IsEnumType); - databaseMapping.Assert().HasColumn("CategoryId"); - - var enumType = databaseMapping.Model.GetEnumType("CategoryId"); - - Assert.NotNull(enumType); - Assert.Equal(7, enumType.Members.Count); - Assert.False(enumType.IsFlags); - Assert.Equal(PrimitiveTypeKind.Int32, enumType.UnderlyingType.PrimitiveTypeKind); - } - - [Fact] - public void Short_enum_mapping_with_flags_attribute() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - var enumType = databaseMapping.Model.GetEnumType("WithFlags"); - - Assert.NotNull(enumType); - Assert.Equal(4, enumType.Members.Count); - Assert.True(enumType.IsFlags); - Assert.Equal(PrimitiveTypeKind.Int16, enumType.UnderlyingType.PrimitiveTypeKind); - } - - [Fact] - public void Build_model_for_a_single_type_with_a_enum_key() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Enum_mapped_as_by_convention_fk_in_association() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasForeignKeyColumn("CategoryId"); - } - - [Fact] - public void Enum_mapped_as_by_convention_IA_in_association() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert().HasForeignKeyColumn("Principal_Id"); - } - - [Fact] - public void Annotated_nullable_enum_inside_complex_type_is_mapped() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(c => c.Enum).IsTrue(t => t.IsEnumType); - databaseMapping.Assert(c => c.Enum).IsTrue(t => t.Nullable); - databaseMapping.Assert(c => c.Enum).DbEqual("col_enum", c => c.Name); - } - - [Fact] - public void Fluent_api_configured_enum_property_gets_correct_facets() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Property(p => p.CategoryId).IsOptional(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(p => p.CategoryId).IsTrue(p => p.Nullable); - } - - [Fact] - public void Should_be_able_to_use_v4_1_model_builder_without_enums() - { - var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - Assert.Equal(2.0, databaseMapping.Model.Version); - Assert.Equal(2.0, databaseMapping.Database.Version); - } - - [Fact] - public void Empty_enum_in_model_does_not_fail_validation() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - databaseMapping.Assert(p => p.Empty).IsFalse(e => e.EnumType.Members.Any()); - } - - [Fact] - public void Unsigned_enum_in_model_should_fail_validation() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - } - - [Fact] - public void Explicitly_mapping_an_enum_property_using_4_1_throws() - { - var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); - - modelBuilder.Entity().Property(e => e.CategoryId); - - Assert.Throws( - () => - modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnsupportedUseOfV3Type", "Enum_Product", "CategoryId"); - } - - [Fact] - public void Explicitly_mapping_a_nullable_enum_property_using_4_1_throws() - { - var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); - - modelBuilder.Entity().Property(e => e.CategoryId); - - Assert.Throws( - () => - modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnsupportedUseOfV3Type", "Enum_Nullable", "CategoryId"); - } - - [Fact] - public void Explicitly_mapping_an_enum_property_on_a_complex_type_using_4_1_throws() - { - var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); - - modelBuilder.ComplexType().Property(c => c.Enum); - - Assert.Throws( - () => - modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnsupportedUseOfV3Type", "Enum_ComplexType", "Enum"); - } - - [Fact] - public void Explicitly_using_an_enum_property_as_a_key_with_4_1_throws() - { - var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); - - modelBuilder.Entity().HasKey(e => e.CategoryId); - - Assert.Throws( - () => - modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnsupportedUseOfV3Type", "Enum_Product", "CategoryId"); - } - - [Fact] - public void Explicitly_using_an_enum_property_as_part_of_a_composite_key_with_4_1_throws() - { - var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); - - modelBuilder.Entity().HasKey( - e => new - { - e.Id, - e.CategoryId - }); - - Assert.Throws( - () => - modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("UnsupportedUseOfV3Type", "Enum_Product", "CategoryId"); - } - - [Fact] - public void Explicitly_mapping_an_enum_property_with_Map_using_4_1_throws() - { - var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); - - modelBuilder.Entity().Map( - mapping => - { - mapping.ToTable("Table1"); - mapping.Properties(e => e.CategoryId); - }); - - Assert.Throws( - () => - modelBuilder.Build( - ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("EntityMappingConfiguration_CannotMapIgnoredProperty", "Enum_Product", "CategoryId"); - } - } - - namespace Fixtures - { - using System.Collections.Generic; - using System.ComponentModel.DataAnnotations.Schema; - - public enum CategoryId - { - Beverages = 1, - Condiments, - Confections, - Dairy_Products, - Grains_Cereals, - Meat_Poultry, - Produce - } - - public enum Empty - { - } - - public class Enum_Empty - { - public int Id { get; set; } - public Empty Empty { get; set; } - } - - public enum Unsigned : uint - { - Member - } - - public class Enum_Unsigned - { - public int Id { get; set; } - public Unsigned Unsigned { get; set; } - } - - public class Enum_Product - { - public int Id { get; set; } - public string ProductName { get; set; } - public decimal UnitPrice { get; set; } - public short UnitsInStock { get; set; } - public CategoryId CategoryId { get; set; } - } - - public class Enum_Nullable - { - public int Id { get; set; } - public CategoryId? CategoryId { get; set; } - } - - [Flags] - public enum WithFlags : short - { - Beverages = 0, - Condiments = 1, - Confections = 2, - Dairy_Products = 4 - } - - public class Enum_Flags - { - public int Id { get; set; } - public WithFlags FlagsEnum { get; set; } - } - - public class Enum_Product_PK - { - public CategoryId Id { get; set; } - public string ProductName { get; set; } - public decimal UnitPrice { get; set; } - public short UnitsInStock { get; set; } - } - - public class Enum_Fk_Product - { - public int Id { get; set; } - public CategoryId CategoryId { get; set; } - public Enum_Fk_Category Category { get; set; } - } - - public class Enum_Fk_Category - { - public CategoryId Id { get; set; } - public ICollection Products { get; set; } - } - - public class Enum_IA_Principal - { - public CategoryId Id { get; set; } - public ICollection Dependents { get; set; } - } - - public class Enum_IA_Dependent - { - public int Id { get; set; } - public Enum_IA_Principal Principal { get; set; } - } - - public class Enum_ComplexEntity - { - public int Id { get; set; } - public Enum_ComplexType ComplexType { get; set; } - } - - [ComplexType] - public class Enum_ComplexType - { - [Column("col_enum")] - public WithFlags? Enum { get; set; } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests +{ + using System; + using System.Data.Entity; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.ModelConfiguration.Edm; + using System.Linq; + using FunctionalTests.Fixtures; + using Xunit; + + public sealed class EnumsScenarioTests : TestBase + { + [Fact] + public void Simple_enum_mapping_scenario() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(p => p.CategoryId).IsTrue(t => t.IsEnumType); + databaseMapping.Assert().HasColumn("CategoryId"); + + var enumType = databaseMapping.Model.GetEnumType("CategoryId"); + + Assert.NotNull(enumType); + Assert.Equal(7, enumType.Members.Count); + Assert.False(enumType.IsFlags); + Assert.Equal(PrimitiveTypeKind.Int32, enumType.UnderlyingType.PrimitiveTypeKind); + } + + [Fact] + public void Short_enum_mapping_with_flags_attribute() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + var enumType = databaseMapping.Model.GetEnumType("WithFlags"); + + Assert.NotNull(enumType); + Assert.Equal(4, enumType.Members.Count); + Assert.True(enumType.IsFlags); + Assert.Equal(PrimitiveTypeKind.Int16, enumType.UnderlyingType.PrimitiveTypeKind); + } + + [Fact] + public void Build_model_for_a_single_type_with_a_enum_key() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Enum_mapped_as_by_convention_fk_in_association() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasForeignKeyColumn("CategoryId"); + } + + [Fact] + public void Enum_mapped_as_by_convention_IA_in_association() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert().HasForeignKeyColumn("Principal_Id"); + } + + [Fact] + public void Annotated_nullable_enum_inside_complex_type_is_mapped() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(c => c.Enum).IsTrue(t => t.IsEnumType); + databaseMapping.Assert(c => c.Enum).IsTrue(t => t.Nullable); + databaseMapping.Assert(c => c.Enum).DbEqual("col_enum", c => c.Name); + } + + [Fact] + public void Fluent_api_configured_enum_property_gets_correct_facets() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Property(p => p.CategoryId).IsOptional(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(p => p.CategoryId).IsTrue(p => p.Nullable); + } + + [Fact] + public void Should_be_able_to_use_v4_1_model_builder_without_enums() + { + var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + Assert.Equal(2.0, databaseMapping.Model.Version); + Assert.Equal(2.0, databaseMapping.Database.Version); + } + + [Fact] + public void Empty_enum_in_model_does_not_fail_validation() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + databaseMapping.Assert(p => p.Empty).IsFalse(e => e.EnumType.Members.Any()); + } + + [Fact] + public void Unsigned_enum_in_model_should_fail_validation() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + } + + [Fact] + public void Explicitly_mapping_an_enum_property_using_4_1_throws() + { + var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); + + modelBuilder.Entity().Property(e => e.CategoryId); + + Assert.Throws( + () => + modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnsupportedUseOfV3Type", "Enum_Product", "CategoryId"); + } + + [Fact] + public void Explicitly_mapping_a_nullable_enum_property_using_4_1_throws() + { + var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); + + modelBuilder.Entity().Property(e => e.CategoryId); + + Assert.Throws( + () => + modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnsupportedUseOfV3Type", "Enum_Nullable", "CategoryId"); + } + + [Fact] + public void Explicitly_mapping_an_enum_property_on_a_complex_type_using_4_1_throws() + { + var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); + + modelBuilder.ComplexType().Property(c => c.Enum); + + Assert.Throws( + () => + modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnsupportedUseOfV3Type", "Enum_ComplexType", "Enum"); + } + + [Fact] + public void Explicitly_using_an_enum_property_as_a_key_with_4_1_throws() + { + var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); + + modelBuilder.Entity().HasKey(e => e.CategoryId); + + Assert.Throws( + () => + modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnsupportedUseOfV3Type", "Enum_Product", "CategoryId"); + } + + [Fact] + public void Explicitly_using_an_enum_property_as_part_of_a_composite_key_with_4_1_throws() + { + var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); + + modelBuilder.Entity().HasKey( + e => new + { + e.Id, + e.CategoryId + }); + + Assert.Throws( + () => + modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("UnsupportedUseOfV3Type", "Enum_Product", "CategoryId"); + } + + [Fact] + public void Explicitly_mapping_an_enum_property_with_Map_using_4_1_throws() + { + var modelBuilder = new DbModelBuilder(DbModelBuilderVersion.V4_1); + + modelBuilder.Entity().Map( + mapping => + { + mapping.ToTable("Table1"); + mapping.Properties(e => e.CategoryId); + }); + + Assert.Throws( + () => + modelBuilder.Build( + ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("EntityMappingConfiguration_CannotMapIgnoredProperty", "Enum_Product", "CategoryId"); + } + } + + namespace Fixtures + { + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations.Schema; + + public enum CategoryId + { + Beverages = 1, + Condiments, + Confections, + Dairy_Products, + Grains_Cereals, + Meat_Poultry, + Produce + } + + public enum Empty + { + } + + public class Enum_Empty + { + public int Id { get; set; } + public Empty Empty { get; set; } + } + + public enum Unsigned : uint + { + Member + } + + public class Enum_Unsigned + { + public int Id { get; set; } + public Unsigned Unsigned { get; set; } + } + + public class Enum_Product + { + public int Id { get; set; } + public string ProductName { get; set; } + public decimal UnitPrice { get; set; } + public short UnitsInStock { get; set; } + public CategoryId CategoryId { get; set; } + } + + public class Enum_Nullable + { + public int Id { get; set; } + public CategoryId? CategoryId { get; set; } + } + + [Flags] + public enum WithFlags : short + { + Beverages = 0, + Condiments = 1, + Confections = 2, + Dairy_Products = 4 + } + + public class Enum_Flags + { + public int Id { get; set; } + public WithFlags FlagsEnum { get; set; } + } + + public class Enum_Product_PK + { + public CategoryId Id { get; set; } + public string ProductName { get; set; } + public decimal UnitPrice { get; set; } + public short UnitsInStock { get; set; } + } + + public class Enum_Fk_Product + { + public int Id { get; set; } + public CategoryId CategoryId { get; set; } + public Enum_Fk_Category Category { get; set; } + } + + public class Enum_Fk_Category + { + public CategoryId Id { get; set; } + public ICollection Products { get; set; } + } + + public class Enum_IA_Principal + { + public CategoryId Id { get; set; } + public ICollection Dependents { get; set; } + } + + public class Enum_IA_Dependent + { + public int Id { get; set; } + public Enum_IA_Principal Principal { get; set; } + } + + public class Enum_ComplexEntity + { + public int Id { get; set; } + public Enum_ComplexType ComplexType { get; set; } + } + + [ComplexType] + public class Enum_ComplexType + { + [Column("col_enum")] + public WithFlags? Enum { get; set; } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/CodeFirst/InheritanceScenarioTests.cs b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/InheritanceScenarioTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/CodeFirst/InheritanceScenarioTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/CodeFirst/InheritanceScenarioTests.cs index b970a074..d1940114 100644 --- a/test/EntityFramework/FunctionalTests/CodeFirst/InheritanceScenarioTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/InheritanceScenarioTests.cs @@ -1,1851 +1,1851 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests -{ - using System; - using System.Collections.Generic; - using System.ComponentModel.DataAnnotations.Schema; - using System.Data.Entity; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.ModelConfiguration.Edm; - using System.Data.Entity.Utilities; - using System.Linq; - using System.Transactions; - using FunctionalTests.Model; - using Xunit; - - public sealed class InheritanceScenarioTests : TestBase - { - [Fact] - public void Orphaned_configured_table_should_throw() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey( - e => new - { - e.Key1, - e.Key2, - }); - modelBuilder.Entity() - .Map( - mapping => - { - mapping.MapInheritedProperties(); - mapping.ToTable("Dependent"); - }); - modelBuilder.Entity() - .Map( - mapping => - { - mapping.MapInheritedProperties(); - mapping.ToTable("BaseDependent"); - }); - - Assert.Throws( - () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) - .ValidateMessage("OrphanedConfiguredTableDetected", "BaseDependent"); - } - - [Fact] - public void Orphaned_unconfigured_table_should_be_removed() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasKey( - e => new - { - e.Key1, - e.Key2, - }); - modelBuilder.Entity() - .Map( - mapping => - { - mapping.MapInheritedProperties(); - mapping.ToTable("Dependent"); - }); - modelBuilder.Entity() - .Map(mapping => mapping.MapInheritedProperties()); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(1, databaseMapping.Database.EntityTypes.Count()); - } - - [Fact] - public void Should_be_able_configure_base_properties_via_derived_type() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().ToTable("Base"); - modelBuilder.Entity().Property(b => b.Id).HasColumnName("base_c"); - modelBuilder.Entity().Property(b => b.Complex.Foo).HasColumnName("base_foo"); - modelBuilder.Entity().ToTable("Derived"); - modelBuilder.Entity().Property(d => d.Id).HasColumnName("derived_c"); - modelBuilder.Entity().Property(d => d.Complex.Foo).HasColumnName("derived_foo"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - modelBuilder.Entity().Property(b => b.Id).HasColumnName("base_c"); - modelBuilder.Entity().Property(b => b.Complex.Foo).HasColumnName("base_foo"); - modelBuilder.Entity().Property(d => d.Id).HasColumnName("derived_c"); - modelBuilder.Entity().Property(d => d.Complex.Foo).HasColumnName("derived_foo"); - } - - [Fact] - public void Should_be_able_configure_base_properties_via_derived_type_reverse() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().ToTable("Derived"); - modelBuilder.Entity().Property(d => d.Id).HasColumnName("derived_c"); - modelBuilder.Entity().Property(d => d.Complex.Foo).HasColumnName("derived_foo"); - modelBuilder.Entity().ToTable("Base"); - modelBuilder.Entity().Property(b => b.Id).HasColumnName("base_c"); - modelBuilder.Entity().Property(b => b.Complex.Foo).HasColumnName("base_foo"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - modelBuilder.Entity().Property(b => b.Id).HasColumnName("base_c"); - modelBuilder.Entity().Property(b => b.Complex.Foo).HasColumnName("base_foo"); - modelBuilder.Entity().Property(d => d.Id).HasColumnName("derived_c"); - modelBuilder.Entity().Property(d => d.Complex.Foo).HasColumnName("derived_foo"); - } - - [Fact] - public void Should_be_able_configure_derived_property_and_base_property_is_not_configured() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().ToTable("Base"); - modelBuilder.Entity().ToTable("Derived"); - modelBuilder.Entity().Property(d => d.Id).HasColumnName("derived_c"); - modelBuilder.Entity().Property(d => d.Complex.Foo).HasColumnName("derived_foo"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - modelBuilder.Entity().Property(b => b.Id).HasColumnName("Id"); - modelBuilder.Entity().Property(b => b.Complex.Foo).HasColumnName("Foo"); - modelBuilder.Entity().Property(b => b.Id).HasColumnName("derived_c"); - modelBuilder.Entity().Property(d => d.Complex.Foo).HasColumnName("derived_foo"); - } - - [Fact] - public void Should_be_able_configure_base_property_and_derived_property_inherits_configuration() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().ToTable("Base"); - modelBuilder.Entity().Property(d => d.Id).HasColumnName("base_c"); - modelBuilder.Entity().ToTable("Derived"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - modelBuilder.Entity().Property(b => b.Id).HasColumnName("base_c"); - modelBuilder.Entity().Property(b => b.Complex.Foo).HasColumnName("base_foo"); - modelBuilder.Entity().Property(d => d.Id).HasColumnName("base_c"); - modelBuilder.Entity().Property(d => d.Complex.Foo).HasColumnName("base_foo"); - } - - [Fact] - public void Columns_should_get_preferred_names_when_distinct_in_target_table() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().ToTable("BaseEntities"); - modelBuilder.Entity().ToTable("Entity1s"); - modelBuilder.Entity().ToTable("Entity2s"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(e => e.SomeProperty).DbEqual("SomeProperty", c => c.Name); - databaseMapping.Assert(e => e.SomeProperty).DbEqual("SomeProperty", c => c.Name); - } - - [Fact] - public void Columns_should_get_configured_names_when_distinct_in_target_table() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().ToTable("BaseEntities"); - modelBuilder.Entity().ToTable("Entity1s"); - modelBuilder.Entity().ToTable("Entity2s"); - modelBuilder.Entity().Property(e => e.SomeProperty).HasColumnName("Foo"); - modelBuilder.Entity().Property(e => e.SomeProperty).HasColumnName("Foo"); - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(e => e.SomeProperty).DbEqual("Foo", c => c.Name); - databaseMapping.Assert(e => e.SomeProperty).DbEqual("Foo", c => c.Name); - } - - [Fact] - public void Build_model_for_simple_tpt() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().ToTable("ColoredProducts"); - modelBuilder.Entity().ToTable("StyledProducts"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_tpt_tph() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().ToTable("Products"); - modelBuilder.Entity().ToTable("DiscontinuedProducts"); - modelBuilder.Entity() - .Map( - m => - { - m.Requires("disc").HasValue("S"); - m.ToTable("StyledProducts"); - }); - modelBuilder.Entity() - .Map( - m => - { - m.Requires("disc").HasValue("C"); - m.ToTable("StyledProducts"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_split_tpt_tph() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity().ToTable("StyledProducts"); - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_tpc_with_default_tph_in_part_of_tree() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity() - .Map( - m => - { - m.MapInheritedProperties(); - m.ToTable("StyledProducts"); - }); - - Assert.Throws( - () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Build_model_for_three_level_abstract_types_tpt() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasKey(a => a.Property1_ID).ToTable("AbstractType1"); - modelBuilder.Entity().ToTable("AbstractType1_1"); - modelBuilder.Entity().ToTable("ConcreteType1_1_1"); - modelBuilder.Entity().ToTable("ConcreteType1_2"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_tree_containing_only_abstract_types() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasKey(a => a.Property1_ID); - modelBuilder.Entity().ToTable("AbstractType1_1"); - modelBuilder.IgnoreAll(); - - Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Build_model_for_entity_splitting() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - m => - { - m.Properties( - v1 => new - { - v1.VendorID, - v1.Name, - v1.PreferredVendorStatus, - v1.AccountNumber, - v1.ActiveFlag, - v1.CreditRating - }); - m.ToTable("Vendor"); - }) - .Map( - m => - { - m.Properties( - v2 => new - { - v2.VendorID, - v2.ModifiedDate, - v2.PurchasingWebServiceURL - }); - m.ToTable("VendorDetails"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_entity_splitting_excluding_key() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity() - .Map( - m => - { - m.Properties( - v1 => new - { - v1.VendorID, - v1.Name, - v1.PreferredVendorStatus, - v1.AccountNumber, - v1.ActiveFlag, - v1.CreditRating - }); - m.ToTable("Vendor"); - }) - .Map( - m => - { - m.Properties( - v2 => new - { - v2.ModifiedDate, - v2.PurchasingWebServiceURL - }); - m.ToTable("VendorDetails"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Build_model_for_entity_splitting_with_complex_properties() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.ComplexType(); - - modelBuilder.Entity() - .Map( - m => - { - m.Properties( - pd1 => new - { - pd1.ProductDescriptionID, - pd1.RowDetails.rowguid - }); - m.ToTable("ProductDescription"); - }) - .Map( - m => - { - m.Properties( - pd2 => new - { - pd2.ProductDescriptionID, - pd2.Description, - pd2.RowDetails.ModifiedDate - }); - m.ToTable("ProductDescriptionExtended"); - }); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - } - - [Fact] - public void Base_type_discovered_by_reachability_is_mapped() - { - var modelBuilder = new DbModelBuilder(); - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(2, databaseMapping.Model.Containers.Single().EntitySets.Count); - Assert.Equal( - "ITFoo", - databaseMapping.Model.Containers.Single().EntitySets.Single(es => es.Name == "ITFoos"). - ElementType.Name); - Assert.Equal(3, databaseMapping.Model.EntityTypes.Count()); - - //Base type with 1 prop - Assert.Equal( - 1, - databaseMapping.Model.EntityTypes.Single(et => et.Name == "ITFoo"). - DeclaredProperties.Count); - Assert.Equal( - 1, - databaseMapping.Model.EntityTypes.Single(et => et.Name == "ITFoo"). - Properties.Count()); - - //Derived type with 1 prop, 0 declared - Assert.Equal( - 0, - databaseMapping.Model.EntityTypes.Single(et => et.Name == "ITBar"). - DeclaredProperties.Count); - Assert.Equal( - 1, - databaseMapping.Model.EntityTypes.Single(et => et.Name == "ITBar"). - Properties.Count()); - } - - [Fact] - public void Abstract_type_at_base_of_TPH_gets_IsTypeOf_mapping() - { - var modelBuilder = new DbModelBuilder(); - modelBuilder.Entity().Map(m => { m.Requires("disc").HasValue("A2"); }).Map( - m => { m.Requires("disc").HasValue("A3"); }).Map(m => { m.Requires("disc").HasValue("A4"); }). - ToTable("A1"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(1, databaseMapping.EntityContainerMappings[0].EntitySetMappings.Count()); - Assert.Equal(4, databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Count()); - Assert.True( - databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Single( - x => x.EntityType.Name == "A1").IsHierarchyMapping); - Assert.False( - databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Single( - x => x.EntityType.Name == "A2").IsHierarchyMapping); - Assert.False( - databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Single( - x => x.EntityType.Name == "A3").IsHierarchyMapping); - Assert.False( - databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Single( - x => x.EntityType.Name == "A4").IsHierarchyMapping); - } - - //[Fact] - // Still fails, investigating issue - public void Abstract_type_in_middle_of_TPH_gets_IsTypeOf_mapping() - { - var modelBuilder = new DbModelBuilder(); - //modelBuilder.Entity().Map(m => - //{ - // m.Requires("disc").HasValue("B2"); - //}).Map(m => - //{ - // m.Requires("disc").HasValue("B3"); - //}).ToTable("B1"); - modelBuilder.Entity(); - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal(1, databaseMapping.EntityContainerMappings[0].EntitySetMappings.Count()); - Assert.Equal(3, databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Count()); - Assert.False( - databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Single( - x => x.EntityType.Name == "B1").IsHierarchyMapping); - Assert.True( - databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Single( - x => x.EntityType.Name == "B2").IsHierarchyMapping); - Assert.False( - databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Single( - x => x.EntityType.Name == "B3").IsHierarchyMapping); - } - - [Fact] - public void Mapping_IA_FK_to_derived_type_puts_FK_in_correct_TPT_table() - { - var modelBuilder = new DbModelBuilder(); - - // Map to TPT - modelBuilder.Entity(); - modelBuilder.Entity().ToTable("Employees"); - modelBuilder.Entity().ToTable("OffSiteEmployees"); - modelBuilder.Entity().ToTable("OnSiteEmployees"); - modelBuilder.Entity() - .HasRequired(e => e.ITOffice); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - databaseMapping.Assert().DbEqual("Employees", t => t.Table); - databaseMapping.Assert().DbEqual("OffSiteEmployees", t => t.Table); - databaseMapping.Assert().DbEqual("OnSiteEmployees", t => t.Table); - - // IA FK was properly moved - databaseMapping.Assert().HasNoForeignKeyColumn("ITOffice_ITOfficeId"); - databaseMapping.Assert().HasForeignKeyColumn("ITOffice_ITOfficeId"); - - // AssociationSet mapping updated properly - Assert.Equal( - "OnSiteEmployees", - databaseMapping.Database.GetEntitySet( - databaseMapping.EntityContainerMappings[0].AssociationSetMappings.ElementAt(0).Table).Table); - - Assert.Equal( - "ITOffice_ITOfficeId", - databaseMapping.EntityContainerMappings[0].AssociationSetMappings.ElementAt(0).SourceEndMapping - .PropertyMappings.ElementAt(0).ColumnProperty.Name); - } - - [Fact] - public void Mapping_FK_to_derived_type_puts_FK_in_correct_TPT_table() - { - var modelBuilder = new DbModelBuilder(); - - // Map to TPT - modelBuilder.Entity(); - modelBuilder.Entity().ToTable("Employees"); - modelBuilder.Entity().ToTable("OffSiteEmployees"); - modelBuilder.Entity().ToTable("OnSiteEmployees"); - modelBuilder.Entity() - .HasRequired(e => e.IT_Office); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - databaseMapping.Assert().DbEqual("Employees", t => t.Table); - databaseMapping.Assert().DbEqual("OffSiteEmployees", t => t.Table); - databaseMapping.Assert().DbEqual("OnSiteEmployees", t => t.Table); - - databaseMapping.Assert().HasNoForeignKeyColumn("IT_OfficeId"); - databaseMapping.Assert().HasForeignKeyColumn("IT_OfficeId"); - Assert.Equal(0, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); - } - - [Fact] - public void Mapping_association_to_subtype_by_convention_and_TPH_uses_correct_entity_sets() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal("C1", databaseMapping.Model.Containers.Single().AssociationSets[0].SourceSet.Name); - Assert.Equal("D1", databaseMapping.Model.Containers.Single().AssociationSets[0].TargetSet.Name); - } - - [Fact] - public void Mapping_association_to_subtype_by_configuration_and_TPH_uses_correct_entity_sets() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().HasRequired(g => g.DiscontinueD1).WithOptional(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - Assert.Equal("C1", databaseMapping.Model.Containers.Single().AssociationSets[0].SourceSet.Name); - Assert.Equal("D1", databaseMapping.Model.Containers.Single().AssociationSets[0].TargetSet.Name); - } - - [Fact] - public void TPT_model_can_map_PK_property_to_different_columns_in_different_tables() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().ToTable("ColoredProducts"); - modelBuilder.Entity().ToTable("StyledProducts"); - - SetDerivedEntityColumnNames(modelBuilder); - - ValidateTPTOrTPCWithRenamedColumns(modelBuilder); - } - - [Fact] - public void TPT_model_using_Map_can_map_PK_property_to_different_columns_in_different_tables() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().Map(m => m.ToTable("ColoredProducts")); - modelBuilder.Entity().Map(m => m.ToTable("StyledProducts")); - - SetDerivedEntityColumnNames(modelBuilder); - - ValidateTPTOrTPCWithRenamedColumns(modelBuilder); - } - - [Fact] - public void TPT_model_with_HasColumnName_done_before_ToTable_can_map_PK_property_to_different_columns_in_different_tables() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - SetDerivedEntityColumnNames(modelBuilder); - - modelBuilder.Entity(); - modelBuilder.Entity().ToTable("ColoredProducts"); - modelBuilder.Entity().ToTable("StyledProducts"); - - ValidateTPTOrTPCWithRenamedColumns(modelBuilder); - } - - [Fact] - public void TPC_model_can_map_PK_property_to_different_columns_in_different_tables() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Map( - m => - { - m.MapInheritedProperties(); - m.ToTable("Products"); - }); - modelBuilder.Entity().Map( - m => - { - m.MapInheritedProperties(); - m.ToTable("ColoredProducts"); - }); - modelBuilder.Entity().Map( - m => - { - m.MapInheritedProperties(); - m.ToTable("StyledProducts"); - }); - - SetDerivedEntityColumnNames(modelBuilder); - - ValidateTPTOrTPCWithRenamedColumns(modelBuilder); - } - - [Fact] - public void TPC_model_with_HasColumnName_done_before_ToTable_can_map_PK_property_to_different_columns_in_different_tables() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - SetDerivedEntityColumnNames(modelBuilder); - - modelBuilder.Entity().Map( - m => - { - m.MapInheritedProperties(); - m.ToTable("Products"); - }); - modelBuilder.Entity().Map( - m => - { - m.MapInheritedProperties(); - m.ToTable("ColoredProducts"); - }); - modelBuilder.Entity().Map( - m => - { - m.MapInheritedProperties(); - m.ToTable("StyledProducts"); - }); - - ValidateTPTOrTPCWithRenamedColumns(modelBuilder); - } - - private void SetDerivedEntityColumnNames(AdventureWorksModelBuilder modelBuilder) - { - modelBuilder.Entity().Property(p => p.ProductID).HasColumnName("base_product_id"); - modelBuilder.Entity().Property(p => p.ProductID).HasColumnName("colored_product_id"); - modelBuilder.Entity().Property(p => p.ProductID).HasColumnName("styled_product_id"); - } - - private void ValidateTPTOrTPCWithRenamedColumns(AdventureWorksModelBuilder modelBuilder) - { - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert(p => p.ProductID).DbEqual("base_product_id", c => c.Name); - databaseMapping.Assert(p => p.ProductID).DbEqual("colored_product_id", c => c.Name); - databaseMapping.Assert(p => p.ProductID).DbEqual("styled_product_id", c => c.Name); - } - - [Fact] - public void TPT_model_using_Table_attributes_can_map_PK_property_to_different_columns_in_different_tables() - { - var modelBuilder = new DbModelBuilder(); - modelBuilder.Entity().Property(e => e.Id).HasColumnName("horse_id"); - modelBuilder.Entity().Property(e => e.Id).HasColumnName("unicorn_id"); - modelBuilder.Entity().Property(e => e.Id).HasColumnName("pegasus_id"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); - - databaseMapping.Assert(p => p.Id).DbEqual("horse_id", c => c.Name); - databaseMapping.Assert(p => p.Id).DbEqual("unicorn_id", c => c.Name); - databaseMapping.Assert(p => p.Id).DbEqual("pegasus_id", c => c.Name); - } - - [Fact] - public void TPT_model_with_PK_property_to_different_columns_in_different_tables_roundtrips() - { - TPT_or_TPC_model_with_PK_property_to_different_columns_in_different_tables_roundtrips(); - } - - [Fact] - public void TPC_model_with_PK_property_to_different_columns_in_different_tables_roundtrips() - { - TPT_or_TPC_model_with_PK_property_to_different_columns_in_different_tables_roundtrips(); - } - - private void TPT_or_TPC_model_with_PK_property_to_different_columns_in_different_tables_roundtrips() - where TContext : BaseContextForPkNaming, new() - { - using (var context = new TContext()) - { - context.Database.Initialize(force: false); - - using (new TransactionScope()) - { - var baseEntity = context.Bases.Add( - new BaseForPKNaming - { - Id = 1, - Foo = "Foo1" - }); - var derivedEntity = - context.Deriveds.Add( - new DerivedForPKNaming - { - Id = 2, - Foo = "Foo2", - Bar = "Bar2" - }); - - context.SaveChanges(); - - context.Entry(baseEntity).State = EntityState.Detached; - context.Entry(derivedEntity).State = EntityState.Detached; - - var foundBase = context.Bases.Single(e => e.Id == baseEntity.Id); - var foundDerived = context.Deriveds.Single(e => e.Id == derivedEntity.Id); - - Assert.Equal("Foo1", foundBase.Foo); - Assert.Equal("Foo2", foundDerived.Foo); - Assert.Equal("Bar2", foundDerived.Bar); - - Assert.True(context.Database.SqlQuery("select base_id from base_table").Any()); - Assert.True(context.Database.SqlQuery("select derived_id from derived_table").Any()); - - if (typeof(TContext) - == typeof(ContextForPkNamingTPC)) - { - Assert.True(context.Database.SqlQuery("select base_foo from base_table").Any()); - Assert.True(context.Database.SqlQuery("select derived_foo from derived_table").Any()); - } - } - } - } - } - - #region Fixtures - - public abstract class ITFoo - { - public int Id { get; set; } - } - - public class ITBar : ITFoo - { - } - - public class ITBaz - { - public int Id { get; set; } - public ICollection ITFoos { get; set; } - } - - public abstract class A1 - { - [DatabaseGenerated(DatabaseGeneratedOption.None)] - public int Id { get; set; } - - public int Age1 { get; set; } - public string Name1 { get; set; } - } - - public class A2 : A1 - { - public int Age2 { get; set; } - public string Name2 { get; set; } - } - - public class A3 : A2 - { - public int Age3 { get; set; } - public string Name3 { get; set; } - } - - public class A4 : A1 - { - public int Age4 { get; set; } - public string Name4 { get; set; } - } - - public class B1 - { - [DatabaseGenerated(DatabaseGeneratedOption.None)] - public int Id { get; set; } - - public int Age1 { get; set; } - public string Name1 { get; set; } - } - - public abstract class B2 : B1 - { - public int Age2 { get; set; } - public string Name2 { get; set; } - } - - public class B3 : B2 - { - public int Age3 { get; set; } - public string Name3 { get; set; } - } - - public class ITOffice - { - public int ITOfficeId { get; set; } - public string Name { get; set; } - } - - public class ITEmployee - { - public int ITEmployeeId { get; set; } - public string Name { get; set; } - } - - public class ITOnSiteEmployee : ITEmployee - { - public ITOffice ITOffice { get; set; } - } - - public class ITOffSiteEmployee : ITEmployee - { - public string SiteName { get; set; } - } - - public class IT_Office - { - public int IT_OfficeId { get; set; } - public string Name { get; set; } - } - - public class IT_Employee - { - public int IT_EmployeeId { get; set; } - public string Name { get; set; } - } - - public class IT_OnSiteEmployee : IT_Employee - { - public int IT_OfficeId { get; set; } - public IT_Office IT_Office { get; set; } - } - - public class IT_OffSiteEmployee : IT_Employee - { - public string SiteName { get; set; } - } - - public class IT_Context : DbContext - { - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - modelBuilder.Entity(); - modelBuilder.Entity().ToTable("Employees"); - modelBuilder.Entity().ToTable("OffSiteEmployees"); - modelBuilder.Entity().ToTable("OnSiteEmployees"); - modelBuilder.Entity() - .HasRequired(e => e.IT_Office); - } - - public DbSet Offices { get; set; } - public DbSet Employees { get; set; } - } - - public abstract class D1 - { - public int D1Id { get; set; } - } - - public class DiscontinueD1 : D1 - { - public DateTime DiscontinuedOn { get; set; } - } - - public class C1 - { - public int Id { get; set; } - public int DiscontinueD1Id { get; set; } - public DiscontinueD1 DiscontinueD1 { get; set; } - } - - public class BaseEntityDuplicateProps - { - public int ID { get; set; } - public string Title { get; set; } - } - - public class Entity1DuplicateProps : BaseEntityDuplicateProps - { - public string SomeProperty { get; set; } - public int Entity2ID { get; set; } - public Entity2DuplicateProps Entity2 { get; set; } - } - - public class Entity2DuplicateProps : BaseEntityDuplicateProps - { - public string SomeProperty { get; set; } - } - - public class Base_195898 - { - public int Id { get; set; } - public Complex_195898 Complex { get; set; } - } - - public class Derived_195898 : Base_195898 - { - } - - public class Complex_195898 - { - public string Foo { get; set; } - } - - public abstract class BaseDependent_165027 - { - public decimal? BaseProperty { get; set; } - public float? Key1 { get; set; } - public decimal? Key2 { get; set; } - } - - public class Dependent_165027 : BaseDependent_165027 - { - } - - #endregion - - #region Bug DevDiv#223284 - - namespace Bug223284 - { - public class ITEmployee : FunctionalTests.ITEmployee - { - public ITOffice ITOffice { get; set; } - } - - public class IT_Context : DbContext - { - public DbSet Employees { get; set; } - } - - public sealed class Bug223284Test : FunctionalTestBase - { - [Fact] - public void Duplicate_entity_name_different_namespace_should_throw() - { - var context = new IT_Context(); - - Assert.Throws(() => context.Employees.Add(new ITEmployee())). - ValidateMessage("InvalidEntityType", "FunctionalTests.Bug223284.ITEmployee"); - } - } - } - - #endregion - - #region Bug DevDiv#175804 - - namespace Bug175804 - { - public class Dependent - { - public int principalnavigationkey1 { get; set; } - public int Id { get; set; } - public Principal PrincipalNavigation { get; set; } - } - - public class Principal : BasePrincipal - { - } - - public class DerivedDependent : Dependent - { - public decimal DependentDerivedProperty1 { get; set; } - } - - public class BasePrincipal - { - public DateTime BaseProperty { get; set; } - public int Key1 { get; set; } - } - - public sealed class Bug175804Test : FunctionalTestBase - { - [Fact] - public void TPC_Ordering_Of_Configuration_Between_Related_Types() - { - var builder = new DbModelBuilder(); - - builder.Entity().HasRequired(e => e.PrincipalNavigation); - builder.Entity().HasKey(e => e.Key1); - - builder.Entity().Map( - mapping => - { - mapping.MapInheritedProperties(); - mapping.ToTable("DerivedDependent"); - }); - builder.Entity().Map( - mapping => - { - mapping.MapInheritedProperties(); - mapping.ToTable("Principal"); - }); - - builder.Entity().Map( - mapping => - { - mapping.MapInheritedProperties(); - mapping.ToTable("Dependent"); - }); - builder.Entity().Map( - mapping => - { - mapping.MapInheritedProperties(); - mapping.ToTable("BasePrincipal"); - }); - - var databaseMapping = builder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; - - databaseMapping.AssertValid(); - - var derivedTypeMappings = - databaseMapping.EntityContainerMappings[0].EntitySetMappings - .First(es => es.EntitySet.Name.Contains("Dependent")).EntityTypeMappings; - - Assert.Equal( - "Principal", - derivedTypeMappings.ElementAt(0).MappingFragments[0].Table.ForeignKeyBuilders.ElementAt(0). - PrincipalTable.Name); - Assert.Equal( - "Principal", - derivedTypeMappings.ElementAt(1).MappingFragments[0].Table.ForeignKeyBuilders.ElementAt(0). - PrincipalTable.Name); - } - } - } - - #endregion - - #region BugDevDiv#178590 - - namespace BugDevDiv_178590 - { - public abstract class A - { - public virtual int Id { get; set; } - public virtual int? X { get; set; } - } - - public abstract class B : A - { - public virtual int? Y { get; set; } - } - - public class C : B - { - public virtual int? Z { get; set; } - } - - #region Subclasses have no extra properties - - public abstract class D - { - public virtual int Id { get; set; } - public virtual int? X { get; set; } - } - - public class E : D - { - } - - public class F : E - { - } - - #endregion - - public sealed class Bug178590Test : FunctionalTestBase - { - [Fact] - public void AbstractClasses_TPC() - { - var builder = new DbModelBuilder(); - - // add .ToTable("B", "dbo") as workaround - builder.Entity(); - builder - .Entity() - .Map(mapping => mapping.MapInheritedProperties()) - ; - - builder - .Entity() - .Map(mapping => mapping.MapInheritedProperties()) - .ToTable("C", "dbo") - ; - - var databaseMapping = builder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; - databaseMapping.AssertValid(); - - var typeMappings = databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings; - - Assert.Equal(1, typeMappings.Count()); - Assert.Equal("C", typeMappings.ElementAt(0).EntityType.Name); - Assert.Equal(1, typeMappings.ElementAt(0).MappingFragments.Count); - Assert.Equal(4, typeMappings.ElementAt(0).MappingFragments[0].ColumnMappings.Count()); - } - - [Fact] - public void AbstractClasses_TPT() - { - var builder = new DbModelBuilder(); - - builder.Entity(); - builder - .Entity() - .Map(mapping => mapping.MapInheritedProperties()); - - builder - .Entity() - .ToTable("C", "dbo"); - - var databaseMapping = builder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; - databaseMapping.AssertValid(); - } - - [Fact] - public void SubClasses_NoProperties() - { - var builder = new DbModelBuilder(); - - builder.Entity(); - builder.Entity(); - builder.Entity(); - - var databaseMapping = builder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; - databaseMapping.AssertValid(); - } - } - } - - #endregion - - #region Bug165027 - - namespace Bug165027 - { - public class Dependent1 - { - public DateTimeOffset key1 { get; set; } - public Principal1 PrincipalNavigation { get; set; } - } - - public abstract class Principal1 : BasePrincipal1 - { - public Dependent1 DependentNavigation { get; set; } - } - - public class BasePrincipal1 - { - public short BaseProperty { get; set; } - public DateTimeOffset? Key1 { get; set; } - } - - public class DerivedPrincipal1 : Principal1 - { - public decimal PrincipalDerivedProperty1 { get; set; } - } - - public sealed class Bug165027Repro : FunctionalTestBase - { - [Fact] - public void Bug165027Test() - { - var builder = new DbModelBuilder(); - - builder.Entity().ToTable("BasePrincipal"); - builder.Entity().HasKey(e => e.Key1); - builder.Entity().HasOptional(e => e.DependentNavigation).WithRequired( - e => e.PrincipalNavigation); - - builder.Entity().Map( - mapping => - { - mapping.MapInheritedProperties(); - mapping.ToTable("DerivedPrincipal"); - }); - - builder.Entity().HasKey(e => e.key1); - - var databaseMapping = builder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; - databaseMapping.AssertValid(); - } - } - } - - #endregion - - #region Bug178568 - - namespace Bug178568 - { - using System.Data.Entity.Core.Metadata.Edm; - - public abstract class A - { - public virtual int Id { get; set; } - public virtual int? X { get; set; } - } - - public class B : A - { - public virtual int? Y { get; set; } - } - - public class C - { - public virtual int Id { get; set; } - public virtual int? X { get; set; } - public virtual int? Y { get; set; } - } - - public sealed class Bug178568Repro : TestBase - { - [Fact] - public void TPC_Identity_ShouldPropagate() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasKey(a => a.Id); - - modelBuilder - .Entity() - .Property(a => a.Id) - .IsRequired() - .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); - - modelBuilder - .Entity() - .Map(mapping => mapping.MapInheritedProperties()) - .ToTable("B", "dbo"); - - var databaseMapping = BuildMapping(modelBuilder); - //databaseMapping.ShellEdmx("TPC_Identity_ShouldPropagate.xml"); - databaseMapping.AssertValid(); - - databaseMapping.Assert("B") - .Column("Id").DbEqual( - StoreGeneratedPattern.Identity, - c => c.StoreGeneratedPattern); - } - - [Fact] - public void TPC_IdentityNotExplicit_ShouldNotPropagate() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - modelBuilder - .Entity() - .Map(mapping => mapping.MapInheritedProperties()) - .ToTable("B", "dbo"); - - var databaseMapping = BuildMapping(modelBuilder); - //databaseMapping.ShellEdmx("TPC_IdentityNotExplicit_ShouldNotPropagate.xml"); - databaseMapping.AssertValid(); - - databaseMapping.Assert("B") - .Column("Id").DbEqual( - StoreGeneratedPattern.None, - c => c.StoreGeneratedPattern); - } - - [Fact] - public void TPT_Identity_ShouldNotPropagate() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasKey(a => a.Id); - - modelBuilder - .Entity() - .Property(a => a.Id) - .IsRequired() - .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); - - modelBuilder - .Entity() - .ToTable("B", "dbo"); - - var databaseMapping = BuildMapping(modelBuilder); - //databaseMapping.ShellEdmx("TPT_Identity_ShouldNotPropagate.xml"); - databaseMapping.AssertValid(); - - databaseMapping.Assert("A") - .Column("Id").DbEqual( - StoreGeneratedPattern.Identity, - c => c.StoreGeneratedPattern); - databaseMapping.Assert("B") - .Column("Id").DbEqual( - StoreGeneratedPattern.None, - c => c.StoreGeneratedPattern); - } - - [Fact] - public void EntitySplitting_Identity_ShouldNotPropagate() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasKey(a => a.Id); - - modelBuilder - .Entity() - .Property(a => a.Id) - .IsRequired() - .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); - - modelBuilder.Entity() - .Map( - m => - { - m.Properties( - c => new - { - c.Id, - c.X - }); - m.ToTable("CX"); - }) - .Map( - m => - { - m.Properties( - c => new - { - c.Id, - c.Y - }); - m.ToTable("CY"); - }); - - var databaseMapping = BuildMapping(modelBuilder); - //databaseMapping.ShellEdmx("EntitySplitting_Identity_ShouldNotPropagate.xml"); - databaseMapping.AssertValid(); - - databaseMapping.Assert("CX") - .Column("Id").DbEqual( - StoreGeneratedPattern.Identity, - c => c.StoreGeneratedPattern); - databaseMapping.Assert("CY") - .Column("Id").DbEqual( - StoreGeneratedPattern.None, - c => c.StoreGeneratedPattern); - } - } - } - - #endregion - - #region Bug336566 - - namespace Bug336566 - { - using System.Data.Entity.Core.Metadata.Edm; - - public class A - { - public virtual int Id { get; set; } - public virtual int? X { get; set; } - } - - public class B : A - { - public virtual int? Y { get; set; } - } - - public class C - { - public virtual int Id { get; set; } - public virtual int? X { get; set; } - public virtual int? Y { get; set; } - } - - public sealed class Bug336566Repro : TestBase - { - [Fact] - public void TPC_IdentityNotExplicit_ShouldNotPropagate() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - modelBuilder - .Entity() - .Map(mapping => mapping.MapInheritedProperties()) - .ToTable("B", "dbo"); - - var databaseMapping = BuildMapping(modelBuilder); - //databaseMapping.ShellEdmx("Bug336566Repro.xml"); - databaseMapping.AssertValid(); - - databaseMapping.Assert("A") - .Column("Id").DbEqual( - StoreGeneratedPattern.None, - c => c.StoreGeneratedPattern); - - databaseMapping.Assert("B") - .Column("Id").DbEqual( - StoreGeneratedPattern.None, - c => c.StoreGeneratedPattern); - } - - [Fact] - public void NoIdentityExplicit() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .Property(a => a.Id) - .IsRequired() - .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); - - var databaseMapping = BuildMapping(modelBuilder); - //databaseMapping.ShellEdmx("NoIdentityExplicit.xml"); - databaseMapping.AssertValid(); - - databaseMapping.Assert("A") - .Column("Id").DbEqual( - StoreGeneratedPattern.None, - c => c.StoreGeneratedPattern); - } - - [Fact] - public void TPT_Identity_ShouldKickIn() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity(); - - modelBuilder - .Entity() - .ToTable("B", "dbo"); - - var databaseMapping = BuildMapping(modelBuilder); - //databaseMapping.ShellEdmx("TPT_Identity_ShouldKickIn.xml"); - databaseMapping.AssertValid(); - - databaseMapping.Assert("A") - .Column("Id").DbEqual( - StoreGeneratedPattern.Identity, - c => c.StoreGeneratedPattern); - databaseMapping.Assert("B") - .Column("Id").DbEqual( - StoreGeneratedPattern.None, - c => c.StoreGeneratedPattern); - } - - [Fact] - public void EntitySplitting_Identity_ShouldKickIn() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder - .Entity() - .HasKey(a => a.Id); - - modelBuilder.Entity() - .Map( - m => - { - m.Properties( - c => new - { - c.Id, - c.X - }); - m.ToTable("CX"); - }) - .Map( - m => - { - m.Properties( - c => new - { - c.Id, - c.Y - }); - m.ToTable("CY"); - }); - - var databaseMapping = BuildMapping(modelBuilder); - //databaseMapping.ShellEdmx("EntitySplitting_Identity_ShouldNotPropagate.xml"); - databaseMapping.AssertValid(); - - databaseMapping.Assert("CX") - .Column("Id").DbEqual( - StoreGeneratedPattern.Identity, - c => c.StoreGeneratedPattern); - databaseMapping.Assert("CY") - .Column("Id").DbEqual( - StoreGeneratedPattern.None, - c => c.StoreGeneratedPattern); - } - } - } - - #endregion - - #region Contexts for TPT/TPC with different PK column names - - public abstract class BaseContextForPkNaming : DbContext - { - public DbSet Bases { get; set; } - public DbSet Deriveds { get; set; } - } - - public class ContextForPkNamingTPC : BaseContextForPkNaming - { - public ContextForPkNamingTPC() - { - Database.SetInitializer(new DropCreateDatabaseIfModelChanges()); - } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - modelBuilder.Entity().Map( - m => - { - m.MapInheritedProperties(); - m.ToTable("base_table"); - }); - modelBuilder.Entity().Map( - m => - { - m.MapInheritedProperties(); - m.ToTable("derived_table"); - }); - - modelBuilder.Entity().Property(e => e.Id).HasColumnName("base_id"); - modelBuilder.Entity().Property(e => e.Id).HasColumnName("derived_id"); - modelBuilder.Entity().Property(e => e.Foo).HasColumnName("base_foo"); - modelBuilder.Entity().Property(e => e.Foo).HasColumnName("derived_foo"); - } - } - - public class ContextForPkNamingTPT : BaseContextForPkNaming - { - public ContextForPkNamingTPT() - { - Database.SetInitializer(new DropCreateDatabaseIfModelChanges()); - } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - modelBuilder.Entity().ToTable("base_table"); - modelBuilder.Entity().ToTable("derived_table"); - - modelBuilder.Entity().Property(e => e.Id).HasColumnName("base_id"); - modelBuilder.Entity().Property(e => e.Id).HasColumnName("derived_id"); - } - } - - public class BaseForPKNaming - { - [DatabaseGenerated(DatabaseGeneratedOption.None)] - public int Id { get; set; } - - public string Foo { get; set; } - } - - public class DerivedForPKNaming : BaseForPKNaming - { - public string Bar { get; set; } - } - - [Table("Horses")] - public class TPTHorse - { - public int Id { get; set; } - } - - [Table("Unicorns")] - public class TPTUnicorn : TPTHorse - { - public int HornLength { get; set; } - } - - [Table("HornedPegasuses")] - public class TPTHornedPegasus : TPTUnicorn - { - public int Wingspan { get; set; } - } - - #endregion - - #region Bug335965 - - namespace Bug335965 - { - using System.Data.Entity.Core; - - public class A - { - public int Id { get; set; } - public string X { get; set; } - } - - public abstract class B : A - { - public string Y { get; set; } - } - - public class C : B - { - public string Z { get; set; } - } - - public class A2 - { - public int Id { get; set; } - public string X { get; set; } - } - - public abstract class B2 : A2 - { - public string Y { get; set; } - } - - public class C2 : B2 - { - public string Z { get; set; } - } - - public class D2 : B2 - { - public string W { get; set; } - } - - public sealed class Bug335965Repro : TestBase - { - [Fact] - public void ExplicitDiscriminatorShouldNotBeNullable() - { - var modelBuilder = new DbModelBuilder(); - - // Adding this configuration makes the discriminator nullable. - modelBuilder.Entity(); - - modelBuilder.Entity().Map(m => m.Requires("Disc").HasValue(17)); - modelBuilder.Entity().Map(m => m.Requires("Disc").HasValue(7)); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - databaseMapping - .Assert("A") - .Column("Disc") - .DbEqual(false, c => c.Nullable); - } - - [Fact] - public void InvalidMappingSubtypeHasNoDiscriminatorCondition() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Map(m => m.Requires("Disc").HasValue(17)); - modelBuilder.Entity().Map(m => m.Requires("Disc").HasValue(7)); - - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - Assert.Throws(() => databaseMapping.AssertValid(true)); - } - - [Fact] - public void ImplicitDiscriminatorShouldNotBeNullable() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - databaseMapping.Assert("A") - .Column("Discriminator") - .DbEqual(false, c => c.Nullable); - } - } - } - - #endregion - - #region Bug339467 - - namespace Bug339467 - { - public class A - { - public int Id { set; get; } - public string Name { set; get; } - } - - public abstract class B : A - { - } - - public class C : B - { - public string CName { set; get; } - } - - public sealed class Bug339467Repro : TestBase - { - [Fact] - public void SimpleTPTWithAbstractWithNoPropertiesInBetween() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - modelBuilder.Entity().ToTable("C"); - - var databaseMapping = BuildMapping(modelBuilder); - //databaseMapping.ShellEdmx("SimpleTest.xml"); - databaseMapping.AssertValid(); - } - } - } - - #endregion - - #region Bug336706 - - namespace Bug336706 - { - public class Dependent : BaseDependent - { - public int PrincipalNavigationId { get; set; } - public BaseDependent PrincipalNavigation { get; set; } - } - - public abstract class BaseDependent - { - public int Id { get; set; } - public ICollection DependentNavigation { get; set; } - - public BaseDependent() - { - DependentNavigation = new List(); - } - } - - public sealed class Bug336706Repro : TestBase - { - [Fact] - public void TPH_with_self_ref_FK_on_derived_type_has_non_nullable_FK_when_base_type_is_abstract() - { - var modelBuilder = new DbModelBuilder(); - modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany( - e => e.DependentNavigation) - .WillCascadeOnDelete(false); - modelBuilder.Entity().Map(mapping => { mapping.Requires("DiscriminatorValue").HasValue(1); }); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.Assert("BaseDependents") - .HasForeignKeyColumn("PrincipalNavigationId") - .DbEqual(false, t => t.Properties.Single(c => c.Name == "PrincipalNavigationId").Nullable); - - //databaseMapping.ShellEdmx("TPH_with_self_ref_FK_on_derived_type_has_non_nullable_FK_when_base_type_is_abstract.xml"); - databaseMapping.AssertValid(); - } - } - } - - #endregion -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests +{ + using System; + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations.Schema; + using System.Data.Entity; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.ModelConfiguration.Edm; + using System.Data.Entity.Utilities; + using System.Linq; + using System.Transactions; + using FunctionalTests.Model; + using Xunit; + + public sealed class InheritanceScenarioTests : TestBase + { + [Fact] + public void Orphaned_configured_table_should_throw() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey( + e => new + { + e.Key1, + e.Key2, + }); + modelBuilder.Entity() + .Map( + mapping => + { + mapping.MapInheritedProperties(); + mapping.ToTable("Dependent"); + }); + modelBuilder.Entity() + .Map( + mapping => + { + mapping.MapInheritedProperties(); + mapping.ToTable("BaseDependent"); + }); + + Assert.Throws( + () => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)) + .ValidateMessage("OrphanedConfiguredTableDetected", "BaseDependent"); + } + + [Fact] + public void Orphaned_unconfigured_table_should_be_removed() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasKey( + e => new + { + e.Key1, + e.Key2, + }); + modelBuilder.Entity() + .Map( + mapping => + { + mapping.MapInheritedProperties(); + mapping.ToTable("Dependent"); + }); + modelBuilder.Entity() + .Map(mapping => mapping.MapInheritedProperties()); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(1, databaseMapping.Database.EntityTypes.Count()); + } + + [Fact] + public void Should_be_able_configure_base_properties_via_derived_type() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().ToTable("Base"); + modelBuilder.Entity().Property(b => b.Id).HasColumnName("base_c"); + modelBuilder.Entity().Property(b => b.Complex.Foo).HasColumnName("base_foo"); + modelBuilder.Entity().ToTable("Derived"); + modelBuilder.Entity().Property(d => d.Id).HasColumnName("derived_c"); + modelBuilder.Entity().Property(d => d.Complex.Foo).HasColumnName("derived_foo"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + modelBuilder.Entity().Property(b => b.Id).HasColumnName("base_c"); + modelBuilder.Entity().Property(b => b.Complex.Foo).HasColumnName("base_foo"); + modelBuilder.Entity().Property(d => d.Id).HasColumnName("derived_c"); + modelBuilder.Entity().Property(d => d.Complex.Foo).HasColumnName("derived_foo"); + } + + [Fact] + public void Should_be_able_configure_base_properties_via_derived_type_reverse() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().ToTable("Derived"); + modelBuilder.Entity().Property(d => d.Id).HasColumnName("derived_c"); + modelBuilder.Entity().Property(d => d.Complex.Foo).HasColumnName("derived_foo"); + modelBuilder.Entity().ToTable("Base"); + modelBuilder.Entity().Property(b => b.Id).HasColumnName("base_c"); + modelBuilder.Entity().Property(b => b.Complex.Foo).HasColumnName("base_foo"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + modelBuilder.Entity().Property(b => b.Id).HasColumnName("base_c"); + modelBuilder.Entity().Property(b => b.Complex.Foo).HasColumnName("base_foo"); + modelBuilder.Entity().Property(d => d.Id).HasColumnName("derived_c"); + modelBuilder.Entity().Property(d => d.Complex.Foo).HasColumnName("derived_foo"); + } + + [Fact] + public void Should_be_able_configure_derived_property_and_base_property_is_not_configured() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().ToTable("Base"); + modelBuilder.Entity().ToTable("Derived"); + modelBuilder.Entity().Property(d => d.Id).HasColumnName("derived_c"); + modelBuilder.Entity().Property(d => d.Complex.Foo).HasColumnName("derived_foo"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + modelBuilder.Entity().Property(b => b.Id).HasColumnName("Id"); + modelBuilder.Entity().Property(b => b.Complex.Foo).HasColumnName("Foo"); + modelBuilder.Entity().Property(b => b.Id).HasColumnName("derived_c"); + modelBuilder.Entity().Property(d => d.Complex.Foo).HasColumnName("derived_foo"); + } + + [Fact] + public void Should_be_able_configure_base_property_and_derived_property_inherits_configuration() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().ToTable("Base"); + modelBuilder.Entity().Property(d => d.Id).HasColumnName("base_c"); + modelBuilder.Entity().ToTable("Derived"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + modelBuilder.Entity().Property(b => b.Id).HasColumnName("base_c"); + modelBuilder.Entity().Property(b => b.Complex.Foo).HasColumnName("base_foo"); + modelBuilder.Entity().Property(d => d.Id).HasColumnName("base_c"); + modelBuilder.Entity().Property(d => d.Complex.Foo).HasColumnName("base_foo"); + } + + [Fact] + public void Columns_should_get_preferred_names_when_distinct_in_target_table() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().ToTable("BaseEntities"); + modelBuilder.Entity().ToTable("Entity1s"); + modelBuilder.Entity().ToTable("Entity2s"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(e => e.SomeProperty).DbEqual("SomeProperty", c => c.Name); + databaseMapping.Assert(e => e.SomeProperty).DbEqual("SomeProperty", c => c.Name); + } + + [Fact] + public void Columns_should_get_configured_names_when_distinct_in_target_table() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().ToTable("BaseEntities"); + modelBuilder.Entity().ToTable("Entity1s"); + modelBuilder.Entity().ToTable("Entity2s"); + modelBuilder.Entity().Property(e => e.SomeProperty).HasColumnName("Foo"); + modelBuilder.Entity().Property(e => e.SomeProperty).HasColumnName("Foo"); + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(e => e.SomeProperty).DbEqual("Foo", c => c.Name); + databaseMapping.Assert(e => e.SomeProperty).DbEqual("Foo", c => c.Name); + } + + [Fact] + public void Build_model_for_simple_tpt() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().ToTable("ColoredProducts"); + modelBuilder.Entity().ToTable("StyledProducts"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_tpt_tph() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().ToTable("Products"); + modelBuilder.Entity().ToTable("DiscontinuedProducts"); + modelBuilder.Entity() + .Map( + m => + { + m.Requires("disc").HasValue("S"); + m.ToTable("StyledProducts"); + }); + modelBuilder.Entity() + .Map( + m => + { + m.Requires("disc").HasValue("C"); + m.ToTable("StyledProducts"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_split_tpt_tph() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity().ToTable("StyledProducts"); + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_tpc_with_default_tph_in_part_of_tree() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity() + .Map( + m => + { + m.MapInheritedProperties(); + m.ToTable("StyledProducts"); + }); + + Assert.Throws( + () => modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Build_model_for_three_level_abstract_types_tpt() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasKey(a => a.Property1_ID).ToTable("AbstractType1"); + modelBuilder.Entity().ToTable("AbstractType1_1"); + modelBuilder.Entity().ToTable("ConcreteType1_1_1"); + modelBuilder.Entity().ToTable("ConcreteType1_2"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_tree_containing_only_abstract_types() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasKey(a => a.Property1_ID); + modelBuilder.Entity().ToTable("AbstractType1_1"); + modelBuilder.IgnoreAll(); + + Assert.Throws(() => modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Build_model_for_entity_splitting() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + m => + { + m.Properties( + v1 => new + { + v1.VendorID, + v1.Name, + v1.PreferredVendorStatus, + v1.AccountNumber, + v1.ActiveFlag, + v1.CreditRating + }); + m.ToTable("Vendor"); + }) + .Map( + m => + { + m.Properties( + v2 => new + { + v2.VendorID, + v2.ModifiedDate, + v2.PurchasingWebServiceURL + }); + m.ToTable("VendorDetails"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_entity_splitting_excluding_key() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity() + .Map( + m => + { + m.Properties( + v1 => new + { + v1.VendorID, + v1.Name, + v1.PreferredVendorStatus, + v1.AccountNumber, + v1.ActiveFlag, + v1.CreditRating + }); + m.ToTable("Vendor"); + }) + .Map( + m => + { + m.Properties( + v2 => new + { + v2.ModifiedDate, + v2.PurchasingWebServiceURL + }); + m.ToTable("VendorDetails"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Build_model_for_entity_splitting_with_complex_properties() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.ComplexType(); + + modelBuilder.Entity() + .Map( + m => + { + m.Properties( + pd1 => new + { + pd1.ProductDescriptionID, + pd1.RowDetails.rowguid + }); + m.ToTable("ProductDescription"); + }) + .Map( + m => + { + m.Properties( + pd2 => new + { + pd2.ProductDescriptionID, + pd2.Description, + pd2.RowDetails.ModifiedDate + }); + m.ToTable("ProductDescriptionExtended"); + }); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + } + + [Fact] + public void Base_type_discovered_by_reachability_is_mapped() + { + var modelBuilder = new DbModelBuilder(); + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(2, databaseMapping.Model.Containers.Single().EntitySets.Count); + Assert.Equal( + "ITFoo", + databaseMapping.Model.Containers.Single().EntitySets.Single(es => es.Name == "ITFoos"). + ElementType.Name); + Assert.Equal(3, databaseMapping.Model.EntityTypes.Count()); + + //Base type with 1 prop + Assert.Equal( + 1, + databaseMapping.Model.EntityTypes.Single(et => et.Name == "ITFoo"). + DeclaredProperties.Count); + Assert.Equal( + 1, + databaseMapping.Model.EntityTypes.Single(et => et.Name == "ITFoo"). + Properties.Count()); + + //Derived type with 1 prop, 0 declared + Assert.Equal( + 0, + databaseMapping.Model.EntityTypes.Single(et => et.Name == "ITBar"). + DeclaredProperties.Count); + Assert.Equal( + 1, + databaseMapping.Model.EntityTypes.Single(et => et.Name == "ITBar"). + Properties.Count()); + } + + [Fact] + public void Abstract_type_at_base_of_TPH_gets_IsTypeOf_mapping() + { + var modelBuilder = new DbModelBuilder(); + modelBuilder.Entity().Map(m => { m.Requires("disc").HasValue("A2"); }).Map( + m => { m.Requires("disc").HasValue("A3"); }).Map(m => { m.Requires("disc").HasValue("A4"); }). + ToTable("A1"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(1, databaseMapping.EntityContainerMappings[0].EntitySetMappings.Count()); + Assert.Equal(4, databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Count()); + Assert.True( + databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Single( + x => x.EntityType.Name == "A1").IsHierarchyMapping); + Assert.False( + databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Single( + x => x.EntityType.Name == "A2").IsHierarchyMapping); + Assert.False( + databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Single( + x => x.EntityType.Name == "A3").IsHierarchyMapping); + Assert.False( + databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Single( + x => x.EntityType.Name == "A4").IsHierarchyMapping); + } + + //[Fact] + // Still fails, investigating issue + public void Abstract_type_in_middle_of_TPH_gets_IsTypeOf_mapping() + { + var modelBuilder = new DbModelBuilder(); + //modelBuilder.Entity().Map(m => + //{ + // m.Requires("disc").HasValue("B2"); + //}).Map(m => + //{ + // m.Requires("disc").HasValue("B3"); + //}).ToTable("B1"); + modelBuilder.Entity(); + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal(1, databaseMapping.EntityContainerMappings[0].EntitySetMappings.Count()); + Assert.Equal(3, databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Count()); + Assert.False( + databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Single( + x => x.EntityType.Name == "B1").IsHierarchyMapping); + Assert.True( + databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Single( + x => x.EntityType.Name == "B2").IsHierarchyMapping); + Assert.False( + databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings.Single( + x => x.EntityType.Name == "B3").IsHierarchyMapping); + } + + [Fact] + public void Mapping_IA_FK_to_derived_type_puts_FK_in_correct_TPT_table() + { + var modelBuilder = new DbModelBuilder(); + + // Map to TPT + modelBuilder.Entity(); + modelBuilder.Entity().ToTable("Employees"); + modelBuilder.Entity().ToTable("OffSiteEmployees"); + modelBuilder.Entity().ToTable("OnSiteEmployees"); + modelBuilder.Entity() + .HasRequired(e => e.ITOffice); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + databaseMapping.Assert().DbEqual("Employees", t => t.Table); + databaseMapping.Assert().DbEqual("OffSiteEmployees", t => t.Table); + databaseMapping.Assert().DbEqual("OnSiteEmployees", t => t.Table); + + // IA FK was properly moved + databaseMapping.Assert().HasNoForeignKeyColumn("ITOffice_ITOfficeId"); + databaseMapping.Assert().HasForeignKeyColumn("ITOffice_ITOfficeId"); + + // AssociationSet mapping updated properly + Assert.Equal( + "OnSiteEmployees", + databaseMapping.Database.GetEntitySet( + databaseMapping.EntityContainerMappings[0].AssociationSetMappings.ElementAt(0).Table).Table); + + Assert.Equal( + "ITOffice_ITOfficeId", + databaseMapping.EntityContainerMappings[0].AssociationSetMappings.ElementAt(0).SourceEndMapping + .PropertyMappings.ElementAt(0).ColumnProperty.Name); + } + + [Fact] + public void Mapping_FK_to_derived_type_puts_FK_in_correct_TPT_table() + { + var modelBuilder = new DbModelBuilder(); + + // Map to TPT + modelBuilder.Entity(); + modelBuilder.Entity().ToTable("Employees"); + modelBuilder.Entity().ToTable("OffSiteEmployees"); + modelBuilder.Entity().ToTable("OnSiteEmployees"); + modelBuilder.Entity() + .HasRequired(e => e.IT_Office); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + databaseMapping.Assert().DbEqual("Employees", t => t.Table); + databaseMapping.Assert().DbEqual("OffSiteEmployees", t => t.Table); + databaseMapping.Assert().DbEqual("OnSiteEmployees", t => t.Table); + + databaseMapping.Assert().HasNoForeignKeyColumn("IT_OfficeId"); + databaseMapping.Assert().HasForeignKeyColumn("IT_OfficeId"); + Assert.Equal(0, databaseMapping.EntityContainerMappings[0].AssociationSetMappings.Count()); + } + + [Fact] + public void Mapping_association_to_subtype_by_convention_and_TPH_uses_correct_entity_sets() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal("C1", databaseMapping.Model.Containers.Single().AssociationSets[0].SourceSet.Name); + Assert.Equal("D1", databaseMapping.Model.Containers.Single().AssociationSets[0].TargetSet.Name); + } + + [Fact] + public void Mapping_association_to_subtype_by_configuration_and_TPH_uses_correct_entity_sets() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().HasRequired(g => g.DiscontinueD1).WithOptional(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + Assert.Equal("C1", databaseMapping.Model.Containers.Single().AssociationSets[0].SourceSet.Name); + Assert.Equal("D1", databaseMapping.Model.Containers.Single().AssociationSets[0].TargetSet.Name); + } + + [Fact] + public void TPT_model_can_map_PK_property_to_different_columns_in_different_tables() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().ToTable("ColoredProducts"); + modelBuilder.Entity().ToTable("StyledProducts"); + + SetDerivedEntityColumnNames(modelBuilder); + + ValidateTPTOrTPCWithRenamedColumns(modelBuilder); + } + + [Fact] + public void TPT_model_using_Map_can_map_PK_property_to_different_columns_in_different_tables() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().Map(m => m.ToTable("ColoredProducts")); + modelBuilder.Entity().Map(m => m.ToTable("StyledProducts")); + + SetDerivedEntityColumnNames(modelBuilder); + + ValidateTPTOrTPCWithRenamedColumns(modelBuilder); + } + + [Fact] + public void TPT_model_with_HasColumnName_done_before_ToTable_can_map_PK_property_to_different_columns_in_different_tables() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + SetDerivedEntityColumnNames(modelBuilder); + + modelBuilder.Entity(); + modelBuilder.Entity().ToTable("ColoredProducts"); + modelBuilder.Entity().ToTable("StyledProducts"); + + ValidateTPTOrTPCWithRenamedColumns(modelBuilder); + } + + [Fact] + public void TPC_model_can_map_PK_property_to_different_columns_in_different_tables() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Map( + m => + { + m.MapInheritedProperties(); + m.ToTable("Products"); + }); + modelBuilder.Entity().Map( + m => + { + m.MapInheritedProperties(); + m.ToTable("ColoredProducts"); + }); + modelBuilder.Entity().Map( + m => + { + m.MapInheritedProperties(); + m.ToTable("StyledProducts"); + }); + + SetDerivedEntityColumnNames(modelBuilder); + + ValidateTPTOrTPCWithRenamedColumns(modelBuilder); + } + + [Fact] + public void TPC_model_with_HasColumnName_done_before_ToTable_can_map_PK_property_to_different_columns_in_different_tables() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + SetDerivedEntityColumnNames(modelBuilder); + + modelBuilder.Entity().Map( + m => + { + m.MapInheritedProperties(); + m.ToTable("Products"); + }); + modelBuilder.Entity().Map( + m => + { + m.MapInheritedProperties(); + m.ToTable("ColoredProducts"); + }); + modelBuilder.Entity().Map( + m => + { + m.MapInheritedProperties(); + m.ToTable("StyledProducts"); + }); + + ValidateTPTOrTPCWithRenamedColumns(modelBuilder); + } + + private void SetDerivedEntityColumnNames(AdventureWorksModelBuilder modelBuilder) + { + modelBuilder.Entity().Property(p => p.ProductID).HasColumnName("base_product_id"); + modelBuilder.Entity().Property(p => p.ProductID).HasColumnName("colored_product_id"); + modelBuilder.Entity().Property(p => p.ProductID).HasColumnName("styled_product_id"); + } + + private void ValidateTPTOrTPCWithRenamedColumns(AdventureWorksModelBuilder modelBuilder) + { + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert(p => p.ProductID).DbEqual("base_product_id", c => c.Name); + databaseMapping.Assert(p => p.ProductID).DbEqual("colored_product_id", c => c.Name); + databaseMapping.Assert(p => p.ProductID).DbEqual("styled_product_id", c => c.Name); + } + + [Fact] + public void TPT_model_using_Table_attributes_can_map_PK_property_to_different_columns_in_different_tables() + { + var modelBuilder = new DbModelBuilder(); + modelBuilder.Entity().Property(e => e.Id).HasColumnName("horse_id"); + modelBuilder.Entity().Property(e => e.Id).HasColumnName("unicorn_id"); + modelBuilder.Entity().Property(e => e.Id).HasColumnName("pegasus_id"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + Assert.Equal(1, databaseMapping.EntityContainerMappings.Single().EntitySetMappings.Count()); + + databaseMapping.Assert(p => p.Id).DbEqual("horse_id", c => c.Name); + databaseMapping.Assert(p => p.Id).DbEqual("unicorn_id", c => c.Name); + databaseMapping.Assert(p => p.Id).DbEqual("pegasus_id", c => c.Name); + } + + [Fact] + public void TPT_model_with_PK_property_to_different_columns_in_different_tables_roundtrips() + { + TPT_or_TPC_model_with_PK_property_to_different_columns_in_different_tables_roundtrips(); + } + + [Fact] + public void TPC_model_with_PK_property_to_different_columns_in_different_tables_roundtrips() + { + TPT_or_TPC_model_with_PK_property_to_different_columns_in_different_tables_roundtrips(); + } + + private void TPT_or_TPC_model_with_PK_property_to_different_columns_in_different_tables_roundtrips() + where TContext : BaseContextForPkNaming, new() + { + using (var context = new TContext()) + { + context.Database.Initialize(force: false); + + using (new TransactionScope()) + { + var baseEntity = context.Bases.Add( + new BaseForPKNaming + { + Id = 1, + Foo = "Foo1" + }); + var derivedEntity = + context.Deriveds.Add( + new DerivedForPKNaming + { + Id = 2, + Foo = "Foo2", + Bar = "Bar2" + }); + + context.SaveChanges(); + + context.Entry(baseEntity).State = EntityState.Detached; + context.Entry(derivedEntity).State = EntityState.Detached; + + var foundBase = context.Bases.Single(e => e.Id == baseEntity.Id); + var foundDerived = context.Deriveds.Single(e => e.Id == derivedEntity.Id); + + Assert.Equal("Foo1", foundBase.Foo); + Assert.Equal("Foo2", foundDerived.Foo); + Assert.Equal("Bar2", foundDerived.Bar); + + Assert.True(context.Database.SqlQuery("select base_id from base_table").Any()); + Assert.True(context.Database.SqlQuery("select derived_id from derived_table").Any()); + + if (typeof(TContext) + == typeof(ContextForPkNamingTPC)) + { + Assert.True(context.Database.SqlQuery("select base_foo from base_table").Any()); + Assert.True(context.Database.SqlQuery("select derived_foo from derived_table").Any()); + } + } + } + } + } + + #region Fixtures + + public abstract class ITFoo + { + public int Id { get; set; } + } + + public class ITBar : ITFoo + { + } + + public class ITBaz + { + public int Id { get; set; } + public ICollection ITFoos { get; set; } + } + + public abstract class A1 + { + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public int Id { get; set; } + + public int Age1 { get; set; } + public string Name1 { get; set; } + } + + public class A2 : A1 + { + public int Age2 { get; set; } + public string Name2 { get; set; } + } + + public class A3 : A2 + { + public int Age3 { get; set; } + public string Name3 { get; set; } + } + + public class A4 : A1 + { + public int Age4 { get; set; } + public string Name4 { get; set; } + } + + public class B1 + { + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public int Id { get; set; } + + public int Age1 { get; set; } + public string Name1 { get; set; } + } + + public abstract class B2 : B1 + { + public int Age2 { get; set; } + public string Name2 { get; set; } + } + + public class B3 : B2 + { + public int Age3 { get; set; } + public string Name3 { get; set; } + } + + public class ITOffice + { + public int ITOfficeId { get; set; } + public string Name { get; set; } + } + + public class ITEmployee + { + public int ITEmployeeId { get; set; } + public string Name { get; set; } + } + + public class ITOnSiteEmployee : ITEmployee + { + public ITOffice ITOffice { get; set; } + } + + public class ITOffSiteEmployee : ITEmployee + { + public string SiteName { get; set; } + } + + public class IT_Office + { + public int IT_OfficeId { get; set; } + public string Name { get; set; } + } + + public class IT_Employee + { + public int IT_EmployeeId { get; set; } + public string Name { get; set; } + } + + public class IT_OnSiteEmployee : IT_Employee + { + public int IT_OfficeId { get; set; } + public IT_Office IT_Office { get; set; } + } + + public class IT_OffSiteEmployee : IT_Employee + { + public string SiteName { get; set; } + } + + public class IT_Context : DbContext + { + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + modelBuilder.Entity(); + modelBuilder.Entity().ToTable("Employees"); + modelBuilder.Entity().ToTable("OffSiteEmployees"); + modelBuilder.Entity().ToTable("OnSiteEmployees"); + modelBuilder.Entity() + .HasRequired(e => e.IT_Office); + } + + public DbSet Offices { get; set; } + public DbSet Employees { get; set; } + } + + public abstract class D1 + { + public int D1Id { get; set; } + } + + public class DiscontinueD1 : D1 + { + public DateTime DiscontinuedOn { get; set; } + } + + public class C1 + { + public int Id { get; set; } + public int DiscontinueD1Id { get; set; } + public DiscontinueD1 DiscontinueD1 { get; set; } + } + + public class BaseEntityDuplicateProps + { + public int ID { get; set; } + public string Title { get; set; } + } + + public class Entity1DuplicateProps : BaseEntityDuplicateProps + { + public string SomeProperty { get; set; } + public int Entity2ID { get; set; } + public Entity2DuplicateProps Entity2 { get; set; } + } + + public class Entity2DuplicateProps : BaseEntityDuplicateProps + { + public string SomeProperty { get; set; } + } + + public class Base_195898 + { + public int Id { get; set; } + public Complex_195898 Complex { get; set; } + } + + public class Derived_195898 : Base_195898 + { + } + + public class Complex_195898 + { + public string Foo { get; set; } + } + + public abstract class BaseDependent_165027 + { + public decimal? BaseProperty { get; set; } + public float? Key1 { get; set; } + public decimal? Key2 { get; set; } + } + + public class Dependent_165027 : BaseDependent_165027 + { + } + + #endregion + + #region Bug DevDiv#223284 + + namespace Bug223284 + { + public class ITEmployee : FunctionalTests.ITEmployee + { + public ITOffice ITOffice { get; set; } + } + + public class IT_Context : DbContext + { + public DbSet Employees { get; set; } + } + + public sealed class Bug223284Test : FunctionalTestBase + { + [Fact] + public void Duplicate_entity_name_different_namespace_should_throw() + { + var context = new IT_Context(); + + Assert.Throws(() => context.Employees.Add(new ITEmployee())). + ValidateMessage("InvalidEntityType", "FunctionalTests.Bug223284.ITEmployee"); + } + } + } + + #endregion + + #region Bug DevDiv#175804 + + namespace Bug175804 + { + public class Dependent + { + public int principalnavigationkey1 { get; set; } + public int Id { get; set; } + public Principal PrincipalNavigation { get; set; } + } + + public class Principal : BasePrincipal + { + } + + public class DerivedDependent : Dependent + { + public decimal DependentDerivedProperty1 { get; set; } + } + + public class BasePrincipal + { + public DateTime BaseProperty { get; set; } + public int Key1 { get; set; } + } + + public sealed class Bug175804Test : FunctionalTestBase + { + [Fact] + public void TPC_Ordering_Of_Configuration_Between_Related_Types() + { + var builder = new DbModelBuilder(); + + builder.Entity().HasRequired(e => e.PrincipalNavigation); + builder.Entity().HasKey(e => e.Key1); + + builder.Entity().Map( + mapping => + { + mapping.MapInheritedProperties(); + mapping.ToTable("DerivedDependent"); + }); + builder.Entity().Map( + mapping => + { + mapping.MapInheritedProperties(); + mapping.ToTable("Principal"); + }); + + builder.Entity().Map( + mapping => + { + mapping.MapInheritedProperties(); + mapping.ToTable("Dependent"); + }); + builder.Entity().Map( + mapping => + { + mapping.MapInheritedProperties(); + mapping.ToTable("BasePrincipal"); + }); + + var databaseMapping = builder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; + + databaseMapping.AssertValid(); + + var derivedTypeMappings = + databaseMapping.EntityContainerMappings[0].EntitySetMappings + .First(es => es.EntitySet.Name.Contains("Dependent")).EntityTypeMappings; + + Assert.Equal( + "Principal", + derivedTypeMappings.ElementAt(0).MappingFragments[0].Table.ForeignKeyBuilders.ElementAt(0). + PrincipalTable.Name); + Assert.Equal( + "Principal", + derivedTypeMappings.ElementAt(1).MappingFragments[0].Table.ForeignKeyBuilders.ElementAt(0). + PrincipalTable.Name); + } + } + } + + #endregion + + #region BugDevDiv#178590 + + namespace BugDevDiv_178590 + { + public abstract class A + { + public virtual int Id { get; set; } + public virtual int? X { get; set; } + } + + public abstract class B : A + { + public virtual int? Y { get; set; } + } + + public class C : B + { + public virtual int? Z { get; set; } + } + + #region Subclasses have no extra properties + + public abstract class D + { + public virtual int Id { get; set; } + public virtual int? X { get; set; } + } + + public class E : D + { + } + + public class F : E + { + } + + #endregion + + public sealed class Bug178590Test : FunctionalTestBase + { + [Fact] + public void AbstractClasses_TPC() + { + var builder = new DbModelBuilder(); + + // add .ToTable("B", "dbo") as workaround + builder.Entity(); + builder + .Entity() + .Map(mapping => mapping.MapInheritedProperties()) + ; + + builder + .Entity() + .Map(mapping => mapping.MapInheritedProperties()) + .ToTable("C", "dbo") + ; + + var databaseMapping = builder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; + databaseMapping.AssertValid(); + + var typeMappings = databaseMapping.EntityContainerMappings[0].EntitySetMappings.ElementAt(0).EntityTypeMappings; + + Assert.Equal(1, typeMappings.Count()); + Assert.Equal("C", typeMappings.ElementAt(0).EntityType.Name); + Assert.Equal(1, typeMappings.ElementAt(0).MappingFragments.Count); + Assert.Equal(4, typeMappings.ElementAt(0).MappingFragments[0].ColumnMappings.Count()); + } + + [Fact] + public void AbstractClasses_TPT() + { + var builder = new DbModelBuilder(); + + builder.Entity(); + builder + .Entity() + .Map(mapping => mapping.MapInheritedProperties()); + + builder + .Entity() + .ToTable("C", "dbo"); + + var databaseMapping = builder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; + databaseMapping.AssertValid(); + } + + [Fact] + public void SubClasses_NoProperties() + { + var builder = new DbModelBuilder(); + + builder.Entity(); + builder.Entity(); + builder.Entity(); + + var databaseMapping = builder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; + databaseMapping.AssertValid(); + } + } + } + + #endregion + + #region Bug165027 + + namespace Bug165027 + { + public class Dependent1 + { + public DateTimeOffset key1 { get; set; } + public Principal1 PrincipalNavigation { get; set; } + } + + public abstract class Principal1 : BasePrincipal1 + { + public Dependent1 DependentNavigation { get; set; } + } + + public class BasePrincipal1 + { + public short BaseProperty { get; set; } + public DateTimeOffset? Key1 { get; set; } + } + + public class DerivedPrincipal1 : Principal1 + { + public decimal PrincipalDerivedProperty1 { get; set; } + } + + public sealed class Bug165027Repro : FunctionalTestBase + { + [Fact] + public void Bug165027Test() + { + var builder = new DbModelBuilder(); + + builder.Entity().ToTable("BasePrincipal"); + builder.Entity().HasKey(e => e.Key1); + builder.Entity().HasOptional(e => e.DependentNavigation).WithRequired( + e => e.PrincipalNavigation); + + builder.Entity().Map( + mapping => + { + mapping.MapInheritedProperties(); + mapping.ToTable("DerivedPrincipal"); + }); + + builder.Entity().HasKey(e => e.key1); + + var databaseMapping = builder.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; + databaseMapping.AssertValid(); + } + } + } + + #endregion + + #region Bug178568 + + namespace Bug178568 + { + using System.Data.Entity.Core.Metadata.Edm; + + public abstract class A + { + public virtual int Id { get; set; } + public virtual int? X { get; set; } + } + + public class B : A + { + public virtual int? Y { get; set; } + } + + public class C + { + public virtual int Id { get; set; } + public virtual int? X { get; set; } + public virtual int? Y { get; set; } + } + + public sealed class Bug178568Repro : TestBase + { + [Fact] + public void TPC_Identity_ShouldPropagate() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasKey(a => a.Id); + + modelBuilder + .Entity() + .Property(a => a.Id) + .IsRequired() + .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); + + modelBuilder + .Entity() + .Map(mapping => mapping.MapInheritedProperties()) + .ToTable("B", "dbo"); + + var databaseMapping = BuildMapping(modelBuilder); + //databaseMapping.ShellEdmx("TPC_Identity_ShouldPropagate.xml"); + databaseMapping.AssertValid(); + + databaseMapping.Assert("B") + .Column("Id").DbEqual( + StoreGeneratedPattern.Identity, + c => c.StoreGeneratedPattern); + } + + [Fact] + public void TPC_IdentityNotExplicit_ShouldNotPropagate() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + modelBuilder + .Entity() + .Map(mapping => mapping.MapInheritedProperties()) + .ToTable("B", "dbo"); + + var databaseMapping = BuildMapping(modelBuilder); + //databaseMapping.ShellEdmx("TPC_IdentityNotExplicit_ShouldNotPropagate.xml"); + databaseMapping.AssertValid(); + + databaseMapping.Assert("B") + .Column("Id").DbEqual( + StoreGeneratedPattern.None, + c => c.StoreGeneratedPattern); + } + + [Fact] + public void TPT_Identity_ShouldNotPropagate() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasKey(a => a.Id); + + modelBuilder + .Entity() + .Property(a => a.Id) + .IsRequired() + .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); + + modelBuilder + .Entity() + .ToTable("B", "dbo"); + + var databaseMapping = BuildMapping(modelBuilder); + //databaseMapping.ShellEdmx("TPT_Identity_ShouldNotPropagate.xml"); + databaseMapping.AssertValid(); + + databaseMapping.Assert("A") + .Column("Id").DbEqual( + StoreGeneratedPattern.Identity, + c => c.StoreGeneratedPattern); + databaseMapping.Assert("B") + .Column("Id").DbEqual( + StoreGeneratedPattern.None, + c => c.StoreGeneratedPattern); + } + + [Fact] + public void EntitySplitting_Identity_ShouldNotPropagate() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasKey(a => a.Id); + + modelBuilder + .Entity() + .Property(a => a.Id) + .IsRequired() + .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); + + modelBuilder.Entity() + .Map( + m => + { + m.Properties( + c => new + { + c.Id, + c.X + }); + m.ToTable("CX"); + }) + .Map( + m => + { + m.Properties( + c => new + { + c.Id, + c.Y + }); + m.ToTable("CY"); + }); + + var databaseMapping = BuildMapping(modelBuilder); + //databaseMapping.ShellEdmx("EntitySplitting_Identity_ShouldNotPropagate.xml"); + databaseMapping.AssertValid(); + + databaseMapping.Assert("CX") + .Column("Id").DbEqual( + StoreGeneratedPattern.Identity, + c => c.StoreGeneratedPattern); + databaseMapping.Assert("CY") + .Column("Id").DbEqual( + StoreGeneratedPattern.None, + c => c.StoreGeneratedPattern); + } + } + } + + #endregion + + #region Bug336566 + + namespace Bug336566 + { + using System.Data.Entity.Core.Metadata.Edm; + + public class A + { + public virtual int Id { get; set; } + public virtual int? X { get; set; } + } + + public class B : A + { + public virtual int? Y { get; set; } + } + + public class C + { + public virtual int Id { get; set; } + public virtual int? X { get; set; } + public virtual int? Y { get; set; } + } + + public sealed class Bug336566Repro : TestBase + { + [Fact] + public void TPC_IdentityNotExplicit_ShouldNotPropagate() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + modelBuilder + .Entity() + .Map(mapping => mapping.MapInheritedProperties()) + .ToTable("B", "dbo"); + + var databaseMapping = BuildMapping(modelBuilder); + //databaseMapping.ShellEdmx("Bug336566Repro.xml"); + databaseMapping.AssertValid(); + + databaseMapping.Assert("A") + .Column("Id").DbEqual( + StoreGeneratedPattern.None, + c => c.StoreGeneratedPattern); + + databaseMapping.Assert("B") + .Column("Id").DbEqual( + StoreGeneratedPattern.None, + c => c.StoreGeneratedPattern); + } + + [Fact] + public void NoIdentityExplicit() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .Property(a => a.Id) + .IsRequired() + .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); + + var databaseMapping = BuildMapping(modelBuilder); + //databaseMapping.ShellEdmx("NoIdentityExplicit.xml"); + databaseMapping.AssertValid(); + + databaseMapping.Assert("A") + .Column("Id").DbEqual( + StoreGeneratedPattern.None, + c => c.StoreGeneratedPattern); + } + + [Fact] + public void TPT_Identity_ShouldKickIn() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity(); + + modelBuilder + .Entity() + .ToTable("B", "dbo"); + + var databaseMapping = BuildMapping(modelBuilder); + //databaseMapping.ShellEdmx("TPT_Identity_ShouldKickIn.xml"); + databaseMapping.AssertValid(); + + databaseMapping.Assert("A") + .Column("Id").DbEqual( + StoreGeneratedPattern.Identity, + c => c.StoreGeneratedPattern); + databaseMapping.Assert("B") + .Column("Id").DbEqual( + StoreGeneratedPattern.None, + c => c.StoreGeneratedPattern); + } + + [Fact] + public void EntitySplitting_Identity_ShouldKickIn() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder + .Entity() + .HasKey(a => a.Id); + + modelBuilder.Entity() + .Map( + m => + { + m.Properties( + c => new + { + c.Id, + c.X + }); + m.ToTable("CX"); + }) + .Map( + m => + { + m.Properties( + c => new + { + c.Id, + c.Y + }); + m.ToTable("CY"); + }); + + var databaseMapping = BuildMapping(modelBuilder); + //databaseMapping.ShellEdmx("EntitySplitting_Identity_ShouldNotPropagate.xml"); + databaseMapping.AssertValid(); + + databaseMapping.Assert("CX") + .Column("Id").DbEqual( + StoreGeneratedPattern.Identity, + c => c.StoreGeneratedPattern); + databaseMapping.Assert("CY") + .Column("Id").DbEqual( + StoreGeneratedPattern.None, + c => c.StoreGeneratedPattern); + } + } + } + + #endregion + + #region Contexts for TPT/TPC with different PK column names + + public abstract class BaseContextForPkNaming : DbContext + { + public DbSet Bases { get; set; } + public DbSet Deriveds { get; set; } + } + + public class ContextForPkNamingTPC : BaseContextForPkNaming + { + public ContextForPkNamingTPC() + { + Database.SetInitializer(new DropCreateDatabaseIfModelChanges()); + } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + modelBuilder.Entity().Map( + m => + { + m.MapInheritedProperties(); + m.ToTable("base_table"); + }); + modelBuilder.Entity().Map( + m => + { + m.MapInheritedProperties(); + m.ToTable("derived_table"); + }); + + modelBuilder.Entity().Property(e => e.Id).HasColumnName("base_id"); + modelBuilder.Entity().Property(e => e.Id).HasColumnName("derived_id"); + modelBuilder.Entity().Property(e => e.Foo).HasColumnName("base_foo"); + modelBuilder.Entity().Property(e => e.Foo).HasColumnName("derived_foo"); + } + } + + public class ContextForPkNamingTPT : BaseContextForPkNaming + { + public ContextForPkNamingTPT() + { + Database.SetInitializer(new DropCreateDatabaseIfModelChanges()); + } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + modelBuilder.Entity().ToTable("base_table"); + modelBuilder.Entity().ToTable("derived_table"); + + modelBuilder.Entity().Property(e => e.Id).HasColumnName("base_id"); + modelBuilder.Entity().Property(e => e.Id).HasColumnName("derived_id"); + } + } + + public class BaseForPKNaming + { + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public int Id { get; set; } + + public string Foo { get; set; } + } + + public class DerivedForPKNaming : BaseForPKNaming + { + public string Bar { get; set; } + } + + [Table("Horses")] + public class TPTHorse + { + public int Id { get; set; } + } + + [Table("Unicorns")] + public class TPTUnicorn : TPTHorse + { + public int HornLength { get; set; } + } + + [Table("HornedPegasuses")] + public class TPTHornedPegasus : TPTUnicorn + { + public int Wingspan { get; set; } + } + + #endregion + + #region Bug335965 + + namespace Bug335965 + { + using System.Data.Entity.Core; + + public class A + { + public int Id { get; set; } + public string X { get; set; } + } + + public abstract class B : A + { + public string Y { get; set; } + } + + public class C : B + { + public string Z { get; set; } + } + + public class A2 + { + public int Id { get; set; } + public string X { get; set; } + } + + public abstract class B2 : A2 + { + public string Y { get; set; } + } + + public class C2 : B2 + { + public string Z { get; set; } + } + + public class D2 : B2 + { + public string W { get; set; } + } + + public sealed class Bug335965Repro : TestBase + { + [Fact] + public void ExplicitDiscriminatorShouldNotBeNullable() + { + var modelBuilder = new DbModelBuilder(); + + // Adding this configuration makes the discriminator nullable. + modelBuilder.Entity(); + + modelBuilder.Entity().Map(m => m.Requires("Disc").HasValue(17)); + modelBuilder.Entity().Map(m => m.Requires("Disc").HasValue(7)); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + databaseMapping + .Assert("A") + .Column("Disc") + .DbEqual(false, c => c.Nullable); + } + + [Fact] + public void InvalidMappingSubtypeHasNoDiscriminatorCondition() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Map(m => m.Requires("Disc").HasValue(17)); + modelBuilder.Entity().Map(m => m.Requires("Disc").HasValue(7)); + + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + Assert.Throws(() => databaseMapping.AssertValid(true)); + } + + [Fact] + public void ImplicitDiscriminatorShouldNotBeNullable() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + databaseMapping.Assert("A") + .Column("Discriminator") + .DbEqual(false, c => c.Nullable); + } + } + } + + #endregion + + #region Bug339467 + + namespace Bug339467 + { + public class A + { + public int Id { set; get; } + public string Name { set; get; } + } + + public abstract class B : A + { + } + + public class C : B + { + public string CName { set; get; } + } + + public sealed class Bug339467Repro : TestBase + { + [Fact] + public void SimpleTPTWithAbstractWithNoPropertiesInBetween() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + modelBuilder.Entity().ToTable("C"); + + var databaseMapping = BuildMapping(modelBuilder); + //databaseMapping.ShellEdmx("SimpleTest.xml"); + databaseMapping.AssertValid(); + } + } + } + + #endregion + + #region Bug336706 + + namespace Bug336706 + { + public class Dependent : BaseDependent + { + public int PrincipalNavigationId { get; set; } + public BaseDependent PrincipalNavigation { get; set; } + } + + public abstract class BaseDependent + { + public int Id { get; set; } + public ICollection DependentNavigation { get; set; } + + public BaseDependent() + { + DependentNavigation = new List(); + } + } + + public sealed class Bug336706Repro : TestBase + { + [Fact] + public void TPH_with_self_ref_FK_on_derived_type_has_non_nullable_FK_when_base_type_is_abstract() + { + var modelBuilder = new DbModelBuilder(); + modelBuilder.Entity().HasRequired(e => e.PrincipalNavigation).WithMany( + e => e.DependentNavigation) + .WillCascadeOnDelete(false); + modelBuilder.Entity().Map(mapping => { mapping.Requires("DiscriminatorValue").HasValue(1); }); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.Assert("BaseDependents") + .HasForeignKeyColumn("PrincipalNavigationId") + .DbEqual(false, t => t.Properties.Single(c => c.Name == "PrincipalNavigationId").Nullable); + + //databaseMapping.ShellEdmx("TPH_with_self_ref_FK_on_derived_type_has_non_nullable_FK_when_base_type_is_abstract.xml"); + databaseMapping.AssertValid(); + } + } + } + + #endregion +} diff --git a/test/EntityFramework/FunctionalTests/CodeFirst/PropertyConfigurationScenarioTests.cs b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/PropertyConfigurationScenarioTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/CodeFirst/PropertyConfigurationScenarioTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/CodeFirst/PropertyConfigurationScenarioTests.cs index bbb5e8da..6a3f47c3 100644 --- a/test/EntityFramework/FunctionalTests/CodeFirst/PropertyConfigurationScenarioTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/CodeFirst/PropertyConfigurationScenarioTests.cs @@ -1,549 +1,549 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests -{ - using System; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; - using System.Data.Entity; - using System.Data.Entity.Core; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.ModelConfiguration; - using System.Linq; - using FunctionalTests.Model; - using Xunit; - - public sealed class PropertyConfigurationScenarioTests : TestBase - { - [Fact] - public void Binary_fixed_length_properties_get_correct_length_in_store() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity().Property(p => p.Prop_binary_10).IsFixedLength(); - modelBuilder.Entity().Property(p => p.NProp_binary_10).IsFixedLength(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(p => p.Prop_binary_10).DbEqual(128, f => f.MaxLength); - databaseMapping.Assert(p => p.Prop_binary_10).DbEqual(false, f => f.IsMaxLength); - databaseMapping.Assert(p => p.NProp_binary_10).DbEqual(128, f => f.MaxLength); - databaseMapping.Assert(p => p.NProp_binary_10).DbEqual(false, f => f.IsMaxLength); - } - - [Fact] - public void Decimal_property_gets_default_precision_by_convention() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert(b => b.PerAssemblyQty).FacetEqual((byte)18, f => f.Precision); - databaseMapping.Assert(b => b.PerAssemblyQty).FacetEqual((byte)2, f => f.Scale); - } - - [Fact] - public void Duplicate_property_names_differing_by_case_are_uniquified() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert().HasColumns("Id", "name", "NAME"); - } - - [Fact] - public void Configure_is_max_length_on_property() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Property(c => c.CustomerType).IsMaxLength(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert(c => c.CustomerType).FacetEqual(true, f => f.IsMaxLength); - } - - private void Configure_is_max_length_on_complex_property(Action configure) - { - var modelBuilder = new AdventureWorksModelBuilder(); - - configure(modelBuilder); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert(u => u.Name).FacetEqual(true, c => c.IsMaxLength); - // Should be null for nvarchar(max) - databaseMapping.Assert("BillOfMaterials").Column("UnitMeasure_Name") - .DbEqual(false, c => c.IsMaxLength); - databaseMapping.Assert(u => u.Name).FacetEqual(null, c => c.MaxLength); - databaseMapping.Assert("BillOfMaterials").Column("UnitMeasure_Name") - .DbEqual(null, c => c.MaxLength); - databaseMapping.Assert(u => u.Name).FacetEqual(false, c => c.IsFixedLength); - databaseMapping.Assert("BillOfMaterials").Column("UnitMeasure_Name") - .DbEqual(null, c => c.IsFixedLength); - } - - [Fact] - public void Configure_is_max_length_on_complex_property_using_api() - { - Configure_is_max_length_on_complex_property( - modelBuilder => - { - modelBuilder.Entity().Ignore(b => b.Product); - modelBuilder.Entity().Ignore( - b => b.Product1); - modelBuilder.ComplexType().Property(u => u.Name) - .IsMaxLength(); - }); - } - - [Fact] - public void Configure_is_max_length_on_complex_property_using_configuration() - { - Configure_is_max_length_on_complex_property( - modelBuilder => - { - var configuration = - new ComplexTypeConfiguration(); - - configuration.Property(u => u.Name).IsMaxLength(); - - modelBuilder.Configurations.Add(configuration); - - modelBuilder.Entity().Ignore(b => b.Product); - modelBuilder.Entity().Ignore( - b => b.Product1); - }); - } - - [Fact] - public void Configure_has_max_length_on_property() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Property(c => c.CustomerType).HasMaxLength(40); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - databaseMapping.AssertValid(); - - databaseMapping.Assert(c => c.CustomerType).FacetEqual(40, f => f.MaxLength); - } - - [Fact] - public void Configure_store_type_on_property() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Property(c => c.CustomerType).HasColumnType("ntext"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - databaseMapping.AssertValid(); - - databaseMapping.Assert(c => c.CustomerType).DbEqual("ntext", f => f.TypeName); - } - - [Fact] - public void Configure_nullable_scalar_key() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - databaseMapping.AssertValid(); - - databaseMapping.Assert(l => l.LocationID).IsFalse(t => t.Nullable); - } - - [Fact] - public void Overridden_nullable_scalar_key_becomes_nullable_scalar_property() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder - .Entity() - .HasKey(l => l.Name); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - databaseMapping.AssertValid(); - - databaseMapping.Assert(l => l.LocationID).IsTrue(t => t.Nullable); - } - - [Fact] - public void Configure_identity_on_nullable_scalar_property() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder - .Entity() - .Property(s => s.MaxQty) - .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - databaseMapping.AssertValid(); - - databaseMapping.Assert(s => s.MaxQty) - .MetadataPropertyEqual("Identity", "StoreGeneratedPattern"); - databaseMapping.Assert(s => s.MaxQty).DbIsFalse(t => t.Nullable); - } - - [Fact] - public void Configure_IsConcurrencyToken_using_api() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Ignore(b => b.Product); - modelBuilder.Entity().Ignore(b => b.Product1); - modelBuilder.ComplexType().Property(u => u.UnitMeasureCode).IsConcurrencyToken(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - Assert.Equal( - ConcurrencyMode.Fixed, - databaseMapping.Model.ComplexTypes.Single() - .Properties.Single(p => p.Name == "UnitMeasureCode").ConcurrencyMode); - } - - [Fact] - public void Configure_IsConcurrencyToken_using_configuration() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - var configuration = new ComplexTypeConfiguration(); - - configuration.Property(u => u.UnitMeasureCode).IsConcurrencyToken(); - - modelBuilder.Configurations.Add(configuration); - - modelBuilder.Entity().Ignore(b => b.Product); - modelBuilder.Entity().Ignore(b => b.Product1); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - Assert.Equal( - ConcurrencyMode.Fixed, - databaseMapping.Model.ComplexTypes.Single() - .Properties.Single(p => p.Name == "UnitMeasureCode").ConcurrencyMode); - } - - [Fact] - public void Configure_nullable_scalar_property_as_required_using_annotation() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert(p => p.SellEndDate).IsFalse(t => t.Nullable); - } - - [Fact] - public void Configure_nullable_scalar_property_as_required_using_api() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().Property(p => p.ProductSubcategoryID).IsRequired(); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert(p => p.ProductSubcategoryID).IsFalse(t => t.Nullable); - } - - [Fact] - public void Configure_identity_on_non_key_property() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder - .Entity() - .Property(w => w.OrderQty) - .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - databaseMapping.Assert(w => w.OrderQty) - .MetadataPropertyEqual("Identity", "StoreGeneratedPattern"); - databaseMapping.Assert(w => w.WorkOrderID) - .AnnotationNull("StoreGeneratedPattern"); - } - - [Fact] - public void Configure_identity_on_complex_property() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder - .ComplexType() - .Property(w => w.OrderQty) - .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - - Assert.Equal( - "Identity", - databaseMapping.Model - .ComplexTypes.Single() - .Properties.Single(p => p.Name == "OrderQty") - .MetadataProperties.Single(a => a.Name.EndsWith("StoreGeneratedPattern")).Value); - } - - [Fact] - public void Configure_IsRequired_on_a_complex_child_property() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .Property(a => a.HomeAddress.Line1) - .IsOptional(); - modelBuilder.Entity() - .Property(a => a.HomeAddress.Line1) - .IsRequired(); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert("CTEmployees") - .Column("HomeAddress_Line1") - .DbEqual(false, l => l.Nullable); - } - - [Fact] - public void Configure_IsRequired_on_a_complex_child_property_conflicting_values() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .Property(a => a.HomeAddress.Line1) - .IsRequired(); - modelBuilder.Entity() - .Property(b => b.Address.Line1) - .IsOptional(); - - Assert.Throws( - () => - modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Configure_IsOptional_on_a_complex_child_property_after_IsRequired_on_complex_type() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.ComplexType
().Property(a => a.Line1).IsRequired(); - - modelBuilder.Entity() - .Property(b => b.Address.Line1) - .IsOptional(); - - Assert.Throws( - () => - modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Configure_IsOptional_and_HasMaxLength_on_a_complex_child_property_after_HasMaxLength_on_complex_type() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.ComplexType
().Property(a => a.Line1).HasMaxLength(10); - - modelBuilder.Entity() - .Property(a => a.HomeAddress.Line1) - .HasMaxLength(20); - modelBuilder.Entity() - .Property(b => b.Address.Line1) - .IsOptional(); - - Assert.Throws( - () => - modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); - } - - [Fact] - public void Configure_HasColumnName_using_api() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - modelBuilder.Entity().HasKey(u => u.UnitMeasureCode); - modelBuilder.Entity().Property(u => u.UnitMeasureCode).HasColumnName("Code"); - - var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); - databaseMapping.AssertValid(); - - databaseMapping.Assert("UnitMeasures").HasColumns("Code", "Name"); - } - - [Fact] - public void Configure_HasColumnName_using_configuration() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - var configuration = new EntityTypeConfiguration(); - - configuration.HasKey(u => u.UnitMeasureCode); - configuration.Property(u => u.UnitMeasureCode).HasColumnName("Code"); - - modelBuilder.Configurations.Add(configuration); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert("UnitMeasures").HasColumns("Code", "Name"); - } - - [Fact] - public void Configure_HasColumnName_using_configuration_can_be_overriden_using_api() - { - var modelBuilder = new AdventureWorksModelBuilder(); - - var configuration = new EntityTypeConfiguration(); - - configuration.HasKey(u => u.UnitMeasureCode); - configuration.Property(u => u.UnitMeasureCode).HasColumnName("Code"); - - modelBuilder.Configurations.Add(configuration); - - modelBuilder.Entity().Property(u => u.UnitMeasureCode).HasColumnName("UnitCode"); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert("UnitMeasures").HasColumns("UnitCode", "Name"); - } - - [Fact] - public void Configure_HasColumnName_on_a_complex_child_property_different_entities() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .Property(a => a.HomeAddress.Line1) - .HasColumnName("HomeAddress"); - modelBuilder.Entity() - .Property(b => b.Address.Line1) - .HasColumnName("StreetAddress"); - - modelBuilder.ComplexType
().Property(a => a.Line1).HasColumnName("FirstLine"); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - - databaseMapping.Assert("CTEmployees").HasColumns( - "CTEmployeeId", "HomeAddress", - "HomeAddress_Line2", "FirstLine", - "WorkAddress_Line2", "Discriminator"); - - databaseMapping.Assert("Buildings").HasColumns("Id", "StreetAddress", "Address_Line2"); - } - - [Fact] - public void Configure_HasColumnName_on_a_complex_child_property_after_HasColumnName_on_complex_type() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.ComplexType
().Property(a => a.Line1).HasColumnName("FirstLine"); - - modelBuilder.Entity(); - modelBuilder.Entity() - .Property(a => a.HomeAddress.Line1) - .HasColumnName("HomeAddress"); - - var databaseMapping = BuildMapping(modelBuilder); - databaseMapping.AssertValid(); - - databaseMapping.Assert("CTEmployees").HasColumns( - "CTEmployeeId", "HomeAddress", - "HomeAddress_Line2", "FirstLine", - "WorkAddress_Line2", "Discriminator"); - - databaseMapping.Assert("Buildings").HasColumns("Id", "FirstLine", "Address_Line2"); - } - - [Fact] - public void Configure_HasColumnName_on_complex_type_appearing_several_times_on_an_entity_throws() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.ComplexType
().Property(a => a.Line1).HasColumnName("FirstLine"); - - modelBuilder.Entity() - .HasKey(e => e.CTEmployeeId); - - Assert.Throws(() => BuildMapping(modelBuilder)); - } - - [Fact] - public void Two_properties_that_both_match_the_primary_key_convention_can_be_disambiguated_using_the_fluent_API() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity() - .HasKey(e => e.ID); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(e => e.ID) - .DbEqual(true, c => c.IsPrimaryKeyColumn); - } - - [Fact] - public void - Two_properties_that_both_match_the_primary_key_convention_can_be_disambiguated_using_a_data_annotation() - { - var modelBuilder = new DbModelBuilder(); - - modelBuilder.Entity(); - - var databaseMapping = BuildMapping(modelBuilder); - - databaseMapping.AssertValid(); - databaseMapping.Assert(e => e.ID) - .DbEqual(true, c => c.IsPrimaryKeyColumn); - } - } - - #region Fixtures - - public class DuplicatePropNames - { - public int Id { get; set; } - public string name { get; set; } - public string NAME { get; set; } - } - - public class AllBinaryDataTypes - { - public int ID { get; set; } - public byte[] Prop_binary_10 { get; set; } - public byte[] NProp_binary_10 { get; set; } - } - - #endregion - - public class TwoManyKeys - { - public int Id { get; set; } - public int ID { get; set; } - } - - public class TwoManyKeysWithAnnotation - { - public int Id { get; set; } - - [Key] - public int ID { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests +{ + using System; + using System.ComponentModel.DataAnnotations; + using System.ComponentModel.DataAnnotations.Schema; + using System.Data.Entity; + using System.Data.Entity.Core; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.ModelConfiguration; + using System.Linq; + using FunctionalTests.Model; + using Xunit; + + public sealed class PropertyConfigurationScenarioTests : TestBase + { + [Fact] + public void Binary_fixed_length_properties_get_correct_length_in_store() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity().Property(p => p.Prop_binary_10).IsFixedLength(); + modelBuilder.Entity().Property(p => p.NProp_binary_10).IsFixedLength(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(p => p.Prop_binary_10).DbEqual(128, f => f.MaxLength); + databaseMapping.Assert(p => p.Prop_binary_10).DbEqual(false, f => f.IsMaxLength); + databaseMapping.Assert(p => p.NProp_binary_10).DbEqual(128, f => f.MaxLength); + databaseMapping.Assert(p => p.NProp_binary_10).DbEqual(false, f => f.IsMaxLength); + } + + [Fact] + public void Decimal_property_gets_default_precision_by_convention() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert(b => b.PerAssemblyQty).FacetEqual((byte)18, f => f.Precision); + databaseMapping.Assert(b => b.PerAssemblyQty).FacetEqual((byte)2, f => f.Scale); + } + + [Fact] + public void Duplicate_property_names_differing_by_case_are_uniquified() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert().HasColumns("Id", "name", "NAME"); + } + + [Fact] + public void Configure_is_max_length_on_property() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Property(c => c.CustomerType).IsMaxLength(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert(c => c.CustomerType).FacetEqual(true, f => f.IsMaxLength); + } + + private void Configure_is_max_length_on_complex_property(Action configure) + { + var modelBuilder = new AdventureWorksModelBuilder(); + + configure(modelBuilder); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert(u => u.Name).FacetEqual(true, c => c.IsMaxLength); + // Should be null for nvarchar(max) + databaseMapping.Assert("BillOfMaterials").Column("UnitMeasure_Name") + .DbEqual(false, c => c.IsMaxLength); + databaseMapping.Assert(u => u.Name).FacetEqual(null, c => c.MaxLength); + databaseMapping.Assert("BillOfMaterials").Column("UnitMeasure_Name") + .DbEqual(null, c => c.MaxLength); + databaseMapping.Assert(u => u.Name).FacetEqual(false, c => c.IsFixedLength); + databaseMapping.Assert("BillOfMaterials").Column("UnitMeasure_Name") + .DbEqual(null, c => c.IsFixedLength); + } + + [Fact] + public void Configure_is_max_length_on_complex_property_using_api() + { + Configure_is_max_length_on_complex_property( + modelBuilder => + { + modelBuilder.Entity().Ignore(b => b.Product); + modelBuilder.Entity().Ignore( + b => b.Product1); + modelBuilder.ComplexType().Property(u => u.Name) + .IsMaxLength(); + }); + } + + [Fact] + public void Configure_is_max_length_on_complex_property_using_configuration() + { + Configure_is_max_length_on_complex_property( + modelBuilder => + { + var configuration = + new ComplexTypeConfiguration(); + + configuration.Property(u => u.Name).IsMaxLength(); + + modelBuilder.Configurations.Add(configuration); + + modelBuilder.Entity().Ignore(b => b.Product); + modelBuilder.Entity().Ignore( + b => b.Product1); + }); + } + + [Fact] + public void Configure_has_max_length_on_property() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Property(c => c.CustomerType).HasMaxLength(40); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + databaseMapping.AssertValid(); + + databaseMapping.Assert(c => c.CustomerType).FacetEqual(40, f => f.MaxLength); + } + + [Fact] + public void Configure_store_type_on_property() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Property(c => c.CustomerType).HasColumnType("ntext"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + databaseMapping.AssertValid(); + + databaseMapping.Assert(c => c.CustomerType).DbEqual("ntext", f => f.TypeName); + } + + [Fact] + public void Configure_nullable_scalar_key() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + databaseMapping.AssertValid(); + + databaseMapping.Assert(l => l.LocationID).IsFalse(t => t.Nullable); + } + + [Fact] + public void Overridden_nullable_scalar_key_becomes_nullable_scalar_property() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder + .Entity() + .HasKey(l => l.Name); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + databaseMapping.AssertValid(); + + databaseMapping.Assert(l => l.LocationID).IsTrue(t => t.Nullable); + } + + [Fact] + public void Configure_identity_on_nullable_scalar_property() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder + .Entity() + .Property(s => s.MaxQty) + .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + databaseMapping.AssertValid(); + + databaseMapping.Assert(s => s.MaxQty) + .MetadataPropertyEqual("Identity", "StoreGeneratedPattern"); + databaseMapping.Assert(s => s.MaxQty).DbIsFalse(t => t.Nullable); + } + + [Fact] + public void Configure_IsConcurrencyToken_using_api() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Ignore(b => b.Product); + modelBuilder.Entity().Ignore(b => b.Product1); + modelBuilder.ComplexType().Property(u => u.UnitMeasureCode).IsConcurrencyToken(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + Assert.Equal( + ConcurrencyMode.Fixed, + databaseMapping.Model.ComplexTypes.Single() + .Properties.Single(p => p.Name == "UnitMeasureCode").ConcurrencyMode); + } + + [Fact] + public void Configure_IsConcurrencyToken_using_configuration() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + var configuration = new ComplexTypeConfiguration(); + + configuration.Property(u => u.UnitMeasureCode).IsConcurrencyToken(); + + modelBuilder.Configurations.Add(configuration); + + modelBuilder.Entity().Ignore(b => b.Product); + modelBuilder.Entity().Ignore(b => b.Product1); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + Assert.Equal( + ConcurrencyMode.Fixed, + databaseMapping.Model.ComplexTypes.Single() + .Properties.Single(p => p.Name == "UnitMeasureCode").ConcurrencyMode); + } + + [Fact] + public void Configure_nullable_scalar_property_as_required_using_annotation() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert(p => p.SellEndDate).IsFalse(t => t.Nullable); + } + + [Fact] + public void Configure_nullable_scalar_property_as_required_using_api() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().Property(p => p.ProductSubcategoryID).IsRequired(); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert(p => p.ProductSubcategoryID).IsFalse(t => t.Nullable); + } + + [Fact] + public void Configure_identity_on_non_key_property() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder + .Entity() + .Property(w => w.OrderQty) + .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + databaseMapping.Assert(w => w.OrderQty) + .MetadataPropertyEqual("Identity", "StoreGeneratedPattern"); + databaseMapping.Assert(w => w.WorkOrderID) + .AnnotationNull("StoreGeneratedPattern"); + } + + [Fact] + public void Configure_identity_on_complex_property() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder + .ComplexType() + .Property(w => w.OrderQty) + .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + + Assert.Equal( + "Identity", + databaseMapping.Model + .ComplexTypes.Single() + .Properties.Single(p => p.Name == "OrderQty") + .MetadataProperties.Single(a => a.Name.EndsWith("StoreGeneratedPattern")).Value); + } + + [Fact] + public void Configure_IsRequired_on_a_complex_child_property() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .Property(a => a.HomeAddress.Line1) + .IsOptional(); + modelBuilder.Entity() + .Property(a => a.HomeAddress.Line1) + .IsRequired(); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert("CTEmployees") + .Column("HomeAddress_Line1") + .DbEqual(false, l => l.Nullable); + } + + [Fact] + public void Configure_IsRequired_on_a_complex_child_property_conflicting_values() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .Property(a => a.HomeAddress.Line1) + .IsRequired(); + modelBuilder.Entity() + .Property(b => b.Address.Line1) + .IsOptional(); + + Assert.Throws( + () => + modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Configure_IsOptional_on_a_complex_child_property_after_IsRequired_on_complex_type() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.ComplexType
().Property(a => a.Line1).IsRequired(); + + modelBuilder.Entity() + .Property(b => b.Address.Line1) + .IsOptional(); + + Assert.Throws( + () => + modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Configure_IsOptional_and_HasMaxLength_on_a_complex_child_property_after_HasMaxLength_on_complex_type() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.ComplexType
().Property(a => a.Line1).HasMaxLength(10); + + modelBuilder.Entity() + .Property(a => a.HomeAddress.Line1) + .HasMaxLength(20); + modelBuilder.Entity() + .Property(b => b.Address.Line1) + .IsOptional(); + + Assert.Throws( + () => + modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo)); + } + + [Fact] + public void Configure_HasColumnName_using_api() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + modelBuilder.Entity().HasKey(u => u.UnitMeasureCode); + modelBuilder.Entity().Property(u => u.UnitMeasureCode).HasColumnName("Code"); + + var databaseMapping = modelBuilder.BuildAndValidate(ProviderRegistry.Sql2008_ProviderInfo); + databaseMapping.AssertValid(); + + databaseMapping.Assert("UnitMeasures").HasColumns("Code", "Name"); + } + + [Fact] + public void Configure_HasColumnName_using_configuration() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + var configuration = new EntityTypeConfiguration(); + + configuration.HasKey(u => u.UnitMeasureCode); + configuration.Property(u => u.UnitMeasureCode).HasColumnName("Code"); + + modelBuilder.Configurations.Add(configuration); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert("UnitMeasures").HasColumns("Code", "Name"); + } + + [Fact] + public void Configure_HasColumnName_using_configuration_can_be_overriden_using_api() + { + var modelBuilder = new AdventureWorksModelBuilder(); + + var configuration = new EntityTypeConfiguration(); + + configuration.HasKey(u => u.UnitMeasureCode); + configuration.Property(u => u.UnitMeasureCode).HasColumnName("Code"); + + modelBuilder.Configurations.Add(configuration); + + modelBuilder.Entity().Property(u => u.UnitMeasureCode).HasColumnName("UnitCode"); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert("UnitMeasures").HasColumns("UnitCode", "Name"); + } + + [Fact] + public void Configure_HasColumnName_on_a_complex_child_property_different_entities() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .Property(a => a.HomeAddress.Line1) + .HasColumnName("HomeAddress"); + modelBuilder.Entity() + .Property(b => b.Address.Line1) + .HasColumnName("StreetAddress"); + + modelBuilder.ComplexType
().Property(a => a.Line1).HasColumnName("FirstLine"); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + + databaseMapping.Assert("CTEmployees").HasColumns( + "CTEmployeeId", "HomeAddress", + "HomeAddress_Line2", "FirstLine", + "WorkAddress_Line2", "Discriminator"); + + databaseMapping.Assert("Buildings").HasColumns("Id", "StreetAddress", "Address_Line2"); + } + + [Fact] + public void Configure_HasColumnName_on_a_complex_child_property_after_HasColumnName_on_complex_type() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.ComplexType
().Property(a => a.Line1).HasColumnName("FirstLine"); + + modelBuilder.Entity(); + modelBuilder.Entity() + .Property(a => a.HomeAddress.Line1) + .HasColumnName("HomeAddress"); + + var databaseMapping = BuildMapping(modelBuilder); + databaseMapping.AssertValid(); + + databaseMapping.Assert("CTEmployees").HasColumns( + "CTEmployeeId", "HomeAddress", + "HomeAddress_Line2", "FirstLine", + "WorkAddress_Line2", "Discriminator"); + + databaseMapping.Assert("Buildings").HasColumns("Id", "FirstLine", "Address_Line2"); + } + + [Fact] + public void Configure_HasColumnName_on_complex_type_appearing_several_times_on_an_entity_throws() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.ComplexType
().Property(a => a.Line1).HasColumnName("FirstLine"); + + modelBuilder.Entity() + .HasKey(e => e.CTEmployeeId); + + Assert.Throws(() => BuildMapping(modelBuilder)); + } + + [Fact] + public void Two_properties_that_both_match_the_primary_key_convention_can_be_disambiguated_using_the_fluent_API() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity() + .HasKey(e => e.ID); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(e => e.ID) + .DbEqual(true, c => c.IsPrimaryKeyColumn); + } + + [Fact] + public void + Two_properties_that_both_match_the_primary_key_convention_can_be_disambiguated_using_a_data_annotation() + { + var modelBuilder = new DbModelBuilder(); + + modelBuilder.Entity(); + + var databaseMapping = BuildMapping(modelBuilder); + + databaseMapping.AssertValid(); + databaseMapping.Assert(e => e.ID) + .DbEqual(true, c => c.IsPrimaryKeyColumn); + } + } + + #region Fixtures + + public class DuplicatePropNames + { + public int Id { get; set; } + public string name { get; set; } + public string NAME { get; set; } + } + + public class AllBinaryDataTypes + { + public int ID { get; set; } + public byte[] Prop_binary_10 { get; set; } + public byte[] NProp_binary_10 { get; set; } + } + + #endregion + + public class TwoManyKeys + { + public int Id { get; set; } + public int ID { get; set; } + } + + public class TwoManyKeysWithAnnotation + { + public int Id { get; set; } + + [Key] + public int ID { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests.Transitional/FunctionalTests.Transitional.csproj b/test/EntityFramework/FunctionalTests.Transitional/FunctionalTests.Transitional.csproj new file mode 100644 index 00000000..9463b83b --- /dev/null +++ b/test/EntityFramework/FunctionalTests.Transitional/FunctionalTests.Transitional.csproj @@ -0,0 +1,591 @@ + + + + + Debug + AnyCPU + {3D65611F-E8FB-4A33-9196-7836969D6378} + Library + Properties + System.Data.Entity + EntityFramework.FunctionalTests.Transitional + 512 + ..\..\..\ + true + + + v4.5 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + 0169 + + + v4.5 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + 0169 + false + + + v4.0 + true + full + false + bin\DebugNet40\ + DEBUG;TRACE;NET40 + prompt + 4 + 0169 + + + v4.0 + pdbonly + true + bin\ReleaseNet40\ + TRACE;NET40 + prompt + 4 + 0169 + + + true + + + ..\FinalPublicKey.snk + + + true + + + + + ..\..\..\packages\Moq.4.0.10827\lib\NET40\Moq.dll + + + + + + + + + + True + ..\..\..\packages\Microsoft.SqlServer.Compact.4.0.8876.1\lib\net40\System.Data.SqlServerCe.dll + + + + + + + + + ..\..\..\packages\xunit.1.9.1\lib\net20\xunit.dll + + + ..\..\..\packages\xunit.extensions.1.9.1\lib\net20\xunit.extensions.dll + + + + + Properties\FinalPublicKey.snk + + + Designer + + + + + + + + + + + + + TextTemplatingFileGenerator + CsAdvancedPatterns.Context.cs + FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns + + + TextTemplatingFileGenerator + CsAdvancedPatterns.cs + FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns + + + TextTemplatingFileGenerator + CsMonsterModel.Context.cs + FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel + + + TextTemplatingFileGenerator + CsMonsterModel.cs + FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel + + + + + + FunctionalTests.ProductivityApi.TemplateModels.Schemas.AdvancedPatterns.edmx + + + FunctionalTests.ProductivityApi.TemplateModels.Schemas.MonsterModel.csdl + + + FunctionalTests.ProductivityApi.TemplateModels.Schemas.MonsterModel.msl + + + FunctionalTests.ProductivityApi.TemplateModels.Schemas.MonsterModel.ssdl + + + + + {1ef9c524-7122-4677-b111-dd14bb2a9ea2} + EntityFramework.SqlServerCompact + + + {6f4bb80b-5f74-44d3-a77f-0025dfa48c1a} + EntityFramework.SqlServer + + + {e06d1c12-efe8-4413-a15c-ae01fc158f2f} + EntityFramework + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 201112202056275_InitialCreate.cs + + + + 201112202056573_AddUrlToBlog.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CsAdvancedPatterns.tt + + + CsAdvancedPatterns.tt + + + CsAdvancedPatterns.tt + + + CsAdvancedPatterns.Context.tt + True + True + + + CsAdvancedPatterns.tt + True + True + + + CsAdvancedPatterns.tt + + + CsAdvancedPatterns.tt + + + CsAdvancedPatterns.tt + + + CsAdvancedPatterns.tt + + + + + + + + + + + CsAdvancedPatterns.tt + + + CsAdvancedPatterns.tt + + + CsAdvancedPatterns.tt + + + CsAdvancedPatterns.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.Context.tt + True + True + + + CsMonsterModel.tt + True + True + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + + + + + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + CsMonsterModel.tt + + + + + + + + + + + + + if not exist "$(TargetDir)x86" md "$(TargetDir)x86" + xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\x86\*.*" "$(TargetDir)x86" + if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64" + xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64" + + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/Metadata/MetadataCachingModel.csdl b/test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataCachingModel.csdl similarity index 96% rename from test/EntityFramework/FunctionalTests/Metadata/MetadataCachingModel.csdl rename to test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataCachingModel.csdl index 474c84b1..8645f570 100644 --- a/test/EntityFramework/FunctionalTests/Metadata/MetadataCachingModel.csdl +++ b/test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataCachingModel.csdl @@ -1,13 +1,13 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/Metadata/MetadataCachingModel.msl b/test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataCachingModel.msl similarity index 96% rename from test/EntityFramework/FunctionalTests/Metadata/MetadataCachingModel.msl rename to test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataCachingModel.msl index 602d31ba..7073cddf 100644 --- a/test/EntityFramework/FunctionalTests/Metadata/MetadataCachingModel.msl +++ b/test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataCachingModel.msl @@ -1,13 +1,13 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/Metadata/MetadataCachingModel.ssdl b/test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataCachingModel.ssdl similarity index 97% rename from test/EntityFramework/FunctionalTests/Metadata/MetadataCachingModel.ssdl rename to test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataCachingModel.ssdl index 554a5a44..8f0ef223 100644 --- a/test/EntityFramework/FunctionalTests/Metadata/MetadataCachingModel.ssdl +++ b/test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataCachingModel.ssdl @@ -1,13 +1,13 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/Metadata/MetadataCachingTests.cs b/test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataCachingTests.cs similarity index 89% rename from test/EntityFramework/FunctionalTests/Metadata/MetadataCachingTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataCachingTests.cs index c810fcc6..2c9bdd86 100644 --- a/test/EntityFramework/FunctionalTests/Metadata/MetadataCachingTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataCachingTests.cs @@ -1,146 +1,146 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Metadata -{ - using System.Data.Entity.Core.EntityClient; - using System.Data.Entity.Core.Metadata.Edm; - using System.Reflection; - using Xunit; - - public class MetadataCachingTests : FunctionalTestBase - { - private static readonly string connectionString = string.Format( - @"metadata=res://EntityFramework.FunctionalTests/System.Data.Entity.Metadata.MetadataCachingModel.csdl|res://EntityFramework.FunctionalTests/System.Data.Entity.Metadata.MetadataCachingModel.ssdl|res://EntityFramework.FunctionalTests/System.Data.Entity.Metadata.MetadataCachingModel.msl;provider=System.Data.SqlClient;provider connection string=""{0}""", - ModelHelpers.SimpleConnectionString("tempdb")); - - [Fact] - public void Verify_that_metadata_is_the_same_for_two_workspaces_created_from_two_entity_connections_with_same_connection_strings() - { - var connection1 = new EntityConnection(connectionString); - var connection2 = new EntityConnection(connectionString); - var workspace1 = connection1.GetMetadataWorkspace(); - var workspace2 = connection2.GetMetadataWorkspace(); - - Assert.Same(workspace1.GetItemCollection(DataSpace.CSpace), workspace2.GetItemCollection(DataSpace.CSpace)); - Assert.Same(workspace1.GetItemCollection(DataSpace.SSpace), workspace2.GetItemCollection(DataSpace.SSpace)); - Assert.Same(workspace1.GetItemCollection(DataSpace.CSSpace), workspace2.GetItemCollection(DataSpace.CSSpace)); - } - - [Fact] - public void - Verify_that_metadata_is_the_same_for_two_workspaces_created_from_two_entity_connections_with_equivalent_connection_strings() - { - var connection1 = new EntityConnection(connectionString); - var connection2 = new EntityConnection(connectionString + ";;"); - - var workspace1 = connection1.GetMetadataWorkspace(); - var workspace2 = connection2.GetMetadataWorkspace(); - - Assert.Same(workspace1.GetItemCollection(DataSpace.CSpace), workspace2.GetItemCollection(DataSpace.CSpace)); - Assert.Same(workspace1.GetItemCollection(DataSpace.SSpace), workspace2.GetItemCollection(DataSpace.SSpace)); - Assert.Same(workspace1.GetItemCollection(DataSpace.CSSpace), workspace2.GetItemCollection(DataSpace.CSSpace)); - } - - [Fact] - public void - Verify_that_conceptual_metadata_is_the_same_for_two_workspaces_created_from_two_entity_connections_with_reordered_metadata_in_connection_strings - () - { - var connectionString2 = string.Format( - @"metadata=res://EntityFramework.FunctionalTests/System.Data.Entity.Metadata.MetadataCachingModel.msl|res://EntityFramework.FunctionalTests/System.Data.Entity.Metadata.MetadataCachingModel.ssdl|res://EntityFramework.FunctionalTests/System.Data.Entity.Metadata.MetadataCachingModel.csdl;provider=System.Data.SqlClient;provider connection string=""{0}""", - ModelHelpers.SimpleConnectionString("tempdb")); - - var connection1 = new EntityConnection(connectionString); - var connection2 = new EntityConnection(connectionString2); - var workspace1 = connection1.GetMetadataWorkspace(); - var workspace2 = connection2.GetMetadataWorkspace(); - - Assert.Same(workspace1.GetItemCollection(DataSpace.CSpace), workspace2.GetItemCollection(DataSpace.CSpace)); - } - - [Fact] - public void Verify_that_opening_connection_does_not_create_new_MetadataWorkspace() - { - var connection = new EntityConnection(connectionString); - var workspace = connection.GetMetadataWorkspace(); - - connection.Open(); - Assert.Same(workspace, connection.GetMetadataWorkspace()); - } - - [Fact] - public void Metadata_does_not_get_garbage_collected_if_references_are_alive() - { - Action garbageCollection = () => - { - GC.Collect(); - GC.WaitForPendingFinalizers(); - }; - - MetadataCachingWithGarbageCollectionTemplate(garbageCollection); - } - - [Fact] - public void Metadata_does_not_get_garbage_collected_after_cleanup_is_performed_once_if_references_are_alive() - { - Action garbageCollection = () => - { - GC.Collect(); - GC.WaitForPendingFinalizers(); - CallPeriodicCleanupMethod(); - }; - - MetadataCachingWithGarbageCollectionTemplate(garbageCollection); - } - - [Fact] - public void Metadata_does_not_get_garbage_collected_after_cleanup_is_performed_twice_if_references_are_alive() - { - Action garbageCollection = () => - { - GC.Collect(); - GC.WaitForPendingFinalizers(); - CallPeriodicCleanupMethod(); - CallPeriodicCleanupMethod(); - }; - - MetadataCachingWithGarbageCollectionTemplate(garbageCollection); - } - - private void MetadataCachingWithGarbageCollectionTemplate(Action garbageCollection) - { - MetadataWorkspace.ClearCache(); - var weakReferences = new WeakReference[3]; - - // load metadata - using (var connection1 = new EntityConnection(connectionString)) - { - connection1.Open(); - - weakReferences[0] = new WeakReference(connection1.GetMetadataWorkspace().GetItemCollection(DataSpace.CSpace)); - weakReferences[1] = new WeakReference(connection1.GetMetadataWorkspace().GetItemCollection(DataSpace.SSpace)); - weakReferences[2] = new WeakReference(connection1.GetMetadataWorkspace().GetItemCollection(DataSpace.CSSpace)); - } - - // perform necessary garbage collection steps - garbageCollection(); - - // verify that metadata was cached - using (var connection2 = new EntityConnection(connectionString)) - { - connection2.Open(); - - Assert.Same(weakReferences[0].Target, connection2.GetMetadataWorkspace().GetItemCollection(DataSpace.CSpace)); - Assert.Same(weakReferences[1].Target, connection2.GetMetadataWorkspace().GetItemCollection(DataSpace.SSpace)); - Assert.Same(weakReferences[2].Target, connection2.GetMetadataWorkspace().GetItemCollection(DataSpace.CSSpace)); - } - } - - internal static void CallPeriodicCleanupMethod() - { - var method = typeof(MetadataCache).GetMethod( - "PeriodicCleanupCallback", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(object) }, null); - method.Invoke(null, new object[] { null }); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Metadata +{ + using System.Data.Entity.Core.EntityClient; + using System.Data.Entity.Core.Metadata.Edm; + using System.Reflection; + using Xunit; + + public class MetadataCachingTests : FunctionalTestBase + { + private static readonly string connectionString = string.Format( + @"metadata=res://EntityFramework.FunctionalTests.Transitional/System.Data.Entity.Metadata.MetadataCachingModel.csdl|res://EntityFramework.FunctionalTests.Transitional/System.Data.Entity.Metadata.MetadataCachingModel.ssdl|res://EntityFramework.FunctionalTests.Transitional/System.Data.Entity.Metadata.MetadataCachingModel.msl;provider=System.Data.SqlClient;provider connection string=""{0}""", + ModelHelpers.SimpleConnectionString("tempdb")); + + [Fact] + public void Verify_that_metadata_is_the_same_for_two_workspaces_created_from_two_entity_connections_with_same_connection_strings() + { + var connection1 = new EntityConnection(connectionString); + var connection2 = new EntityConnection(connectionString); + var workspace1 = connection1.GetMetadataWorkspace(); + var workspace2 = connection2.GetMetadataWorkspace(); + + Assert.Same(workspace1.GetItemCollection(DataSpace.CSpace), workspace2.GetItemCollection(DataSpace.CSpace)); + Assert.Same(workspace1.GetItemCollection(DataSpace.SSpace), workspace2.GetItemCollection(DataSpace.SSpace)); + Assert.Same(workspace1.GetItemCollection(DataSpace.CSSpace), workspace2.GetItemCollection(DataSpace.CSSpace)); + } + + [Fact] + public void + Verify_that_metadata_is_the_same_for_two_workspaces_created_from_two_entity_connections_with_equivalent_connection_strings() + { + var connection1 = new EntityConnection(connectionString); + var connection2 = new EntityConnection(connectionString + ";;"); + + var workspace1 = connection1.GetMetadataWorkspace(); + var workspace2 = connection2.GetMetadataWorkspace(); + + Assert.Same(workspace1.GetItemCollection(DataSpace.CSpace), workspace2.GetItemCollection(DataSpace.CSpace)); + Assert.Same(workspace1.GetItemCollection(DataSpace.SSpace), workspace2.GetItemCollection(DataSpace.SSpace)); + Assert.Same(workspace1.GetItemCollection(DataSpace.CSSpace), workspace2.GetItemCollection(DataSpace.CSSpace)); + } + + [Fact] + public void + Verify_that_conceptual_metadata_is_the_same_for_two_workspaces_created_from_two_entity_connections_with_reordered_metadata_in_connection_strings + () + { + var connectionString2 = string.Format( + @"metadata=res://EntityFramework.FunctionalTests.Transitional/System.Data.Entity.Metadata.MetadataCachingModel.msl|res://EntityFramework.FunctionalTests.Transitional/System.Data.Entity.Metadata.MetadataCachingModel.ssdl|res://EntityFramework.FunctionalTests.Transitional/System.Data.Entity.Metadata.MetadataCachingModel.csdl;provider=System.Data.SqlClient;provider connection string=""{0}""", + ModelHelpers.SimpleConnectionString("tempdb")); + + var connection1 = new EntityConnection(connectionString); + var connection2 = new EntityConnection(connectionString2); + var workspace1 = connection1.GetMetadataWorkspace(); + var workspace2 = connection2.GetMetadataWorkspace(); + + Assert.Same(workspace1.GetItemCollection(DataSpace.CSpace), workspace2.GetItemCollection(DataSpace.CSpace)); + } + + [Fact] + public void Verify_that_opening_connection_does_not_create_new_MetadataWorkspace() + { + var connection = new EntityConnection(connectionString); + var workspace = connection.GetMetadataWorkspace(); + + connection.Open(); + Assert.Same(workspace, connection.GetMetadataWorkspace()); + } + + [Fact] + public void Metadata_does_not_get_garbage_collected_if_references_are_alive() + { + Action garbageCollection = () => + { + GC.Collect(); + GC.WaitForPendingFinalizers(); + }; + + MetadataCachingWithGarbageCollectionTemplate(garbageCollection); + } + + [Fact] + public void Metadata_does_not_get_garbage_collected_after_cleanup_is_performed_once_if_references_are_alive() + { + Action garbageCollection = () => + { + GC.Collect(); + GC.WaitForPendingFinalizers(); + CallPeriodicCleanupMethod(); + }; + + MetadataCachingWithGarbageCollectionTemplate(garbageCollection); + } + + [Fact] + public void Metadata_does_not_get_garbage_collected_after_cleanup_is_performed_twice_if_references_are_alive() + { + Action garbageCollection = () => + { + GC.Collect(); + GC.WaitForPendingFinalizers(); + CallPeriodicCleanupMethod(); + CallPeriodicCleanupMethod(); + }; + + MetadataCachingWithGarbageCollectionTemplate(garbageCollection); + } + + private void MetadataCachingWithGarbageCollectionTemplate(Action garbageCollection) + { + MetadataWorkspace.ClearCache(); + var weakReferences = new WeakReference[3]; + + // load metadata + using (var connection1 = new EntityConnection(connectionString)) + { + connection1.Open(); + + weakReferences[0] = new WeakReference(connection1.GetMetadataWorkspace().GetItemCollection(DataSpace.CSpace)); + weakReferences[1] = new WeakReference(connection1.GetMetadataWorkspace().GetItemCollection(DataSpace.SSpace)); + weakReferences[2] = new WeakReference(connection1.GetMetadataWorkspace().GetItemCollection(DataSpace.CSSpace)); + } + + // perform necessary garbage collection steps + garbageCollection(); + + // verify that metadata was cached + using (var connection2 = new EntityConnection(connectionString)) + { + connection2.Open(); + + Assert.Same(weakReferences[0].Target, connection2.GetMetadataWorkspace().GetItemCollection(DataSpace.CSpace)); + Assert.Same(weakReferences[1].Target, connection2.GetMetadataWorkspace().GetItemCollection(DataSpace.SSpace)); + Assert.Same(weakReferences[2].Target, connection2.GetMetadataWorkspace().GetItemCollection(DataSpace.CSSpace)); + } + } + + internal static void CallPeriodicCleanupMethod() + { + var method = typeof(MetadataCache).GetMethod( + "PeriodicCleanupCallback", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(object) }, null); + method.Invoke(null, new object[] { null }); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/Metadata/MetadataEnumTests.cs b/test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataEnumTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/Metadata/MetadataEnumTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataEnumTests.cs index fd6a193f..6efb9704 100644 --- a/test/EntityFramework/FunctionalTests/Metadata/MetadataEnumTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataEnumTests.cs @@ -1,933 +1,933 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Metadata -{ - using System; - using System.Collections.Generic; - using System.Data.Entity.Core; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.Resources; - using System.IO; - using System.Linq; - using System.Xml; - using System.Xml.Linq; - using System.Xml.Schema; - using Xunit; - using Xunit.Sdk; - - public class MetadataEnumTests : FunctionalTestBase, IUseFixture - { - private const string enumCsdl = -@" - - - - - - - - - - - - - - - -"; - - private const string edmNamespace = "http://schemas.microsoft.com/ado/2009/11/edm"; - - private XmlSchemaSet csdlSchemaSet; - - public void SetFixture(MetadataEnumFixture data) - { - csdlSchemaSet = data.CsdlSchemaSet; - } - - [Fact] - public void Empty_enum_is_valid() - { - var emptyEnum = -@" - - -"; - - var edmItemCollection = new EdmItemCollection(new[] { XmlReader.Create(new StringReader(emptyEnum)) }); - var enumType = edmItemCollection.GetItems().Single(); - - Assert.Equal(0, enumType.Members.Count); - } - - [Fact] - public void SchemaSource_metadata_property_is_populated() - { - var edmItemCollection = new EdmItemCollection(new[] { XmlReader.Create(new StringReader(enumCsdl)) }); - var enumType = edmItemCollection.GetItems().Single(); - - var schemaSource = enumType.MetadataProperties["SchemaSource"]; - Assert.Equal(PropertyKind.System, schemaSource.PropertyKind); - } - - [Fact] - public void Documenation_is_populated_correctly_for_enum_type() - { - var enumWithDocumentation = -@" - - - Documentation - summary - Documentation - long description - - - -"; - - var edmItemCollection = new EdmItemCollection(new[] { XmlReader.Create(new StringReader(enumWithDocumentation)) }); - var enumType = edmItemCollection.GetItems().Single(); - - Assert.NotNull(enumType.Documentation); - Assert.Equal("Documentation - summary", enumType.Documentation.Summary); - Assert.Equal("Documentation - long description", enumType.Documentation.LongDescription); - } - - [Fact] - public void Documenation_is_populated_correctly_for_members_of_enum_type() - { - var enumWithDocumentation = -@" - - - - Documentation - summary - Documentation - long description - - - -"; - - var edmItemCollection = new EdmItemCollection(new[] { XmlReader.Create(new StringReader(enumWithDocumentation)) }); - var enumType = edmItemCollection.GetItems().Single(); - var enumMemberDocumetation = enumType.Members.Single().Documentation; - - Assert.NotNull(enumMemberDocumetation); - Assert.Equal("Documentation - summary", enumMemberDocumetation.Summary); - Assert.Equal("Documentation - long description", enumMemberDocumetation.LongDescription); - } - - [Fact] - public void EnumType_contains_MetadataProperties() - { - var enumCsdl = -@" - - - - - -"; - - var edmItemCollection = new EdmItemCollection(new[] { XmlReader.Create(new StringReader(enumCsdl)) }); - - var enumType = edmItemCollection.GetItems().Single(); - - Assert.Equal("Color", enumType.MetadataProperties.Where(p => p.Name == "Name").Single().Value); - Assert.False((bool)enumType.MetadataProperties.Where(p => p.Name == "IsFlags").Single().Value); - Assert.Equal("Edm.Int32", enumType.MetadataProperties.Where(p => p.Name == "UnderlyingType").Single().Value.ToString()); - - var membersProperty = ((IEnumerable)enumType.MetadataProperties.Where(p => p.Name == "Members").Single().Value).ToList(); - - Assert.Equal(3, membersProperty.Count()); - Assert.Equal("Yellow", membersProperty[0].Name); - Assert.Equal(1, membersProperty[0].Value); - - Assert.Equal("Green", membersProperty[1].Name); - Assert.Equal(2, membersProperty[1].Value); - - Assert.Equal("Blue", membersProperty[2].Name); - Assert.Equal(3, membersProperty[2].Value); - } - - [Fact] - public void Clr_types_of_member_values_match_the_UnderlyingType() - { - var clrTypeForUndelryingType = new Dictionary() { - { "Byte", typeof(byte) }, - { "SByte", typeof(sbyte) }, - { "Int16", typeof(short) }, - { "Int32", typeof(int) }, - { "Int64", typeof(long) }, - { "Edm.Byte", typeof(byte) }, - { "Edm.SByte", typeof(sbyte) }, - { "Edm.Int16", typeof(short) }, - { "Edm.Int32", typeof(int) }, - { "Edm.Int64", typeof(long) }, - }; - - var enumCSDL = XDocument.Parse(enumCsdl); - var enumTypeElement = enumCSDL.Descendants(XName.Get("EnumType", edmNamespace)).Single(); - - foreach (var kvp in clrTypeForUndelryingType) - { - enumTypeElement.SetAttributeValue("UnderlyingType", kvp.Key); - var edmItemCollection = new EdmItemCollection(new XmlReader[] { enumCSDL.CreateReader() }); - var enumType = edmItemCollection.GetItems().Single(); - - Assert.False(enumType.Members.Any(m => m.Value.GetType() != kvp.Value)); - } - } - - [Fact] - public void Custom_MetadataProperties_are_populated_for_members_of_enum_type() - { - var enumCsdl = -@" - - - - - -"; - - var edmItemCollection = new EdmItemCollection(new[] { XmlReader.Create(new StringReader(enumCsdl)) }); - var enumMember = edmItemCollection.GetItems().Single().Members.First(); - - var customProperty = enumMember.MetadataProperties["http://tempuri.org:abc"]; - - Assert.Equal("xyz", customProperty.Value); - Assert.Equal(PropertyKind.Extended, customProperty.PropertyKind); - } - - [Fact] - public void Nullable_facet_on_EnumProperty_is_set_correctly() - { - foreach (var nullableFacetValue in new bool?[] { null, false, true }) - { - var csdl = XDocument.Parse(enumCsdl); - csdl.Descendants(XName.Get("Property", edmNamespace)) - .Where(p => (string)p.Attribute("Name") == "Color") - .Single() - .SetAttributeValue("Nullable", nullableFacetValue == null ? null : nullableFacetValue.ToString().ToLower()); - - var edmItemCollection = new EdmItemCollection(new XmlReader[] { csdl.CreateReader() }); - - Assert.Equal( - nullableFacetValue ?? true, - edmItemCollection.GetItems().Single().Properties.Single(p => p.Name == "Color").Nullable); - } - } - - [Fact] - public void Enum_values_with_facets_can_be_used_on_Parameter_element() - { - foreach (var nullableFacetValue in new bool?[] { null, false, true }) - { - VerifyFunctionDefinitionWithEnumsValid(XElement.Parse( -@" - - -"), - (edmFunction) => - { - Assert.Equal(BuiltInTypeKind.EnumType, edmFunction.Parameters.Single().TypeUsage.EdmType.BuiltInTypeKind); - Assert.Equal( - nullableFacetValue ?? true, - (bool)edmFunction.Parameters.Single().TypeUsage.Facets.Single(f => f.Name == "Nullable").Value); - }); - } - } - - [Fact] - public void Enum_ReturnTypes_with_facets_can_be_ised_on_Function_element() - { - foreach (var nullableFacetValue in new bool?[] { null, false, true }) - { - VerifyFunctionDefinitionWithEnumsValid(XElement.Parse( -@""), - (edmFunction) => - { - Assert.Equal(BuiltInTypeKind.EnumType, edmFunction.ReturnParameter.TypeUsage.EdmType.BuiltInTypeKind); - Assert.Equal( - nullableFacetValue ?? true, - (bool)edmFunction.ReturnParameter.TypeUsage.Facets.Single(f => f.Name == "Nullable").Value); - }); - } - } - - [Fact] - public void Enum_values_with_facets_can_be_used_on_ReturnType_element() - { - foreach (var nullableFacetValue in new bool?[] { null, false, true }) - { - VerifyFunctionDefinitionWithEnumsValid(XElement.Parse( -@" - -"), - (edmFunction) => - { - Assert.Equal(BuiltInTypeKind.EnumType, edmFunction.ReturnParameter.TypeUsage.EdmType.BuiltInTypeKind); - Assert.Equal( - nullableFacetValue ?? true, - (bool)edmFunction.ReturnParameter.TypeUsage.Facets.Single(f => f.Name == "Nullable").Value); - }); - } - } - - private static void VerifyFunctionDefinitionWithEnumsValid(XElement funcDefinition, Action verifyFunctionAction) - { - Assert.True(funcDefinition.Name.LocalName == "Function"); - Assert.True(funcDefinition.DescendantsAndSelf().Any(e => e.Attributes().Any(a => ((string)a).Contains("EnumTestModel.Color")))); - - var enumCSDL = XDocument.Parse(enumCsdl); - enumCSDL.Root.Add(funcDefinition); - - var edmItemCollection = new EdmItemCollection(new XmlReader[] { enumCSDL.CreateReader() }); - var function = edmItemCollection.GetItems().Where(f => f.Name == (string)funcDefinition.Attribute("Name")).Single(); - - verifyFunctionAction(function); - } - - private static string GetNullableFacetAttributeString(bool? nullableFacetValue) - { - return - nullableFacetValue != null ? - string.Format(@"Nullable=""{0}""", nullableFacetValue.ToString().ToLower()) : - string.Empty; - } - - [Fact] - public void Using_invalid_facets_on__EnumProperty_throws() - { - RunInvalidEnumTypeFacetTests((csdl, facetName, facetValue) => - { - csdl.Descendants(XName.Get("Property", edmNamespace)) - .Where(p => (string)p.Attribute("Name") == "Color") - .Single().SetAttributeValue(facetName, facetValue); - }); - } - - [Fact] - public void Using_invalid_facets_on_EnumFunction_param_throws() - { - RunInvalidEnumTypeFacetTests((csdl, facetName, facetValue) => - { - csdl.Root.Add(XElement.Parse(string.Format( -@" - -", facetName, facetValue))); - }); - } - - [Fact] - public void Using_invalid_facets_on_inline_EnumFunction_ReturnType_throws() - { - RunInvalidEnumTypeFacetTests((csdl, facetName, facetValue) => - { - csdl.Root.Add(XElement.Parse(string.Format( - @"", - facetName, facetValue))); - }); - } - - [Fact] - public void Using_invalidFacetsOnEnumFunctionReturnTypeThrows() - { - RunInvalidEnumTypeFacetTests((csdl, facetName, facetValue) => - { - csdl.Root.Add(XElement.Parse(string.Format( -@" - -", facetName, facetValue))); - }); - } - - [Fact] - public void Using_invalid_facets_on_Collection_of_Enum__for_function_ReturnType_throws() - { - RunInvalidEnumTypeFacetTests((csdl, facetName, facetValue) => - { - csdl.Root.Add(XElement.Parse(string.Format( -@" - - - -", facetName, facetValue))); - }); - } - - [Fact] - public void Using_invalid_facets_on_collection_of_Ref_Enum_for_function_ReturnType_throws() - { - RunInvalidEnumTypeFacetTests((csdl, facetName, facetValue) => - { - csdl.Root.Add(XElement.Parse(string.Format( -@" - - - - - -", facetName, facetValue))); - }); - } - - [Fact] - public void Using_invalid_facets_on_RowType_of_Collection_of_Enum_for_function_ReturnType_throws() - { - RunInvalidEnumTypeFacetTests((csdl, facetName, facetValue) => - { - csdl.Root.Add(XElement.Parse(string.Format( -@" - - - - - -", facetName, facetValue))); - }); - } - - private static string[,] invalidEnumPropertyFacets = - { - { "Collation", "Int32" }, - { "FixedLength", "false" }, - { "MaxLength", "30" }, - { "Precision", "3" }, - { "Scale", "2" }, - { "Unicode", "true" } - }; - - private static void RunInvalidEnumTypeFacetTests(Action updateCsdl) - { - for (int i = 0; i < invalidEnumPropertyFacets.Length >> 1; i++) - { - var enumCSDL = XDocument.Parse(enumCsdl); - updateCsdl(enumCSDL, invalidEnumPropertyFacets[i, 0], invalidEnumPropertyFacets[i, 1]); - - try - { - new EdmItemCollection(new XmlReader[] { enumCSDL.CreateReader() }); - - throw new AssertException("Expecting exception to be thrown during EdmItemCollection construction."); - } - catch (MetadataException ex) - { - Assert.True(ex.Message.Contains(invalidEnumPropertyFacets[i, 0] + " facet isn't allowed for properties of type EnumTestModel.Color"), "Unexpected exception\n: " + ex); - } - } - } - - [Fact] - public void Using_invalid_facets_on_FunctionImport_enum_parameter_throws() - { - string[,] funcImportInvalidEnumParamFacets = new string[8, 2]; - Array.Copy(invalidEnumPropertyFacets, funcImportInvalidEnumParamFacets, invalidEnumPropertyFacets.Length); - - funcImportInvalidEnumParamFacets[6, 0] = "Nullable"; - funcImportInvalidEnumParamFacets[6, 1] = "false"; - funcImportInvalidEnumParamFacets[7, 0] = "DefaultValue"; - funcImportInvalidEnumParamFacets[7, 1] = "34"; - - for (int i = 0; i < funcImportInvalidEnumParamFacets.Length >> 1; i++) - { - var enumCSDL = XDocument.Parse(enumCsdl); - enumCSDL.Root - .Descendants(XName.Get("EntityContainer", edmNamespace)) - .Single() - .Add(XElement.Parse(string.Format( -@" - -", funcImportInvalidEnumParamFacets[i, 0], funcImportInvalidEnumParamFacets[i, 1]))); - - try - { - new EdmItemCollection(new XmlReader[] { enumCSDL.CreateReader() }); - - // Should never get here - exception is expected - Assert.True(1 == 2); - } - catch (MetadataException ex) - { - if (new string[] { "MaxLength", "Precision", "Scale" }.Contains(funcImportInvalidEnumParamFacets[i, 0])) - { - Assert.True(ex.Message.Contains(funcImportInvalidEnumParamFacets[i, 0] + " facet isn't allowed for properties of type EnumTestModel.Color"), "Unexpected exception\n: " + ex); - } - else if (funcImportInvalidEnumParamFacets[i, 0] == "Nullable") - { - Assert.True(ex.Message.Contains("non-nullable"), "Unexpected exception\n: " + ex); - } - else - { - Assert.True(ex.Message.Contains("The '" + funcImportInvalidEnumParamFacets[i, 0] + "' attribute is not allowed"), "Unexpected exception\n: " + ex); - } - } - } - } - - [Fact] - public void Collection_of_enum_values_can_be_specified_as_FunctionImport_ReturnType() - { - var functionImportDefinitions = new XElement[] { - XElement.Parse(@""), - XElement.Parse( - @" - - "), - XElement.Parse( - @" - - - ") - }; - - foreach (var functionImportDefinition in functionImportDefinitions) - { - var enumCSDL = XDocument.Parse(enumCsdl); - enumCSDL.Root - .Descendants(XName.Get("EntityContainer", edmNamespace)) - .Single() - .Add(functionImportDefinition); - - var edmItemCollection = new EdmItemCollection(new XmlReader[] { enumCSDL.CreateReader() }); - var functionImport = edmItemCollection.GetItems().Single().FunctionImports.Single(f => f.Name == "TestFunc"); - - Assert.Equal(functionImportDefinition.Elements("{http://schemas.microsoft.com/ado/2009/11/edm}ReturnType").Count() + functionImportDefinition.Attributes("ReturnType").Count(), - functionImport.ReturnParameters.Count); - - foreach (var retParam in (IEnumerable)functionImport.ReturnParameters ?? new FunctionParameter[] { functionImport.ReturnParameter }) - { - var retParamEdmType = retParam.TypeUsage.EdmType; - - Assert.True(retParamEdmType is CollectionType); - Assert.Equal(((CollectionType)retParamEdmType).TypeUsage.EdmType.BuiltInTypeKind, BuiltInTypeKind.EnumType); - } - } - } - - [Fact] - public void Enum_type_with_code_generation_ExternalTypeName_attribute_is_valid() - { - var document = XDocument.Parse(enumCsdl); - var enumType = document.Descendants(XName.Get("EnumType", edmNamespace)).First(); - enumType.SetAttributeValue(XName.Get("ExternalTypeName", "http://schemas.microsoft.com/ado/2006/04/codegeneration"), "abc"); - - document.Validate(csdlSchemaSet, (o, e) => { throw e.Exception; }); - } - - [Fact] - public void Code_generation_ExternamTypeName_attribute_is_added_to_metadata_properties() - { - var document = XDocument.Parse(enumCsdl); - var enumType = document.Descendants(XName.Get("EnumType", edmNamespace)).First(); - enumType.SetAttributeValue(XName.Get("ExternalTypeName", "http://schemas.microsoft.com/ado/2006/04/codegeneration"), "abc"); - - var itemCollection = new EdmItemCollection(new[] { document.CreateReader() }); - - Assert.Equal( - "abc", - itemCollection.GetItems().Single().MetadataProperties.Single(m => m.Name == "http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName").Value); - } - - [Fact] - public void Validation_fails_for_enums_with_missing_EnumTypeName() - { - var csdl = XDocument.Parse(enumCsdl); - var enumType = csdl.Descendants(XName.Get("EnumType", edmNamespace)).First(); - enumType.Attributes("Name").Remove(); - - var exceptionMessage = string.Empty; - csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); - Assert.Equal("The required attribute 'Name' is missing.", exceptionMessage); - } - - [Fact] - public void Validation_fails_for_enums_with_empty_EnumTypeName() - { - var csdl = XDocument.Parse(enumCsdl); - var enumType = csdl.Descendants(XName.Get("EnumType", edmNamespace)).First(); - enumType.SetAttributeValue("Name", string.Empty); - - var exceptionMessage = string.Empty; - csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); - Assert.True(exceptionMessage.Contains("Name")); - Assert.True(exceptionMessage.Contains("http://schemas.microsoft.com/ado/2009/11/edm:TSimpleIdentifier")); - } - - [Fact] - public void Validation_fails_for_enums_with_empty_UnderlyingType_value() - { - var csdl = XDocument.Parse(enumCsdl); - var enumType = csdl.Descendants(XName.Get("EnumType", edmNamespace)).First(); - enumType.SetAttributeValue("UnderlyingType", string.Empty); - - var exceptionMessage = string.Empty; - csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); - Assert.True(exceptionMessage.Contains("UnderlyingType")); - Assert.True(exceptionMessage.Contains("http://schemas.microsoft.com/ado/2009/11/edm:TPropertyType")); - } - - [Fact] - public void Validation_fails_for_enums_with_empty_IsFlags_value() - { - var csdl = XDocument.Parse(enumCsdl); - var enumType = csdl.Descendants(XName.Get("EnumType", edmNamespace)).First(); - enumType.SetAttributeValue("IsFlags", string.Empty); - - var exceptionMessage = string.Empty; - csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); - Assert.True(exceptionMessage.Contains("IsFlags")); - Assert.True(exceptionMessage.Contains("http://www.w3.org/2001/XMLSchema:boolean")); - } - - [Fact] - public void Validation_fails_for_enums_with_invalid_IsFlags_value() - { - var csdl = XDocument.Parse(enumCsdl); - var enumType = csdl.Descendants(XName.Get("EnumType", edmNamespace)).First(); - enumType.SetAttributeValue("IsFlags", "abc"); - - var exceptionMessage = string.Empty; - csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); - Assert.True(exceptionMessage.Contains("IsFlags")); - Assert.True(exceptionMessage.Contains("abc")); - Assert.True(exceptionMessage.Contains("http://www.w3.org/2001/XMLSchema:boolean")); - } - - [Fact] - public void Validation_fails_for_enums_with_missing_enum_member_Name() - { - var csdl = XDocument.Parse(enumCsdl); - var enumMember = csdl.Descendants(XName.Get("Member", edmNamespace)).First(); - enumMember.Attributes("Name").Remove(); - - var exceptionMessage = string.Empty; - csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); - Assert.Equal("The required attribute 'Name' is missing.", exceptionMessage); - } - - [Fact] - public void Validation_fails_for_enums_with_empty_enum_member_Name() - { - var csdl = XDocument.Parse(enumCsdl); - var enumMember = csdl.Descendants(XName.Get("Member", edmNamespace)).First(); - enumMember.SetAttributeValue("Name", string.Empty); - - var exceptionMessage = string.Empty; - csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); - Assert.True(exceptionMessage.Contains("Name")); - Assert.True(exceptionMessage.Contains("http://schemas.microsoft.com/ado/2009/11/edm:TSimpleIdentifier")); - } - - [Fact] - public void Validation_fails_for_enums_with_empty_member_Value() - { - var csdl = XDocument.Parse(enumCsdl); - var enumMember = csdl.Descendants(XName.Get("Member", edmNamespace)).First(); - enumMember.SetAttributeValue("Value", string.Empty); - - var exceptionMessage = string.Empty; - csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); - Assert.True(exceptionMessage.Contains("Value")); - Assert.True(exceptionMessage.Contains("http://www.w3.org/2001/XMLSchema:long")); - } - - [Fact] - public void Validation_fails_for_enums_with_invalid_member_Value() - { - var csdl = XDocument.Parse(enumCsdl); - var enumMember = csdl.Descendants(XName.Get("Member", edmNamespace)).First(); - enumMember.SetAttributeValue("Value", "abc"); - - var exceptionMessage = string.Empty; - csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); - Assert.True(exceptionMessage.Contains("Value")); - Assert.True(exceptionMessage.Contains("abc")); - Assert.True(exceptionMessage.Contains("http://www.w3.org/2001/XMLSchema:long")); - } - - [Fact] - public void Validation_fails_for_enums_with_out_of_range_member_Value() - { - var csdl = XDocument.Parse(enumCsdl); - var enumMember = csdl.Descendants(XName.Get("Member", edmNamespace)).First(); - enumMember.SetAttributeValue("Value", new string('9', 30)); - - var exceptionMessage = string.Empty; - csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); - - Assert.True(exceptionMessage.Contains("Value")); - Assert.True(exceptionMessage.Contains("999999999999999999999999999999")); - Assert.True(exceptionMessage.Contains("http://www.w3.org/2001/XMLSchema:long")); - } - - [Fact] - public void Validation_fails_for_enum_with_duplicate_member() - { - var csdl = -@" - - - - - -"; - - var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { XmlReader.Create(new StringReader(csdl)) })).Message; - Assert.True(exceptionMessage.Contains(Strings.DuplicateEnumMember)); - } - - [Fact] - public void Validation_fails_for_enums_with_incorrect_UnderlyingType_String() - { - IncorrectUnderlyingType("String", Strings.InvalidEnumUnderlyingType); - } - - [Fact] - public void Validation_fails_for_enums_with_incorrect_UnderlyingType_ModelType() - { - IncorrectUnderlyingType("EnumTestModel.EnumTestEntity", Strings.InvalidEnumUnderlyingType); - } - - [Fact] - public void Validation_fails_for_enums_with_incorrect_UnderlyingType_SameEnumType() - { - IncorrectUnderlyingType("EnumTestModel.Color", Strings.InvalidEnumUnderlyingType); - } - - [Fact] - public void Validation_fails_for_enums_with_incorrect_UnderlyingType_NonExistingType() - { - IncorrectUnderlyingType("EnumTestModel.NonExistingType", Strings.NotInNamespaceNoAlias("NonExistingType", "EnumTestModel")); - } - - [Fact] - public void Validation_fails_for_enums_with_incorrect_UnderlyingType_InvalidEdmType() - { - IncorrectUnderlyingType("Edm.MyType", Strings.NotInNamespaceNoAlias("MyType", "Edm")); - } - - private void IncorrectUnderlyingType(string typeName, string expectedException) - { - var csdlDocument = XDocument.Parse(enumCsdl); - var enumType = csdlDocument.Descendants(XName.Get("EnumType", edmNamespace)).Single(); - enumType.SetAttributeValue("UnderlyingType", typeName); - - var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { csdlDocument.CreateReader() })).Message; - Assert.True(exceptionMessage.Contains(expectedException)); - } - - [Fact] - public void Validation_fails_for_enums_with_CalculatedValue_out_of_range() - { - var csdl = -@" - - - - -"; - - var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { XmlReader.Create(new StringReader(csdl)) })).Message; - Assert.True(exceptionMessage.Contains(Strings.CalculatedEnumValueOutOfRange)); - } - - [Fact] - public void Validation_fails_for_enums_with_SpecifiedValue_too_large_to_fit_in_Byte() - { - var value = (((long)Byte.MaxValue) + 1).ToString(); - RunUnderOverflowTestForExplicitlySpecifiedValues("Byte", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "Byte")); - } - - [Fact] - public void Validation_fails_for_enums_with_SpecifiedValue_cannot_be_converted_to_Byte() - { - var value = (((long)Byte.MinValue) - 1).ToString(); - RunUnderOverflowTestForExplicitlySpecifiedValues("Byte", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "Byte")); - } - - [Fact] - public void Validation_fails_for_enums_with_SpecifiedValue_too_large_to_fit_in_SByte() - { - var value = (((long)SByte.MaxValue) + 1).ToString(); - RunUnderOverflowTestForExplicitlySpecifiedValues("SByte", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "SByte")); - } - - [Fact] - public void Validation_fails_for_enums_with_SpecifiedValue_cannot_be_converted_to_SByte() - { - var value = (((long)SByte.MinValue) - 1).ToString(); - RunUnderOverflowTestForExplicitlySpecifiedValues("SByte", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "SByte")); - } - - [Fact] - public void Validation_fails_for_enums_with_SpecifiedValue_too_large_to_fit_in_Int16() - { - var value = (((long)Int16.MaxValue) + 1).ToString(); - RunUnderOverflowTestForExplicitlySpecifiedValues("Int16", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "Int16")); - } - - [Fact] - public void Validation_fails_for_enums_with_SpecifiedValue_cannot_be_converted_to_Int16() - { - var value = (((long)Int16.MinValue) - 1).ToString(); - RunUnderOverflowTestForExplicitlySpecifiedValues("Int16", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "Int16")); - } - - [Fact] - public void Validation_fails_for_enums_with_SpecifiedValue_too_large_to_fit_in_Int32() - { - var value = (((long)Int32.MaxValue) + 1).ToString(); - RunUnderOverflowTestForExplicitlySpecifiedValues("Int32", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "Int32")); - } - - [Fact] - public void Validation_fails_for_enums_with_SpecifiedValue_cannot_be_converted_to_Int32() - { - var value = (((long)Int32.MinValue) - 1).ToString(); - RunUnderOverflowTestForExplicitlySpecifiedValues("Int32", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "Int32")); - } - - [Fact] - public void Validation_fails_for_enums_with_SpecifiedValue_too_large_to_fit_in_Int64() - { - var value = ((long)Int64.MaxValue).ToString() + "1"; - RunUnderOverflowTestForExplicitlySpecifiedValues("Int64", value, "http://www.w3.org/2001/XMLSchema:long"); - } - - [Fact] - public void Validation_fails_for_enums_with_SpecifiedValue_cannot_be_converted_to_Int64() - { - var value = "-1" + ((long)Int64.MaxValue).ToString(); - RunUnderOverflowTestForExplicitlySpecifiedValues("Int64", value, "http://www.w3.org/2001/XMLSchema:long"); - } - - private static void RunUnderOverflowTestForExplicitlySpecifiedValues(string underlyingTypeName, string value, string expectedException) - { - var document = XDocument.Parse(enumCsdl); - var enumType = document.Descendants(XName.Get("EnumType", edmNamespace)).Single(); - enumType.SetAttributeValue("UnderlyingType", underlyingTypeName); - document.Descendants(XName.Get("Member", edmNamespace)) - .First() - .SetAttributeValue("Value", value); - - var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { document.CreateReader() })).Message; - Assert.True(exceptionMessage.Contains(expectedException)); - } - - [Fact] - public void Validation_fails_for_enums_with_CalculatedValue_too_large_to_fit_in_Byte() - { - var value = (long)Byte.MaxValue; - var exceptions = new [] - { - Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 1, "Green", "Byte"), - Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 2, "Blue", "Byte"), - }; - - RunOverflowTestsForCalculatedValues("Byte", value, exceptions); - } - - [Fact] - public void Validation_fails_for_enums_with_CalculatedValue_too_large_to_fit_in_SByte() - { - var value = (long)SByte.MaxValue; - var exceptions = new[] - { - Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 1, "Green", "SByte"), - Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 2, "Blue", "SByte"), - }; - - RunOverflowTestsForCalculatedValues("SByte", value, exceptions); - } - - [Fact] - public void Validation_fails_for_enums_with_CalculatedValue_too_large_to_fit_in_Int16() - { - var value = (long)Int16.MaxValue; - var exceptions = new[] - { - Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 1, "Green", "Int16"), - Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 2, "Blue", "Int16"), - }; - - RunOverflowTestsForCalculatedValues("Int16", value, exceptions); - } - - [Fact] - public void Validation_fails_for_enums_with_CalculatedValue_too_large_to_fit_in_Int32() - { - var value = (long)Int32.MaxValue; - var exceptions = new[] - { - Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 1, "Green", "Int32"), - Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 2, "Blue", "Int32"), - }; - - RunOverflowTestsForCalculatedValues("Int32", value, exceptions); - } - - private static void RunOverflowTestsForCalculatedValues(string underlyingTypeName, long lastSpecifiedValue, string[] expectedExceptions) - { - var document = XDocument.Parse(enumCsdl); - var enumType = document.Descendants(XName.Get("EnumType", edmNamespace)).Single(); - enumType.SetAttributeValue("UnderlyingType", underlyingTypeName); - document.Descendants(XName.Get("Member", edmNamespace)) - .First() - .SetAttributeValue("Value", lastSpecifiedValue); - - document.Descendants(XName.Get("Member", edmNamespace)) - .Skip(1) - .Attributes("Value") - .Remove(); - - var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { document.CreateReader() })).Message; - foreach (var expectedException in expectedExceptions) - { - Assert.True(exceptionMessage.Contains(expectedException)); - } - } - - [Fact] - public void DefaultValue_not_supported_for_enum_properties() - { - var csdl = @" - - - - - - - - - - -"; - - var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { XmlReader.Create(new StringReader(csdl)) })).Message; - Assert.True(exceptionMessage.Contains(Strings.DefaultNotAllowed)); - } - } - - public class MetadataEnumFixture - { - public XmlSchemaSet CsdlSchemaSet { get; private set; } - - public MetadataEnumFixture() - { - this.CsdlSchemaSet = new XmlSchemaSet(); - - foreach (var schemaName in new string[] { - "System.Data.Resources.CSDLSchema_3.xsd", - "System.Data.Resources.CodeGenerationSchema.xsd", - "System.Data.Resources.AnnotationSchema.xsd"}) - { - this.CsdlSchemaSet.Add(XmlSchema.Read( - typeof(EntityContainer).Assembly.GetManifestResourceStream(schemaName), - (o, e) => { throw new InvalidOperationException("The built-in schema is invalid", e.Exception); })); - } - - this.CsdlSchemaSet.Compile(); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Metadata +{ + using System; + using System.Collections.Generic; + using System.Data.Entity.Core; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.Resources; + using System.IO; + using System.Linq; + using System.Xml; + using System.Xml.Linq; + using System.Xml.Schema; + using Xunit; + using Xunit.Sdk; + + public class MetadataEnumTests : FunctionalTestBase, IUseFixture + { + private const string enumCsdl = +@" + + + + + + + + + + + + + + + +"; + + private const string edmNamespace = "http://schemas.microsoft.com/ado/2009/11/edm"; + + private XmlSchemaSet csdlSchemaSet; + + public void SetFixture(MetadataEnumFixture data) + { + csdlSchemaSet = data.CsdlSchemaSet; + } + + [Fact] + public void Empty_enum_is_valid() + { + var emptyEnum = +@" + + +"; + + var edmItemCollection = new EdmItemCollection(new[] { XmlReader.Create(new StringReader(emptyEnum)) }); + var enumType = edmItemCollection.GetItems().Single(); + + Assert.Equal(0, enumType.Members.Count); + } + + [Fact] + public void SchemaSource_metadata_property_is_populated() + { + var edmItemCollection = new EdmItemCollection(new[] { XmlReader.Create(new StringReader(enumCsdl)) }); + var enumType = edmItemCollection.GetItems().Single(); + + var schemaSource = enumType.MetadataProperties["SchemaSource"]; + Assert.Equal(PropertyKind.System, schemaSource.PropertyKind); + } + + [Fact] + public void Documenation_is_populated_correctly_for_enum_type() + { + var enumWithDocumentation = +@" + + + Documentation - summary + Documentation - long description + + + +"; + + var edmItemCollection = new EdmItemCollection(new[] { XmlReader.Create(new StringReader(enumWithDocumentation)) }); + var enumType = edmItemCollection.GetItems().Single(); + + Assert.NotNull(enumType.Documentation); + Assert.Equal("Documentation - summary", enumType.Documentation.Summary); + Assert.Equal("Documentation - long description", enumType.Documentation.LongDescription); + } + + [Fact] + public void Documenation_is_populated_correctly_for_members_of_enum_type() + { + var enumWithDocumentation = +@" + + + + Documentation - summary + Documentation - long description + + + +"; + + var edmItemCollection = new EdmItemCollection(new[] { XmlReader.Create(new StringReader(enumWithDocumentation)) }); + var enumType = edmItemCollection.GetItems().Single(); + var enumMemberDocumetation = enumType.Members.Single().Documentation; + + Assert.NotNull(enumMemberDocumetation); + Assert.Equal("Documentation - summary", enumMemberDocumetation.Summary); + Assert.Equal("Documentation - long description", enumMemberDocumetation.LongDescription); + } + + [Fact] + public void EnumType_contains_MetadataProperties() + { + var enumCsdl = +@" + + + + + +"; + + var edmItemCollection = new EdmItemCollection(new[] { XmlReader.Create(new StringReader(enumCsdl)) }); + + var enumType = edmItemCollection.GetItems().Single(); + + Assert.Equal("Color", enumType.MetadataProperties.Where(p => p.Name == "Name").Single().Value); + Assert.False((bool)enumType.MetadataProperties.Where(p => p.Name == "IsFlags").Single().Value); + Assert.Equal("Edm.Int32", enumType.MetadataProperties.Where(p => p.Name == "UnderlyingType").Single().Value.ToString()); + + var membersProperty = ((IEnumerable)enumType.MetadataProperties.Where(p => p.Name == "Members").Single().Value).ToList(); + + Assert.Equal(3, membersProperty.Count()); + Assert.Equal("Yellow", membersProperty[0].Name); + Assert.Equal(1, membersProperty[0].Value); + + Assert.Equal("Green", membersProperty[1].Name); + Assert.Equal(2, membersProperty[1].Value); + + Assert.Equal("Blue", membersProperty[2].Name); + Assert.Equal(3, membersProperty[2].Value); + } + + [Fact] + public void Clr_types_of_member_values_match_the_UnderlyingType() + { + var clrTypeForUndelryingType = new Dictionary() { + { "Byte", typeof(byte) }, + { "SByte", typeof(sbyte) }, + { "Int16", typeof(short) }, + { "Int32", typeof(int) }, + { "Int64", typeof(long) }, + { "Edm.Byte", typeof(byte) }, + { "Edm.SByte", typeof(sbyte) }, + { "Edm.Int16", typeof(short) }, + { "Edm.Int32", typeof(int) }, + { "Edm.Int64", typeof(long) }, + }; + + var enumCSDL = XDocument.Parse(enumCsdl); + var enumTypeElement = enumCSDL.Descendants(XName.Get("EnumType", edmNamespace)).Single(); + + foreach (var kvp in clrTypeForUndelryingType) + { + enumTypeElement.SetAttributeValue("UnderlyingType", kvp.Key); + var edmItemCollection = new EdmItemCollection(new XmlReader[] { enumCSDL.CreateReader() }); + var enumType = edmItemCollection.GetItems().Single(); + + Assert.False(enumType.Members.Any(m => m.Value.GetType() != kvp.Value)); + } + } + + [Fact] + public void Custom_MetadataProperties_are_populated_for_members_of_enum_type() + { + var enumCsdl = +@" + + + + + +"; + + var edmItemCollection = new EdmItemCollection(new[] { XmlReader.Create(new StringReader(enumCsdl)) }); + var enumMember = edmItemCollection.GetItems().Single().Members.First(); + + var customProperty = enumMember.MetadataProperties["http://tempuri.org:abc"]; + + Assert.Equal("xyz", customProperty.Value); + Assert.Equal(PropertyKind.Extended, customProperty.PropertyKind); + } + + [Fact] + public void Nullable_facet_on_EnumProperty_is_set_correctly() + { + foreach (var nullableFacetValue in new bool?[] { null, false, true }) + { + var csdl = XDocument.Parse(enumCsdl); + csdl.Descendants(XName.Get("Property", edmNamespace)) + .Where(p => (string)p.Attribute("Name") == "Color") + .Single() + .SetAttributeValue("Nullable", nullableFacetValue == null ? null : nullableFacetValue.ToString().ToLower()); + + var edmItemCollection = new EdmItemCollection(new XmlReader[] { csdl.CreateReader() }); + + Assert.Equal( + nullableFacetValue ?? true, + edmItemCollection.GetItems().Single().Properties.Single(p => p.Name == "Color").Nullable); + } + } + + [Fact] + public void Enum_values_with_facets_can_be_used_on_Parameter_element() + { + foreach (var nullableFacetValue in new bool?[] { null, false, true }) + { + VerifyFunctionDefinitionWithEnumsValid(XElement.Parse( +@" + + +"), + (edmFunction) => + { + Assert.Equal(BuiltInTypeKind.EnumType, edmFunction.Parameters.Single().TypeUsage.EdmType.BuiltInTypeKind); + Assert.Equal( + nullableFacetValue ?? true, + (bool)edmFunction.Parameters.Single().TypeUsage.Facets.Single(f => f.Name == "Nullable").Value); + }); + } + } + + [Fact] + public void Enum_ReturnTypes_with_facets_can_be_ised_on_Function_element() + { + foreach (var nullableFacetValue in new bool?[] { null, false, true }) + { + VerifyFunctionDefinitionWithEnumsValid(XElement.Parse( +@""), + (edmFunction) => + { + Assert.Equal(BuiltInTypeKind.EnumType, edmFunction.ReturnParameter.TypeUsage.EdmType.BuiltInTypeKind); + Assert.Equal( + nullableFacetValue ?? true, + (bool)edmFunction.ReturnParameter.TypeUsage.Facets.Single(f => f.Name == "Nullable").Value); + }); + } + } + + [Fact] + public void Enum_values_with_facets_can_be_used_on_ReturnType_element() + { + foreach (var nullableFacetValue in new bool?[] { null, false, true }) + { + VerifyFunctionDefinitionWithEnumsValid(XElement.Parse( +@" + +"), + (edmFunction) => + { + Assert.Equal(BuiltInTypeKind.EnumType, edmFunction.ReturnParameter.TypeUsage.EdmType.BuiltInTypeKind); + Assert.Equal( + nullableFacetValue ?? true, + (bool)edmFunction.ReturnParameter.TypeUsage.Facets.Single(f => f.Name == "Nullable").Value); + }); + } + } + + private static void VerifyFunctionDefinitionWithEnumsValid(XElement funcDefinition, Action verifyFunctionAction) + { + Assert.True(funcDefinition.Name.LocalName == "Function"); + Assert.True(funcDefinition.DescendantsAndSelf().Any(e => e.Attributes().Any(a => ((string)a).Contains("EnumTestModel.Color")))); + + var enumCSDL = XDocument.Parse(enumCsdl); + enumCSDL.Root.Add(funcDefinition); + + var edmItemCollection = new EdmItemCollection(new XmlReader[] { enumCSDL.CreateReader() }); + var function = edmItemCollection.GetItems().Where(f => f.Name == (string)funcDefinition.Attribute("Name")).Single(); + + verifyFunctionAction(function); + } + + private static string GetNullableFacetAttributeString(bool? nullableFacetValue) + { + return + nullableFacetValue != null ? + string.Format(@"Nullable=""{0}""", nullableFacetValue.ToString().ToLower()) : + string.Empty; + } + + [Fact] + public void Using_invalid_facets_on__EnumProperty_throws() + { + RunInvalidEnumTypeFacetTests((csdl, facetName, facetValue) => + { + csdl.Descendants(XName.Get("Property", edmNamespace)) + .Where(p => (string)p.Attribute("Name") == "Color") + .Single().SetAttributeValue(facetName, facetValue); + }); + } + + [Fact] + public void Using_invalid_facets_on_EnumFunction_param_throws() + { + RunInvalidEnumTypeFacetTests((csdl, facetName, facetValue) => + { + csdl.Root.Add(XElement.Parse(string.Format( +@" + +", facetName, facetValue))); + }); + } + + [Fact] + public void Using_invalid_facets_on_inline_EnumFunction_ReturnType_throws() + { + RunInvalidEnumTypeFacetTests((csdl, facetName, facetValue) => + { + csdl.Root.Add(XElement.Parse(string.Format( + @"", + facetName, facetValue))); + }); + } + + [Fact] + public void Using_invalidFacetsOnEnumFunctionReturnTypeThrows() + { + RunInvalidEnumTypeFacetTests((csdl, facetName, facetValue) => + { + csdl.Root.Add(XElement.Parse(string.Format( +@" + +", facetName, facetValue))); + }); + } + + [Fact] + public void Using_invalid_facets_on_Collection_of_Enum__for_function_ReturnType_throws() + { + RunInvalidEnumTypeFacetTests((csdl, facetName, facetValue) => + { + csdl.Root.Add(XElement.Parse(string.Format( +@" + + + +", facetName, facetValue))); + }); + } + + [Fact] + public void Using_invalid_facets_on_collection_of_Ref_Enum_for_function_ReturnType_throws() + { + RunInvalidEnumTypeFacetTests((csdl, facetName, facetValue) => + { + csdl.Root.Add(XElement.Parse(string.Format( +@" + + + + + +", facetName, facetValue))); + }); + } + + [Fact] + public void Using_invalid_facets_on_RowType_of_Collection_of_Enum_for_function_ReturnType_throws() + { + RunInvalidEnumTypeFacetTests((csdl, facetName, facetValue) => + { + csdl.Root.Add(XElement.Parse(string.Format( +@" + + + + + +", facetName, facetValue))); + }); + } + + private static string[,] invalidEnumPropertyFacets = + { + { "Collation", "Int32" }, + { "FixedLength", "false" }, + { "MaxLength", "30" }, + { "Precision", "3" }, + { "Scale", "2" }, + { "Unicode", "true" } + }; + + private static void RunInvalidEnumTypeFacetTests(Action updateCsdl) + { + for (int i = 0; i < invalidEnumPropertyFacets.Length >> 1; i++) + { + var enumCSDL = XDocument.Parse(enumCsdl); + updateCsdl(enumCSDL, invalidEnumPropertyFacets[i, 0], invalidEnumPropertyFacets[i, 1]); + + try + { + new EdmItemCollection(new XmlReader[] { enumCSDL.CreateReader() }); + + throw new AssertException("Expecting exception to be thrown during EdmItemCollection construction."); + } + catch (MetadataException ex) + { + Assert.True(ex.Message.Contains(invalidEnumPropertyFacets[i, 0] + " facet isn't allowed for properties of type EnumTestModel.Color"), "Unexpected exception\n: " + ex); + } + } + } + + [Fact] + public void Using_invalid_facets_on_FunctionImport_enum_parameter_throws() + { + string[,] funcImportInvalidEnumParamFacets = new string[8, 2]; + Array.Copy(invalidEnumPropertyFacets, funcImportInvalidEnumParamFacets, invalidEnumPropertyFacets.Length); + + funcImportInvalidEnumParamFacets[6, 0] = "Nullable"; + funcImportInvalidEnumParamFacets[6, 1] = "false"; + funcImportInvalidEnumParamFacets[7, 0] = "DefaultValue"; + funcImportInvalidEnumParamFacets[7, 1] = "34"; + + for (int i = 0; i < funcImportInvalidEnumParamFacets.Length >> 1; i++) + { + var enumCSDL = XDocument.Parse(enumCsdl); + enumCSDL.Root + .Descendants(XName.Get("EntityContainer", edmNamespace)) + .Single() + .Add(XElement.Parse(string.Format( +@" + +", funcImportInvalidEnumParamFacets[i, 0], funcImportInvalidEnumParamFacets[i, 1]))); + + try + { + new EdmItemCollection(new XmlReader[] { enumCSDL.CreateReader() }); + + // Should never get here - exception is expected + Assert.True(1 == 2); + } + catch (MetadataException ex) + { + if (new string[] { "MaxLength", "Precision", "Scale" }.Contains(funcImportInvalidEnumParamFacets[i, 0])) + { + Assert.True(ex.Message.Contains(funcImportInvalidEnumParamFacets[i, 0] + " facet isn't allowed for properties of type EnumTestModel.Color"), "Unexpected exception\n: " + ex); + } + else if (funcImportInvalidEnumParamFacets[i, 0] == "Nullable") + { + Assert.True(ex.Message.Contains("non-nullable"), "Unexpected exception\n: " + ex); + } + else + { + Assert.True(ex.Message.Contains("The '" + funcImportInvalidEnumParamFacets[i, 0] + "' attribute is not allowed"), "Unexpected exception\n: " + ex); + } + } + } + } + + [Fact] + public void Collection_of_enum_values_can_be_specified_as_FunctionImport_ReturnType() + { + var functionImportDefinitions = new XElement[] { + XElement.Parse(@""), + XElement.Parse( + @" + + "), + XElement.Parse( + @" + + + ") + }; + + foreach (var functionImportDefinition in functionImportDefinitions) + { + var enumCSDL = XDocument.Parse(enumCsdl); + enumCSDL.Root + .Descendants(XName.Get("EntityContainer", edmNamespace)) + .Single() + .Add(functionImportDefinition); + + var edmItemCollection = new EdmItemCollection(new XmlReader[] { enumCSDL.CreateReader() }); + var functionImport = edmItemCollection.GetItems().Single().FunctionImports.Single(f => f.Name == "TestFunc"); + + Assert.Equal(functionImportDefinition.Elements("{http://schemas.microsoft.com/ado/2009/11/edm}ReturnType").Count() + functionImportDefinition.Attributes("ReturnType").Count(), + functionImport.ReturnParameters.Count); + + foreach (var retParam in (IEnumerable)functionImport.ReturnParameters ?? new FunctionParameter[] { functionImport.ReturnParameter }) + { + var retParamEdmType = retParam.TypeUsage.EdmType; + + Assert.True(retParamEdmType is CollectionType); + Assert.Equal(((CollectionType)retParamEdmType).TypeUsage.EdmType.BuiltInTypeKind, BuiltInTypeKind.EnumType); + } + } + } + + [Fact] + public void Enum_type_with_code_generation_ExternalTypeName_attribute_is_valid() + { + var document = XDocument.Parse(enumCsdl); + var enumType = document.Descendants(XName.Get("EnumType", edmNamespace)).First(); + enumType.SetAttributeValue(XName.Get("ExternalTypeName", "http://schemas.microsoft.com/ado/2006/04/codegeneration"), "abc"); + + document.Validate(csdlSchemaSet, (o, e) => { throw e.Exception; }); + } + + [Fact] + public void Code_generation_ExternamTypeName_attribute_is_added_to_metadata_properties() + { + var document = XDocument.Parse(enumCsdl); + var enumType = document.Descendants(XName.Get("EnumType", edmNamespace)).First(); + enumType.SetAttributeValue(XName.Get("ExternalTypeName", "http://schemas.microsoft.com/ado/2006/04/codegeneration"), "abc"); + + var itemCollection = new EdmItemCollection(new[] { document.CreateReader() }); + + Assert.Equal( + "abc", + itemCollection.GetItems().Single().MetadataProperties.Single(m => m.Name == "http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName").Value); + } + + [Fact] + public void Validation_fails_for_enums_with_missing_EnumTypeName() + { + var csdl = XDocument.Parse(enumCsdl); + var enumType = csdl.Descendants(XName.Get("EnumType", edmNamespace)).First(); + enumType.Attributes("Name").Remove(); + + var exceptionMessage = string.Empty; + csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); + Assert.Equal("The required attribute 'Name' is missing.", exceptionMessage); + } + + [Fact] + public void Validation_fails_for_enums_with_empty_EnumTypeName() + { + var csdl = XDocument.Parse(enumCsdl); + var enumType = csdl.Descendants(XName.Get("EnumType", edmNamespace)).First(); + enumType.SetAttributeValue("Name", string.Empty); + + var exceptionMessage = string.Empty; + csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); + Assert.True(exceptionMessage.Contains("Name")); + Assert.True(exceptionMessage.Contains("http://schemas.microsoft.com/ado/2009/11/edm:TSimpleIdentifier")); + } + + [Fact] + public void Validation_fails_for_enums_with_empty_UnderlyingType_value() + { + var csdl = XDocument.Parse(enumCsdl); + var enumType = csdl.Descendants(XName.Get("EnumType", edmNamespace)).First(); + enumType.SetAttributeValue("UnderlyingType", string.Empty); + + var exceptionMessage = string.Empty; + csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); + Assert.True(exceptionMessage.Contains("UnderlyingType")); + Assert.True(exceptionMessage.Contains("http://schemas.microsoft.com/ado/2009/11/edm:TPropertyType")); + } + + [Fact] + public void Validation_fails_for_enums_with_empty_IsFlags_value() + { + var csdl = XDocument.Parse(enumCsdl); + var enumType = csdl.Descendants(XName.Get("EnumType", edmNamespace)).First(); + enumType.SetAttributeValue("IsFlags", string.Empty); + + var exceptionMessage = string.Empty; + csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); + Assert.True(exceptionMessage.Contains("IsFlags")); + Assert.True(exceptionMessage.Contains("http://www.w3.org/2001/XMLSchema:boolean")); + } + + [Fact] + public void Validation_fails_for_enums_with_invalid_IsFlags_value() + { + var csdl = XDocument.Parse(enumCsdl); + var enumType = csdl.Descendants(XName.Get("EnumType", edmNamespace)).First(); + enumType.SetAttributeValue("IsFlags", "abc"); + + var exceptionMessage = string.Empty; + csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); + Assert.True(exceptionMessage.Contains("IsFlags")); + Assert.True(exceptionMessage.Contains("abc")); + Assert.True(exceptionMessage.Contains("http://www.w3.org/2001/XMLSchema:boolean")); + } + + [Fact] + public void Validation_fails_for_enums_with_missing_enum_member_Name() + { + var csdl = XDocument.Parse(enumCsdl); + var enumMember = csdl.Descendants(XName.Get("Member", edmNamespace)).First(); + enumMember.Attributes("Name").Remove(); + + var exceptionMessage = string.Empty; + csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); + Assert.Equal("The required attribute 'Name' is missing.", exceptionMessage); + } + + [Fact] + public void Validation_fails_for_enums_with_empty_enum_member_Name() + { + var csdl = XDocument.Parse(enumCsdl); + var enumMember = csdl.Descendants(XName.Get("Member", edmNamespace)).First(); + enumMember.SetAttributeValue("Name", string.Empty); + + var exceptionMessage = string.Empty; + csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); + Assert.True(exceptionMessage.Contains("Name")); + Assert.True(exceptionMessage.Contains("http://schemas.microsoft.com/ado/2009/11/edm:TSimpleIdentifier")); + } + + [Fact] + public void Validation_fails_for_enums_with_empty_member_Value() + { + var csdl = XDocument.Parse(enumCsdl); + var enumMember = csdl.Descendants(XName.Get("Member", edmNamespace)).First(); + enumMember.SetAttributeValue("Value", string.Empty); + + var exceptionMessage = string.Empty; + csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); + Assert.True(exceptionMessage.Contains("Value")); + Assert.True(exceptionMessage.Contains("http://www.w3.org/2001/XMLSchema:long")); + } + + [Fact] + public void Validation_fails_for_enums_with_invalid_member_Value() + { + var csdl = XDocument.Parse(enumCsdl); + var enumMember = csdl.Descendants(XName.Get("Member", edmNamespace)).First(); + enumMember.SetAttributeValue("Value", "abc"); + + var exceptionMessage = string.Empty; + csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); + Assert.True(exceptionMessage.Contains("Value")); + Assert.True(exceptionMessage.Contains("abc")); + Assert.True(exceptionMessage.Contains("http://www.w3.org/2001/XMLSchema:long")); + } + + [Fact] + public void Validation_fails_for_enums_with_out_of_range_member_Value() + { + var csdl = XDocument.Parse(enumCsdl); + var enumMember = csdl.Descendants(XName.Get("Member", edmNamespace)).First(); + enumMember.SetAttributeValue("Value", new string('9', 30)); + + var exceptionMessage = string.Empty; + csdl.Validate(csdlSchemaSet, (o, e) => exceptionMessage = e.Message); + + Assert.True(exceptionMessage.Contains("Value")); + Assert.True(exceptionMessage.Contains("999999999999999999999999999999")); + Assert.True(exceptionMessage.Contains("http://www.w3.org/2001/XMLSchema:long")); + } + + [Fact] + public void Validation_fails_for_enum_with_duplicate_member() + { + var csdl = +@" + + + + + +"; + + var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { XmlReader.Create(new StringReader(csdl)) })).Message; + Assert.True(exceptionMessage.Contains(Strings.DuplicateEnumMember)); + } + + [Fact] + public void Validation_fails_for_enums_with_incorrect_UnderlyingType_String() + { + IncorrectUnderlyingType("String", Strings.InvalidEnumUnderlyingType); + } + + [Fact] + public void Validation_fails_for_enums_with_incorrect_UnderlyingType_ModelType() + { + IncorrectUnderlyingType("EnumTestModel.EnumTestEntity", Strings.InvalidEnumUnderlyingType); + } + + [Fact] + public void Validation_fails_for_enums_with_incorrect_UnderlyingType_SameEnumType() + { + IncorrectUnderlyingType("EnumTestModel.Color", Strings.InvalidEnumUnderlyingType); + } + + [Fact] + public void Validation_fails_for_enums_with_incorrect_UnderlyingType_NonExistingType() + { + IncorrectUnderlyingType("EnumTestModel.NonExistingType", Strings.NotInNamespaceNoAlias("NonExistingType", "EnumTestModel")); + } + + [Fact] + public void Validation_fails_for_enums_with_incorrect_UnderlyingType_InvalidEdmType() + { + IncorrectUnderlyingType("Edm.MyType", Strings.NotInNamespaceNoAlias("MyType", "Edm")); + } + + private void IncorrectUnderlyingType(string typeName, string expectedException) + { + var csdlDocument = XDocument.Parse(enumCsdl); + var enumType = csdlDocument.Descendants(XName.Get("EnumType", edmNamespace)).Single(); + enumType.SetAttributeValue("UnderlyingType", typeName); + + var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { csdlDocument.CreateReader() })).Message; + Assert.True(exceptionMessage.Contains(expectedException)); + } + + [Fact] + public void Validation_fails_for_enums_with_CalculatedValue_out_of_range() + { + var csdl = +@" + + + + +"; + + var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { XmlReader.Create(new StringReader(csdl)) })).Message; + Assert.True(exceptionMessage.Contains(Strings.CalculatedEnumValueOutOfRange)); + } + + [Fact] + public void Validation_fails_for_enums_with_SpecifiedValue_too_large_to_fit_in_Byte() + { + var value = (((long)Byte.MaxValue) + 1).ToString(); + RunUnderOverflowTestForExplicitlySpecifiedValues("Byte", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "Byte")); + } + + [Fact] + public void Validation_fails_for_enums_with_SpecifiedValue_cannot_be_converted_to_Byte() + { + var value = (((long)Byte.MinValue) - 1).ToString(); + RunUnderOverflowTestForExplicitlySpecifiedValues("Byte", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "Byte")); + } + + [Fact] + public void Validation_fails_for_enums_with_SpecifiedValue_too_large_to_fit_in_SByte() + { + var value = (((long)SByte.MaxValue) + 1).ToString(); + RunUnderOverflowTestForExplicitlySpecifiedValues("SByte", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "SByte")); + } + + [Fact] + public void Validation_fails_for_enums_with_SpecifiedValue_cannot_be_converted_to_SByte() + { + var value = (((long)SByte.MinValue) - 1).ToString(); + RunUnderOverflowTestForExplicitlySpecifiedValues("SByte", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "SByte")); + } + + [Fact] + public void Validation_fails_for_enums_with_SpecifiedValue_too_large_to_fit_in_Int16() + { + var value = (((long)Int16.MaxValue) + 1).ToString(); + RunUnderOverflowTestForExplicitlySpecifiedValues("Int16", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "Int16")); + } + + [Fact] + public void Validation_fails_for_enums_with_SpecifiedValue_cannot_be_converted_to_Int16() + { + var value = (((long)Int16.MinValue) - 1).ToString(); + RunUnderOverflowTestForExplicitlySpecifiedValues("Int16", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "Int16")); + } + + [Fact] + public void Validation_fails_for_enums_with_SpecifiedValue_too_large_to_fit_in_Int32() + { + var value = (((long)Int32.MaxValue) + 1).ToString(); + RunUnderOverflowTestForExplicitlySpecifiedValues("Int32", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "Int32")); + } + + [Fact] + public void Validation_fails_for_enums_with_SpecifiedValue_cannot_be_converted_to_Int32() + { + var value = (((long)Int32.MinValue) - 1).ToString(); + RunUnderOverflowTestForExplicitlySpecifiedValues("Int32", value, Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value, "Yellow", "Int32")); + } + + [Fact] + public void Validation_fails_for_enums_with_SpecifiedValue_too_large_to_fit_in_Int64() + { + var value = ((long)Int64.MaxValue).ToString() + "1"; + RunUnderOverflowTestForExplicitlySpecifiedValues("Int64", value, "http://www.w3.org/2001/XMLSchema:long"); + } + + [Fact] + public void Validation_fails_for_enums_with_SpecifiedValue_cannot_be_converted_to_Int64() + { + var value = "-1" + ((long)Int64.MaxValue).ToString(); + RunUnderOverflowTestForExplicitlySpecifiedValues("Int64", value, "http://www.w3.org/2001/XMLSchema:long"); + } + + private static void RunUnderOverflowTestForExplicitlySpecifiedValues(string underlyingTypeName, string value, string expectedException) + { + var document = XDocument.Parse(enumCsdl); + var enumType = document.Descendants(XName.Get("EnumType", edmNamespace)).Single(); + enumType.SetAttributeValue("UnderlyingType", underlyingTypeName); + document.Descendants(XName.Get("Member", edmNamespace)) + .First() + .SetAttributeValue("Value", value); + + var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { document.CreateReader() })).Message; + Assert.True(exceptionMessage.Contains(expectedException)); + } + + [Fact] + public void Validation_fails_for_enums_with_CalculatedValue_too_large_to_fit_in_Byte() + { + var value = (long)Byte.MaxValue; + var exceptions = new [] + { + Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 1, "Green", "Byte"), + Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 2, "Blue", "Byte"), + }; + + RunOverflowTestsForCalculatedValues("Byte", value, exceptions); + } + + [Fact] + public void Validation_fails_for_enums_with_CalculatedValue_too_large_to_fit_in_SByte() + { + var value = (long)SByte.MaxValue; + var exceptions = new[] + { + Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 1, "Green", "SByte"), + Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 2, "Blue", "SByte"), + }; + + RunOverflowTestsForCalculatedValues("SByte", value, exceptions); + } + + [Fact] + public void Validation_fails_for_enums_with_CalculatedValue_too_large_to_fit_in_Int16() + { + var value = (long)Int16.MaxValue; + var exceptions = new[] + { + Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 1, "Green", "Int16"), + Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 2, "Blue", "Int16"), + }; + + RunOverflowTestsForCalculatedValues("Int16", value, exceptions); + } + + [Fact] + public void Validation_fails_for_enums_with_CalculatedValue_too_large_to_fit_in_Int32() + { + var value = (long)Int32.MaxValue; + var exceptions = new[] + { + Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 1, "Green", "Int32"), + Strings.EnumMemberValueOutOfItsUnderylingTypeRange(value + 2, "Blue", "Int32"), + }; + + RunOverflowTestsForCalculatedValues("Int32", value, exceptions); + } + + private static void RunOverflowTestsForCalculatedValues(string underlyingTypeName, long lastSpecifiedValue, string[] expectedExceptions) + { + var document = XDocument.Parse(enumCsdl); + var enumType = document.Descendants(XName.Get("EnumType", edmNamespace)).Single(); + enumType.SetAttributeValue("UnderlyingType", underlyingTypeName); + document.Descendants(XName.Get("Member", edmNamespace)) + .First() + .SetAttributeValue("Value", lastSpecifiedValue); + + document.Descendants(XName.Get("Member", edmNamespace)) + .Skip(1) + .Attributes("Value") + .Remove(); + + var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { document.CreateReader() })).Message; + foreach (var expectedException in expectedExceptions) + { + Assert.True(exceptionMessage.Contains(expectedException)); + } + } + + [Fact] + public void DefaultValue_not_supported_for_enum_properties() + { + var csdl = @" + + + + + + + + + + +"; + + var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { XmlReader.Create(new StringReader(csdl)) })).Message; + Assert.True(exceptionMessage.Contains(Strings.DefaultNotAllowed)); + } + } + + public class MetadataEnumFixture + { + public XmlSchemaSet CsdlSchemaSet { get; private set; } + + public MetadataEnumFixture() + { + this.CsdlSchemaSet = new XmlSchemaSet(); + + foreach (var schemaName in new string[] { + "System.Data.Resources.CSDLSchema_3.xsd", + "System.Data.Resources.CodeGenerationSchema.xsd", + "System.Data.Resources.AnnotationSchema.xsd"}) + { + this.CsdlSchemaSet.Add(XmlSchema.Read( + typeof(EntityContainer).Assembly.GetManifestResourceStream(schemaName), + (o, e) => { throw new InvalidOperationException("The built-in schema is invalid", e.Exception); })); + } + + this.CsdlSchemaSet.Compile(); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/Metadata/MetadataFunctionsTests.cs b/test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataFunctionsTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/Metadata/MetadataFunctionsTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataFunctionsTests.cs index 165bb745..33c129c0 100644 --- a/test/EntityFramework/FunctionalTests/Metadata/MetadataFunctionsTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataFunctionsTests.cs @@ -1,424 +1,424 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Metadata -{ - using System; - using System.Data.Entity.Core; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.Resources; - using System.Globalization; - using System.IO; - using System.Xml; - using Xunit; - - public class MetadataFunctionsTests : FunctionalTestBase - { - [Fact] - public void Exception_thrown_when_loading_ssdl_containing_functions_with_duplicate_overloads() - { - var ssdl = -@" - - - - - - - -"; - - var exceptionMessage = Assert.Throws(() => new StoreItemCollection(new[] { XmlReader.Create(new StringReader(ssdl)) })).Message; - - Assert.True( - exceptionMessage.Contains(Strings.DuplicatedFunctionoverloads("Dbo.MyFunc", "(In Edm.String(Nullable=True,DefaultValue=,MaxLength=,Unicode=,FixedLength=))"))); - } - - [Fact] - public void Exception_thrown_when_loading_ssdl_with_out_of_range_facet_value() - { - var ssdl = -@" - - - - - - - - -"; - - var exceptionMessage = Assert.Throws(() => new StoreItemCollection(new[] { XmlReader.Create(new StringReader(ssdl)) })).Message; - - Assert.True(exceptionMessage.Contains("MaxLength")); - Assert.True(exceptionMessage.Contains("11111111111111111111111111111111111111111111111111111111111111111111111111111111")); - Assert.True(exceptionMessage.Contains("http://schemas.microsoft.com/ado/2006/04/edm/ssdl:TMaxLengthFacet")); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_having_the_same_name_as_type_in_the_model() - { - var functionDefinition = -@" - - esql expression - "; - - MetadataFunctionHelper( - functionDefinition, - e => Assert.True(e.Contains(Strings.AmbiguousFunctionAndType("Entities.Person", "Conceptual")))); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_facet_set_on_non_scalar_return_type() - { - var functionDefinition = -@" - - esql expression - "; - - MetadataFunctionHelper( - functionDefinition, - e => Assert.True(e.Contains(Strings.FacetsOnNonScalarType("Entities.Person")))); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_facet_set_on_non_scalar_type() - { - var functionDefinition = -@" - - esql expression - "; - - MetadataFunctionHelper( - functionDefinition, - e => Assert.True(e.Contains(Strings.FacetsOnNonScalarType("Entities.Person")))); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_without_return_type() - { - var functionDefinition = -@" - - esql expression - "; - - MetadataFunctionHelper( - functionDefinition, - e => - { - Assert.True(e.Contains(Strings.ComposableFunctionOrFunctionImportMustDeclareReturnType)); - Assert.True(e.Contains(Strings.FacetDeclarationRequiresTypeAttribute)); - }); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_parameter_without_a_return_type() - { - var functionDefinition = -@" - - esql expression - "; - - MetadataFunctionHelper( - functionDefinition, - e => - { - Assert.True(e.Contains(Strings.TypeMustBeDeclared)); - Assert.True(e.Contains(Strings.FacetDeclarationRequiresTypeAttribute)); - }); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_return_type_without_type_declaration() - { - var functionDefinition = -@" - - - ABC - "; - - MetadataFunctionHelper( - functionDefinition, - e => - { - Assert.True(e.Contains(Strings.TypeMustBeDeclared)); - Assert.True(e.Contains(Strings.FacetDeclarationRequiresTypeAttribute)); - }); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_facet_set_on_collection_of_entities_type() - { - var functionDefinition = -@" - - - - ABC - "; - - MetadataFunctionHelper( - functionDefinition, - e => Assert.True(e.Contains(Strings.FacetsOnNonScalarType("Entities.Person")))); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_return_type_being_a_collection_of_unspecified_type() - { - var functionDefinition = -@" - - - - ABC - "; - - MetadataFunctionHelper( - functionDefinition, - e => - { - Assert.True(e.Contains(Strings.TypeMustBeDeclared)); - Assert.True(e.Contains(Strings.FacetDeclarationRequiresTypeAttribute)); - }); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_return_type_being_a_collection_row_of_entity_with_facet_specified() - { - var functionDefinition = -@" - - - - - - - - ABC - "; - - MetadataFunctionHelper( - functionDefinition, - e => Assert.True(e.Contains(Strings.FacetsOnNonScalarType("Entities.Person")))); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_return_type_being_a_collection_row_of_unspecified_type() - { - var functionDefinition = -@" - - - - - - - - ABC - "; - - MetadataFunctionHelper( - functionDefinition, - e => - { - Assert.True(e.Contains(Strings.TypeMustBeDeclared)); - Assert.True(e.Contains(Strings.FacetDeclarationRequiresTypeAttribute)); - }); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_return_type_declared_boh_in_attribute_and_element() - { - var functionDefinition = -@" - - - - ABC - "; - - MetadataFunctionHelper( - functionDefinition, - e => Assert.True(e.Contains(Strings.TypeDeclaredAsAttributeAndElement))); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_return_type_being_row_without_properties() - { - var functionDefinition = -@" - - - - esql expression - "; - - MetadataFunctionHelper( - functionDefinition, - e => Assert.True(e.Contains(Strings.RowTypeWithoutProperty))); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_return_type_being_reference_to_non_entity_type() - { - var functionDefinition = -@" - - - - esql expression - "; - - MetadataFunctionHelper( - functionDefinition, - e => Assert.True(e.Contains(Strings.ReferenceToNonEntityType("Edm.Int32")))); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_parameter_being_type_being_reference_to_non_entity_type() - { - var functionDefinition = -@" - - - - - - esql expression - "; - - MetadataFunctionHelper( - functionDefinition, - e => Assert.True(e.Contains(Strings.ReferenceToNonEntityType("Edm.Int32")))); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_ambiguous_functions() - { - var functionDefinition = -@" - - - - - - - - 'abc' - - - - - - - - - - - 'abc' - - "; - - MetadataFunctionHelper( - functionDefinition, - e => Assert.True(e.Contains(Strings.AmbiguousFunctionOverload("Entities.MyFunction", "Conceptual")))); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_two_arguments_that_are_the_same() - { - var functionDefinition = -@" - - - esql expression - "; - - MetadataFunctionHelper( - functionDefinition, - e => Assert.True(e.Contains(Strings.ParameterNameAlreadyDefinedDuplicate("Param1")))); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_argument_being_a_row_with_two_properties_with_the_same_name() - { - var functionDefinition = -@" - - - - - - - esql expression - "; - - MetadataFunctionHelper( - functionDefinition, - e => Assert.True(e.Contains(Strings.EdmModel_Validator_Semantic_DuplicateEntityContainerMemberName("AProperty")))); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_undefined_return_type_and_parameter_type() - { - var functionDefinition = -@" - - esql expression - "; - - MetadataFunctionHelper( - functionDefinition, - e => - { - Assert.True(e.Contains(Strings.NotInNamespaceAlias("Undefined", "Entities", "Self"))); - Assert.True(e.Contains(Strings.NotInNamespaceNoAlias("Undefined", "Edm"))); - }); - } - - [Fact] - public void Exception_thrown_when_loading_csdl_with_function_with_reference_to_undefined_type_as_return_type_and_parameter_type() - { - var functionDefinition = -@" - - - - - - - - esql expression - "; - - MetadataFunctionHelper( - functionDefinition, - e => Assert.True(e.Contains(Strings.NotInNamespaceAlias("Undefined", "Entities", "Self")))); - } - - private void MetadataFunctionHelper(string functionDefinition, Action verificationAction) - { - var csdl = string.Format( - CultureInfo.InvariantCulture, -@" - - - - - - - - {0} -", functionDefinition); - - var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { XmlReader.Create(new StringReader(csdl)) })).Message; - verificationAction(exceptionMessage); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Metadata +{ + using System; + using System.Data.Entity.Core; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.Resources; + using System.Globalization; + using System.IO; + using System.Xml; + using Xunit; + + public class MetadataFunctionsTests : FunctionalTestBase + { + [Fact] + public void Exception_thrown_when_loading_ssdl_containing_functions_with_duplicate_overloads() + { + var ssdl = +@" + + + + + + + +"; + + var exceptionMessage = Assert.Throws(() => new StoreItemCollection(new[] { XmlReader.Create(new StringReader(ssdl)) })).Message; + + Assert.True( + exceptionMessage.Contains(Strings.DuplicatedFunctionoverloads("Dbo.MyFunc", "(In Edm.String(Nullable=True,DefaultValue=,MaxLength=,Unicode=,FixedLength=))"))); + } + + [Fact] + public void Exception_thrown_when_loading_ssdl_with_out_of_range_facet_value() + { + var ssdl = +@" + + + + + + + + +"; + + var exceptionMessage = Assert.Throws(() => new StoreItemCollection(new[] { XmlReader.Create(new StringReader(ssdl)) })).Message; + + Assert.True(exceptionMessage.Contains("MaxLength")); + Assert.True(exceptionMessage.Contains("11111111111111111111111111111111111111111111111111111111111111111111111111111111")); + Assert.True(exceptionMessage.Contains("http://schemas.microsoft.com/ado/2006/04/edm/ssdl:TMaxLengthFacet")); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_having_the_same_name_as_type_in_the_model() + { + var functionDefinition = +@" + + esql expression + "; + + MetadataFunctionHelper( + functionDefinition, + e => Assert.True(e.Contains(Strings.AmbiguousFunctionAndType("Entities.Person", "Conceptual")))); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_facet_set_on_non_scalar_return_type() + { + var functionDefinition = +@" + + esql expression + "; + + MetadataFunctionHelper( + functionDefinition, + e => Assert.True(e.Contains(Strings.FacetsOnNonScalarType("Entities.Person")))); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_facet_set_on_non_scalar_type() + { + var functionDefinition = +@" + + esql expression + "; + + MetadataFunctionHelper( + functionDefinition, + e => Assert.True(e.Contains(Strings.FacetsOnNonScalarType("Entities.Person")))); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_without_return_type() + { + var functionDefinition = +@" + + esql expression + "; + + MetadataFunctionHelper( + functionDefinition, + e => + { + Assert.True(e.Contains(Strings.ComposableFunctionOrFunctionImportMustDeclareReturnType)); + Assert.True(e.Contains(Strings.FacetDeclarationRequiresTypeAttribute)); + }); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_parameter_without_a_return_type() + { + var functionDefinition = +@" + + esql expression + "; + + MetadataFunctionHelper( + functionDefinition, + e => + { + Assert.True(e.Contains(Strings.TypeMustBeDeclared)); + Assert.True(e.Contains(Strings.FacetDeclarationRequiresTypeAttribute)); + }); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_return_type_without_type_declaration() + { + var functionDefinition = +@" + + + ABC + "; + + MetadataFunctionHelper( + functionDefinition, + e => + { + Assert.True(e.Contains(Strings.TypeMustBeDeclared)); + Assert.True(e.Contains(Strings.FacetDeclarationRequiresTypeAttribute)); + }); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_facet_set_on_collection_of_entities_type() + { + var functionDefinition = +@" + + + + ABC + "; + + MetadataFunctionHelper( + functionDefinition, + e => Assert.True(e.Contains(Strings.FacetsOnNonScalarType("Entities.Person")))); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_return_type_being_a_collection_of_unspecified_type() + { + var functionDefinition = +@" + + + + ABC + "; + + MetadataFunctionHelper( + functionDefinition, + e => + { + Assert.True(e.Contains(Strings.TypeMustBeDeclared)); + Assert.True(e.Contains(Strings.FacetDeclarationRequiresTypeAttribute)); + }); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_return_type_being_a_collection_row_of_entity_with_facet_specified() + { + var functionDefinition = +@" + + + + + + + + ABC + "; + + MetadataFunctionHelper( + functionDefinition, + e => Assert.True(e.Contains(Strings.FacetsOnNonScalarType("Entities.Person")))); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_return_type_being_a_collection_row_of_unspecified_type() + { + var functionDefinition = +@" + + + + + + + + ABC + "; + + MetadataFunctionHelper( + functionDefinition, + e => + { + Assert.True(e.Contains(Strings.TypeMustBeDeclared)); + Assert.True(e.Contains(Strings.FacetDeclarationRequiresTypeAttribute)); + }); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_return_type_declared_boh_in_attribute_and_element() + { + var functionDefinition = +@" + + + + ABC + "; + + MetadataFunctionHelper( + functionDefinition, + e => Assert.True(e.Contains(Strings.TypeDeclaredAsAttributeAndElement))); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_return_type_being_row_without_properties() + { + var functionDefinition = +@" + + + + esql expression + "; + + MetadataFunctionHelper( + functionDefinition, + e => Assert.True(e.Contains(Strings.RowTypeWithoutProperty))); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_return_type_being_reference_to_non_entity_type() + { + var functionDefinition = +@" + + + + esql expression + "; + + MetadataFunctionHelper( + functionDefinition, + e => Assert.True(e.Contains(Strings.ReferenceToNonEntityType("Edm.Int32")))); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_parameter_being_type_being_reference_to_non_entity_type() + { + var functionDefinition = +@" + + + + + + esql expression + "; + + MetadataFunctionHelper( + functionDefinition, + e => Assert.True(e.Contains(Strings.ReferenceToNonEntityType("Edm.Int32")))); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_ambiguous_functions() + { + var functionDefinition = +@" + + + + + + + + 'abc' + + + + + + + + + + + 'abc' + + "; + + MetadataFunctionHelper( + functionDefinition, + e => Assert.True(e.Contains(Strings.AmbiguousFunctionOverload("Entities.MyFunction", "Conceptual")))); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_two_arguments_that_are_the_same() + { + var functionDefinition = +@" + + + esql expression + "; + + MetadataFunctionHelper( + functionDefinition, + e => Assert.True(e.Contains(Strings.ParameterNameAlreadyDefinedDuplicate("Param1")))); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_argument_being_a_row_with_two_properties_with_the_same_name() + { + var functionDefinition = +@" + + + + + + + esql expression + "; + + MetadataFunctionHelper( + functionDefinition, + e => Assert.True(e.Contains(Strings.EdmModel_Validator_Semantic_DuplicateEntityContainerMemberName("AProperty")))); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_undefined_return_type_and_parameter_type() + { + var functionDefinition = +@" + + esql expression + "; + + MetadataFunctionHelper( + functionDefinition, + e => + { + Assert.True(e.Contains(Strings.NotInNamespaceAlias("Undefined", "Entities", "Self"))); + Assert.True(e.Contains(Strings.NotInNamespaceNoAlias("Undefined", "Edm"))); + }); + } + + [Fact] + public void Exception_thrown_when_loading_csdl_with_function_with_reference_to_undefined_type_as_return_type_and_parameter_type() + { + var functionDefinition = +@" + + + + + + + + esql expression + "; + + MetadataFunctionHelper( + functionDefinition, + e => Assert.True(e.Contains(Strings.NotInNamespaceAlias("Undefined", "Entities", "Self")))); + } + + private void MetadataFunctionHelper(string functionDefinition, Action verificationAction) + { + var csdl = string.Format( + CultureInfo.InvariantCulture, +@" + + + + + + + + {0} +", functionDefinition); + + var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { XmlReader.Create(new StringReader(csdl)) })).Message; + verificationAction(exceptionMessage); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/Metadata/MetadataSpatialTests.cs b/test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataSpatialTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/Metadata/MetadataSpatialTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataSpatialTests.cs index 3cfc57cf..ec9c2ab3 100644 --- a/test/EntityFramework/FunctionalTests/Metadata/MetadataSpatialTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Metadata/MetadataSpatialTests.cs @@ -1,205 +1,205 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Metadata -{ - using System.Data.Entity.Core; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.Resources; - using System.Globalization; - using System.IO; - using System.Xml; - using Xunit; - - public class MetadataSpatialTests : FunctionalTestBase - { - private static readonly string SpatialEntityPropertyCSDLTemplate = @" - - - - - - - - -"; - - private const string EdmNamespaceV1 = "http://schemas.microsoft.com/ado/2007/05/edm"; - private const string EdmNamespaceV2 = "http://schemas.microsoft.com/ado/2008/09/edm"; - private const string EdmNamespaceV3 = "http://schemas.microsoft.com/ado/2009/11/edm"; - private const string UseStrongSpatialAnnotation = @"annotation:UseStrongSpatialTypes=""false"" "; - - [Fact] - public void Error_on_Geography_entity_property_in_csdl_version1() - { - Assert.True( - Assert.Throws( - () => SpatialEntityPropertyTest(EdmNamespaceV1, PrimitiveTypeKind.Geography)).Message.Contains(Strings.NotNamespaceQualified("Geography"))); - } - - [Fact] - public void Error_on_Geography_entity_property_in_csdl_version2() - { - Assert.True( - Assert.Throws( - () => SpatialEntityPropertyTest(EdmNamespaceV2, PrimitiveTypeKind.Geography)).Message.Contains(Strings.NotNamespaceQualified("Geography"))); - } - - - [Fact] - public void Geography_entity_property_in_csdl_versio3n_works() - { - VerifySpatialEntityProperty(PrimitiveTypeKind.Geography); - } - - [Fact] - public void Error_on_Geography_EntityKey_property_in_csdl_version3() - { - Assert.True( - Assert.Throws( - () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geography, "Location", UseStrongSpatialAnnotation)).Message. - Contains(Strings.EntityKeyTypeCurrentlyNotSupported("Location", "SpatialEntityPropertyTest.EntityWithSpatialProperty", "Geography"))); - } - - [Fact] - public void Error_on_Geography_without_StrongTypes_in_csdl_version3() - { - Assert.True( - Assert.Throws( - () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geography, "ID", "")).Message.Contains(Strings.SpatialWithUseStrongSpatialTypesFalse)); - } - - [Fact] - public void Error_on_Geography_with_TrueStrongTypes_in_csdl_version3() - { - Assert.True( - Assert.Throws( - () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geography, "ID", @"annotation:UseStrongSpatialTypes=""true""")).Message. - Contains(Strings.SpatialWithUseStrongSpatialTypesFalse)); - } - - [Fact] - public void Error_on_Geography_with_invalid_StrongTypes_in_csdl_version3() - { - var exceptionMessage = Assert.Throws( - () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geography, "ID", @"annotation:UseStrongSpatialTypes=""Invalid""")).Message; - - Assert.True(exceptionMessage.Contains("http://schemas.microsoft.com/ado/2009/02/edm/annotation:UseStrongSpatialTypes")); - Assert.True(exceptionMessage.Contains("Invalid")); - Assert.True(exceptionMessage.Contains("http://www.w3.org/2001/XMLSchema:boolean")); - } - - [Fact] - public void Error_on_Geometry_entity_property_in_csdl_version1() - { - Assert.True( - Assert.Throws( - () => SpatialEntityPropertyTest(EdmNamespaceV1, PrimitiveTypeKind.Geometry)).Message.Contains(Strings.NotNamespaceQualified("Geometry"))); - } - - [Fact] - public void Error_on_Geometry_entity_property_in_csdl_version2() - { - Assert.True( - Assert.Throws( - () => SpatialEntityPropertyTest(EdmNamespaceV2, PrimitiveTypeKind.Geometry)).Message.Contains(Strings.NotNamespaceQualified("Geometry"))); - } - - [Fact] - public void Verify_Geometry_entity_property_in_csdl_version3_works() - { - VerifySpatialEntityProperty(PrimitiveTypeKind.Geometry); - } - - [Fact] - public void Error_on_Geometry_without_StrongTypes_in_csdl_version3() - { - Assert.True( - Assert.Throws( - () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geometry, "ID", "")).Message.Contains(Strings.SpatialWithUseStrongSpatialTypesFalse)); - } - - [Fact] - public void Error_on_Geometry_with_TrueStrongTypes_in_csdl_version3() - { - Assert.True( - Assert.Throws( - () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geometry, "ID", @"annotation:UseStrongSpatialTypes=""true""")).Message. - Contains(Strings.SpatialWithUseStrongSpatialTypesFalse)); - } - - [Fact] - public void Error_on_Geometry_with_invalid_StrongTypes_in_csdl_version3() - { - Assert.True( - Assert.Throws( - () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geometry, "ID", @"annotation:UseStrongSpatialTypes=""Invalid""")).Message. - Contains("http://www.w3.org/2001/XMLSchema:boolean")); - } - - [Fact] - public void Error_on_Geometry_EntityKey_property_in_csdl__version3() - { - Assert.True( - Assert.Throws( - () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geometry, "Location", UseStrongSpatialAnnotation)).Message. - Contains(Strings.EntityKeyTypeCurrentlyNotSupported("Location","SpatialEntityPropertyTest.EntityWithSpatialProperty","Geometry"))); - } - - [Fact] - public void Error_on_invalid_facet_for_Spatial() - { - var invalidCsdl = -@" - - - - - - - - - - "; - - string csdlContent = string.Format(CultureInfo.InvariantCulture, invalidCsdl, EdmNamespaceV3, UseStrongSpatialAnnotation); - XmlReader csdlReader = XmlReader.Create(new StringReader(csdlContent)); - - var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { csdlReader })).Message; - - Assert.True(exceptionMessage.Contains(Strings.FacetNotAllowed("ConcurrencyMode", "Edm.Geography"))); - Assert.True(exceptionMessage.Contains(Strings.FacetNotAllowed("ConcurrencyMode", "Edm.Geometry"))); - } - - private EdmItemCollection SpatialEntityPropertyTest(string namespaceVersion, PrimitiveTypeKind spatialType) - { - return SpatialEntityPropertyTest(namespaceVersion, spatialType, keyPropertyName: "ID", strongSpatialAnnotation: ""); - } - - private EdmItemCollection SpatialEntityPropertyTest(string namespaceVersion, PrimitiveTypeKind spatialType, string keyPropertyName, string strongSpatialAnnotation) - { - string typeName = (spatialType == PrimitiveTypeKind.Geography ? "Geography" : "Geometry"); - string csdlContent = string.Format( - CultureInfo.InvariantCulture, - SpatialEntityPropertyCSDLTemplate, - namespaceVersion, - keyPropertyName, - typeName, - strongSpatialAnnotation); - - var csdlReader = XmlReader.Create(new StringReader(csdlContent)); - var testCollection = new EdmItemCollection(new[] { csdlReader }); - - return testCollection; - } - - private void VerifySpatialEntityProperty(PrimitiveTypeKind spatialType) - { - EdmItemCollection items = SpatialEntityPropertyTest(EdmNamespaceV3, spatialType, "ID", UseStrongSpatialAnnotation); - EntityType spatialEntityType = items.GetItem("SpatialEntityPropertyTest.EntityWithSpatialProperty", ignoreCase: false); - EdmProperty spatialProperty = spatialEntityType.Properties["Location"]; - PrimitiveType primitivePropertyType = (PrimitiveType)spatialProperty.TypeUsage.EdmType; - - Assert.True(primitivePropertyType.PrimitiveTypeKind == spatialType, "Spatial Entity property was not correctly loaded for " + spatialType.ToString()); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Metadata +{ + using System.Data.Entity.Core; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.Resources; + using System.Globalization; + using System.IO; + using System.Xml; + using Xunit; + + public class MetadataSpatialTests : FunctionalTestBase + { + private static readonly string SpatialEntityPropertyCSDLTemplate = @" + + + + + + + + +"; + + private const string EdmNamespaceV1 = "http://schemas.microsoft.com/ado/2007/05/edm"; + private const string EdmNamespaceV2 = "http://schemas.microsoft.com/ado/2008/09/edm"; + private const string EdmNamespaceV3 = "http://schemas.microsoft.com/ado/2009/11/edm"; + private const string UseStrongSpatialAnnotation = @"annotation:UseStrongSpatialTypes=""false"" "; + + [Fact] + public void Error_on_Geography_entity_property_in_csdl_version1() + { + Assert.True( + Assert.Throws( + () => SpatialEntityPropertyTest(EdmNamespaceV1, PrimitiveTypeKind.Geography)).Message.Contains(Strings.NotNamespaceQualified("Geography"))); + } + + [Fact] + public void Error_on_Geography_entity_property_in_csdl_version2() + { + Assert.True( + Assert.Throws( + () => SpatialEntityPropertyTest(EdmNamespaceV2, PrimitiveTypeKind.Geography)).Message.Contains(Strings.NotNamespaceQualified("Geography"))); + } + + + [Fact] + public void Geography_entity_property_in_csdl_versio3n_works() + { + VerifySpatialEntityProperty(PrimitiveTypeKind.Geography); + } + + [Fact] + public void Error_on_Geography_EntityKey_property_in_csdl_version3() + { + Assert.True( + Assert.Throws( + () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geography, "Location", UseStrongSpatialAnnotation)).Message. + Contains(Strings.EntityKeyTypeCurrentlyNotSupported("Location", "SpatialEntityPropertyTest.EntityWithSpatialProperty", "Geography"))); + } + + [Fact] + public void Error_on_Geography_without_StrongTypes_in_csdl_version3() + { + Assert.True( + Assert.Throws( + () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geography, "ID", "")).Message.Contains(Strings.SpatialWithUseStrongSpatialTypesFalse)); + } + + [Fact] + public void Error_on_Geography_with_TrueStrongTypes_in_csdl_version3() + { + Assert.True( + Assert.Throws( + () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geography, "ID", @"annotation:UseStrongSpatialTypes=""true""")).Message. + Contains(Strings.SpatialWithUseStrongSpatialTypesFalse)); + } + + [Fact] + public void Error_on_Geography_with_invalid_StrongTypes_in_csdl_version3() + { + var exceptionMessage = Assert.Throws( + () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geography, "ID", @"annotation:UseStrongSpatialTypes=""Invalid""")).Message; + + Assert.True(exceptionMessage.Contains("http://schemas.microsoft.com/ado/2009/02/edm/annotation:UseStrongSpatialTypes")); + Assert.True(exceptionMessage.Contains("Invalid")); + Assert.True(exceptionMessage.Contains("http://www.w3.org/2001/XMLSchema:boolean")); + } + + [Fact] + public void Error_on_Geometry_entity_property_in_csdl_version1() + { + Assert.True( + Assert.Throws( + () => SpatialEntityPropertyTest(EdmNamespaceV1, PrimitiveTypeKind.Geometry)).Message.Contains(Strings.NotNamespaceQualified("Geometry"))); + } + + [Fact] + public void Error_on_Geometry_entity_property_in_csdl_version2() + { + Assert.True( + Assert.Throws( + () => SpatialEntityPropertyTest(EdmNamespaceV2, PrimitiveTypeKind.Geometry)).Message.Contains(Strings.NotNamespaceQualified("Geometry"))); + } + + [Fact] + public void Verify_Geometry_entity_property_in_csdl_version3_works() + { + VerifySpatialEntityProperty(PrimitiveTypeKind.Geometry); + } + + [Fact] + public void Error_on_Geometry_without_StrongTypes_in_csdl_version3() + { + Assert.True( + Assert.Throws( + () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geometry, "ID", "")).Message.Contains(Strings.SpatialWithUseStrongSpatialTypesFalse)); + } + + [Fact] + public void Error_on_Geometry_with_TrueStrongTypes_in_csdl_version3() + { + Assert.True( + Assert.Throws( + () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geometry, "ID", @"annotation:UseStrongSpatialTypes=""true""")).Message. + Contains(Strings.SpatialWithUseStrongSpatialTypesFalse)); + } + + [Fact] + public void Error_on_Geometry_with_invalid_StrongTypes_in_csdl_version3() + { + Assert.True( + Assert.Throws( + () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geometry, "ID", @"annotation:UseStrongSpatialTypes=""Invalid""")).Message. + Contains("http://www.w3.org/2001/XMLSchema:boolean")); + } + + [Fact] + public void Error_on_Geometry_EntityKey_property_in_csdl__version3() + { + Assert.True( + Assert.Throws( + () => SpatialEntityPropertyTest(EdmNamespaceV3, PrimitiveTypeKind.Geometry, "Location", UseStrongSpatialAnnotation)).Message. + Contains(Strings.EntityKeyTypeCurrentlyNotSupported("Location","SpatialEntityPropertyTest.EntityWithSpatialProperty","Geometry"))); + } + + [Fact] + public void Error_on_invalid_facet_for_Spatial() + { + var invalidCsdl = +@" + + + + + + + + + + "; + + string csdlContent = string.Format(CultureInfo.InvariantCulture, invalidCsdl, EdmNamespaceV3, UseStrongSpatialAnnotation); + XmlReader csdlReader = XmlReader.Create(new StringReader(csdlContent)); + + var exceptionMessage = Assert.Throws(() => new EdmItemCollection(new[] { csdlReader })).Message; + + Assert.True(exceptionMessage.Contains(Strings.FacetNotAllowed("ConcurrencyMode", "Edm.Geography"))); + Assert.True(exceptionMessage.Contains(Strings.FacetNotAllowed("ConcurrencyMode", "Edm.Geometry"))); + } + + private EdmItemCollection SpatialEntityPropertyTest(string namespaceVersion, PrimitiveTypeKind spatialType) + { + return SpatialEntityPropertyTest(namespaceVersion, spatialType, keyPropertyName: "ID", strongSpatialAnnotation: ""); + } + + private EdmItemCollection SpatialEntityPropertyTest(string namespaceVersion, PrimitiveTypeKind spatialType, string keyPropertyName, string strongSpatialAnnotation) + { + string typeName = (spatialType == PrimitiveTypeKind.Geography ? "Geography" : "Geometry"); + string csdlContent = string.Format( + CultureInfo.InvariantCulture, + SpatialEntityPropertyCSDLTemplate, + namespaceVersion, + keyPropertyName, + typeName, + strongSpatialAnnotation); + + var csdlReader = XmlReader.Create(new StringReader(csdlContent)); + var testCollection = new EdmItemCollection(new[] { csdlReader }); + + return testCollection; + } + + private void VerifySpatialEntityProperty(PrimitiveTypeKind spatialType) + { + EdmItemCollection items = SpatialEntityPropertyTest(EdmNamespaceV3, spatialType, "ID", UseStrongSpatialAnnotation); + EntityType spatialEntityType = items.GetItem("SpatialEntityPropertyTest.EntityWithSpatialProperty", ignoreCase: false); + EdmProperty spatialProperty = spatialEntityType.Properties["Location"]; + PrimitiveType primitivePropertyType = (PrimitiveType)spatialProperty.TypeUsage.EdmType; + + Assert.True(primitivePropertyType.PrimitiveTypeKind == spatialType, "Spatial Entity property was not correctly loaded for " + spatialType.ToString()); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/MetadataMapping/Enum.csdl b/test/EntityFramework/FunctionalTests.Transitional/MetadataMapping/Enum.csdl similarity index 97% rename from test/EntityFramework/FunctionalTests/MetadataMapping/Enum.csdl rename to test/EntityFramework/FunctionalTests.Transitional/MetadataMapping/Enum.csdl index b5de6da5..dea7e964 100644 --- a/test/EntityFramework/FunctionalTests/MetadataMapping/Enum.csdl +++ b/test/EntityFramework/FunctionalTests.Transitional/MetadataMapping/Enum.csdl @@ -1,58 +1,58 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/MetadataMapping/Enum.msl b/test/EntityFramework/FunctionalTests.Transitional/MetadataMapping/Enum.msl similarity index 97% rename from test/EntityFramework/FunctionalTests/MetadataMapping/Enum.msl rename to test/EntityFramework/FunctionalTests.Transitional/MetadataMapping/Enum.msl index a05d90a0..20b63ec0 100644 --- a/test/EntityFramework/FunctionalTests/MetadataMapping/Enum.msl +++ b/test/EntityFramework/FunctionalTests.Transitional/MetadataMapping/Enum.msl @@ -1,23 +1,23 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/MetadataMapping/Enum.ssdl b/test/EntityFramework/FunctionalTests.Transitional/MetadataMapping/Enum.ssdl similarity index 97% rename from test/EntityFramework/FunctionalTests/MetadataMapping/Enum.ssdl rename to test/EntityFramework/FunctionalTests.Transitional/MetadataMapping/Enum.ssdl index a7b6be23..ba83c73e 100644 --- a/test/EntityFramework/FunctionalTests/MetadataMapping/Enum.ssdl +++ b/test/EntityFramework/FunctionalTests.Transitional/MetadataMapping/Enum.ssdl @@ -1,40 +1,40 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/MetadataMapping/EnumOCMappingTests.cs b/test/EntityFramework/FunctionalTests.Transitional/MetadataMapping/EnumOCMappingTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/MetadataMapping/EnumOCMappingTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/MetadataMapping/EnumOCMappingTests.cs index 9856ca2a..ce2b3a55 100644 --- a/test/EntityFramework/FunctionalTests/MetadataMapping/EnumOCMappingTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/MetadataMapping/EnumOCMappingTests.cs @@ -1,905 +1,905 @@ - -namespace System.Data.Entity.MetadataMapping -{ - using System.Data.Entity.Core; - using System.Data.Entity.Core.Mapping; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.Resources; - using System.Data.Entity.TestHelpers; - using System.IO; - using System.Linq; - using System.Reflection; - using System.Xml; - using System.Xml.Linq; - using Xunit; - - public class EnumOCMappingTests : FunctionalTestBase - { - private static XDocument EnumCsdl() - { - return XDocument.Load( - Assembly - .GetExecutingAssembly() - .GetManifestResourceStream("System.Data.Entity.MetadataMapping.Enum.csdl")); - } - #region convention loader (POCO) - - [Fact] - public void Verify_simple_enum_mapping_POCO() - { - Verify_simple_enum_mapping(true); - } - - [Fact] - public void Complex_type_with_eumm_property_is_mapped_correctly_POCO() - { - Complex_type_with_enum_property_is_mapped_correctly(true); - } - - [Fact] - public void Enums_with_members_with_same_values_are_mapped_even_if_order_is_different_POCO() - { - Enums_with_members_with_same_values_are_mapped_even_if_order_is_different(true); - } - - [Fact] - public void Nullability_of_enum_properties_ignored_for_mapping_POCO() - { - Nullability_of_enum_properties_ignored_for_mapping(true); - } - - [Fact] - public void Can_map_enum_type_with_no_members_POCO() - { - Can_map_enum_type_with_no_members(true); - } - - [Fact] - public void Cannot_map_OSpace_enum_type_with_unsupported_underlying_type_POCO() - { - var exception = - Assert.Throws( - () => Cannot_map_OSpace_enum_type_with_unsupported_underlying_type(true)); - - Assert.Contains( - Strings.Validator_OSpace_Convention_MissingOSpaceType("MessageModel.MessageType"), - exception.Message); - - Assert.Contains( - Strings.Validator_UnsupportedEnumUnderlyingType("System.UInt32"), - exception.Message); - - } - - [Fact] - public void Cannot_map_enum_types_if_names_are_different_POCO() - { - Assert.Contains( - Strings.Validator_OSpace_Convention_MissingOSpaceType("MessageModel.PaymentMethod"), - Assert.Throws( - () => Cannot_map_enum_types_if_names_are_different(true)).Message); - } - - [Fact] - public void Cannot_map_enum_types_if_underlying_types_dont_match_POCO() - { - var exception = Assert.Throws( - () => Cannot_map_enum_types_if_underlying_types_dont_match(true)); - - Assert.Contains( - Strings.Validator_OSpace_Convention_MissingOSpaceType("MessageModel.MessageType"), - exception.Message); - - Assert.Contains( - Strings.Validator_OSpace_Convention_NonMatchingUnderlyingTypes, - exception.Message); - } - - [Fact] - public void Cannot_map_OSpace_enum_type_with_fewer_members_than_CSpace_enum_type_POCO() - { - var exception = Assert.Throws( - () => Cannot_map_OSpace_enum_type_with_fewer_members_than_CSpace_enum_type(true)); - - Assert.Contains( - Strings.Validator_OSpace_Convention_MissingOSpaceType("MessageModel.MessageType"), - exception.Message); - - Assert.Contains( - Strings.Mapping_Enum_OCMapping_MemberMismatch("MessageModel.MessageType", "Ground", 2, "MessageModel.MessageType"), - exception.Message); - } - - [Fact] - public void Cannot_map_OSpace_enum_type_whose_member_name_does_not_match_CSpace_enum_type_member_name_POCO() - { - var exception = Assert.Throws( - () => - Cannot_map_OSpace_enum_type_whose_member_name_does_not_match_CSpace_enum_type_member_name(true)); - - Assert.Contains( - Strings.Validator_OSpace_Convention_MissingOSpaceType("MessageModel.MessageType"), - exception.Message); - - Assert.Contains( - Strings.Mapping_Enum_OCMapping_MemberMismatch("MessageModel.MessageType", "Ground", 2, "MessageModel.MessageType"), - exception.Message); - } - - [Fact] - public void Can_map_OSpace_enum_type_that_has_more_members_than_CSPace_enum_type_if_members_match_POCO() - { - Can_map_OSpace_enum_type_that_has_more_members_than_CSPace_enum_type_if_members_match(true); - } - - [Fact] - public void Can_map_CSpace_enum_type_with_no_enum_members_POCO() - { - Can_map_CSpace_enum_type_with_no_enum_members(true); - } - - [Fact] - public void Cannot_map_if_OSpace_enum_type_member_value_does_not_match_CSpace_enum_type_member_value_POCO() - { - var exception = Assert.Throws( - () => - Cannot_map_if_OSpace_enum_type_member_value_does_not_match_CSpace_enum_type_member_value(true)); - - Assert.Contains( - Strings.Validator_OSpace_Convention_MissingOSpaceType("MessageModel.MessageType"), - exception.Message); - - Assert.Contains( - Strings.Mapping_Enum_OCMapping_MemberMismatch("MessageModel.MessageType", "Ground", 2, "MessageModel.MessageType"), - exception.Message); - } - - [Fact] - public void Verify_OSpace_enum_type_is_not_mapped_to_CSpace_entity_type_with_same_name_POCO() - { - Assert.Equal( - Strings.Mapping_Object_InvalidType("Model.MessageType"), - Assert.Throws( - () => OSpace_enum_type_and_CSpace_entity_type_have_the_same_name(true)).Message); - } - - [Fact] - public void Verify_OSpace_entity_type_is_not_mapped_to_CSpace_enum_type_with_same_name_POCO() - { - Assert.Equal( - Strings.Mapping_Object_InvalidType("Model.MessageType"), - Assert.Throws( - () => OSpace_entity_type_and_CSpace_enum_type_have_the_same_name(true)).Message); - } - - // POCO specific cases - - [Fact] - public void Correct_CSpace_enum_type_is_mapped_if_multiple_OSpace_enum_types_exist_but_only_one_matches() - { - var additionalEnumType = XDocument.Parse( -@" - -"); - - var workspace = - CreateMetadataWorkspace( - EnumCsdl(), - BuildAssembly(true, EnumCsdl(), additionalEnumType), - true); - - Assert.Equal( - "MessageModel.MessageType:MessageModel.MessageType", - workspace.GetMap("MessageModel.MessageType", DataSpace.OSpace, DataSpace.OCSpace).Identity); - - Assert.Equal( - "MessageModel.Message:MessageModel.Message", - workspace.GetMap("MessageModel.Message", DataSpace.OSpace, DataSpace.OCSpace).Identity); - } - - [Fact] - public void Mapping_fails_for_multiple_OSpace_enum_types_matching_the_same_CSpace_enum_type_POCO() - { - var additionalMatchingEnumType = XDocument.Parse( -@" - - - - - - -"); - - var assembly = BuildAssembly(true, EnumCsdl(), additionalMatchingEnumType); - Assert.Contains( - Strings.Validator_OSpace_Convention_AmbiguousClrType( - "MessageType", - "MessageModel.MessageType", - "MessageModel1.MessageType"), - Assert.Throws( - () => CreateMetadataWorkspace(EnumCsdl(), assembly, true)).Message); - } - - [Fact] - public void Cannot_create_workspace_if_OSpace_enum_property_does_not_have_getter() - { - var oSpaceCsdl = EnumCsdl(); - oSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") - .Single(p => (string)p.Attribute("Name") == "MessageType") - .SetAttributeValue("{MappingTestExtension}SuppressGetter", true); - - var assembly = BuildAssembly(true, oSpaceCsdl); - - Assert.Contains( - Strings.Validator_OSpace_Convention_ScalarPropertyMissginGetterOrSetter( - "MessageType", - "MessageModel.Message", - assembly.FullName), - Assert.Throws( - () => CreateMetadataWorkspace(EnumCsdl(), assembly, true)).Message); - } - - [Fact] - public void Cannot_create_workspace_if_OSpace_enum_property_does_not_have_setter() - { - var oSpaceCsdl = EnumCsdl(); - oSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") - .Single(p => (string)p.Attribute("Name") == "MessageType") - .SetAttributeValue("{MappingTestExtension}SuppressSetter", true); - - var assembly = BuildAssembly(true, oSpaceCsdl); - - Assert.Contains( - Strings.Validator_OSpace_Convention_ScalarPropertyMissginGetterOrSetter( - "MessageType", - "MessageModel.Message", - assembly.FullName), - Assert.Throws( - () => CreateMetadataWorkspace(EnumCsdl(), assembly, true)).Message); - } - - [Fact] - public void Can_load_entity_with_property_of_enum_type_from_different_assembly() - { - const bool isPOCO = true; - - var enumTypeCsdl = XDocument.Parse( -@" - -"); - - var entityTypeCsdl = XDocument.Parse( -@" - - - - - - - - - - -"); - - var assemblyWithEnumType = BuildAssembly(isPOCO, enumTypeCsdl); - var assemblyWithEntityType = BuildAssembly(isPOCO, entityTypeCsdl); - - EdmItemCollection edmItemCollection; - - var workspace = new MetadataWorkspace(); - using (var enumTypeReader = enumTypeCsdl.CreateReader()) - using (var entityTypeReader = entityTypeCsdl.CreateReader()) - { - edmItemCollection = - new EdmItemCollection( - new XmlReader[] { enumTypeReader, entityTypeReader }); - } - workspace.RegisterItemCollection(edmItemCollection); - - var objectItemCollection = new ObjectItemCollection(); - - objectItemCollection.LoadFromAssembly(assemblyWithEnumType, edmItemCollection); - objectItemCollection.LoadFromAssembly(assemblyWithEntityType, edmItemCollection); - workspace.RegisterItemCollection(objectItemCollection); - - Assert.Equal( - "EnumModel.Entity:EnumModel.Entity", - workspace.GetMap("EnumModel.Entity", DataSpace.OSpace, DataSpace.OCSpace).Identity); - } - - - #endregion - - #region attribute loader (non-POCO) - - [Fact] - public void Verify_simple_enum_mapping_non_POCO() - { - Verify_simple_enum_mapping(false); - } - - [Fact] - public void Complex_type_with_enum_property_is_mapped_correctly_NonPOCO() - { - Complex_type_with_enum_property_is_mapped_correctly(false); - } - - [Fact] - public void Enums_with_members_with_same_values_are_mapped_even_if_order_is_different_NonPOCO() - { - Enums_with_members_with_same_values_are_mapped_even_if_order_is_different(false); - } - - [Fact] - public void Nullability_of_enum_properties_ignored_for_mapping_NonPOCO() - { - Nullability_of_enum_properties_ignored_for_mapping(false); - } - - [Fact] - public void Can_map_enum_type_with_no_members_NonPOCO() - { - Can_map_enum_type_with_no_members(false); - } - - [Fact] - public void Cannot_map_OSpace_enum_type_with_unsupported_underlying_NonPOCO() - { - var exception = - Assert.Throws( - () => Cannot_map_OSpace_enum_type_with_unsupported_underlying_type(false)); - - Assert.Contains( - Strings.Validator_OSpace_ScalarPropertyNotPrimitive( - "TypeOfMessage", - "MessageModel.MessageTypeLookUp", - "MessageModel.MessageType"), - exception.Message); - - Assert.Contains( - Strings.Validator_UnsupportedEnumUnderlyingType("System.UInt32"), - exception.Message); - - } - - [Fact] - public void Cannot_map_enum_types_if_names_are_different_NonPOCO() - { - Assert.Equal( - Strings.Mapping_Object_InvalidType("MessageModel.ShippingType"), - Assert.Throws( - () => Cannot_map_enum_types_if_names_are_different(false)).Message); - - } - - [Fact] - public void OSpaceEnumUnderlyingTypeDoesNotMatchCSpaceEnumUnderlyingTypeName_NonPOCO() - { - Assert.Contains( - Strings.Mapping_Enum_OCMapping_UnderlyingTypesMismatch("Int32", "MessageModel.MessageType", "Int64", "MessageModel.MessageType"), - Assert.Throws( - () => Cannot_map_enum_types_if_underlying_types_dont_match(false)).Message); - } - - [Fact] - public void Cannot_map_OSpace_enum_type_with_fewer_members_than_CSpace_enum_type_NonPOCO() - { - Assert.Equal( - Strings.Mapping_Enum_OCMapping_MemberMismatch("MessageModel.MessageType", "Ground", 2, "MessageModel.MessageType"), - Assert.Throws( - () => Cannot_map_OSpace_enum_type_with_fewer_members_than_CSpace_enum_type(false)).Message); - } - - [Fact] - public void OSpaceEnumTypeMemberNameDoesNotMatchCSpaceEnumTypeMemberName_NonPOCO() - { - Assert.Equal( - Strings.Mapping_Enum_OCMapping_MemberMismatch("MessageModel.MessageType", "Ground", 2, "MessageModel.MessageType"), - Assert.Throws( - () => - Cannot_map_OSpace_enum_type_whose_member_name_does_not_match_CSpace_enum_type_member_name(false)) - .Message); - } - - [Fact] - public void Can_map_OSpace_enum_type_that_has_more_members_than_CSPace_enum_type_if_members_match_NonPOCO() - { - Can_map_OSpace_enum_type_that_has_more_members_than_CSPace_enum_type_if_members_match(false); - } - - [Fact] - public void Can_map_CSpace_enum_type_with_no_enum_members_NonPOCO() - { - Can_map_CSpace_enum_type_with_no_enum_members(false); - } - - [Fact] - public void Cannot_map_if_OSpace_enum_type_member_value_does_not_match_CSpace_enum_type_member_value_NonPOCO() - { - Assert.Equal( - Strings.Mapping_Enum_OCMapping_MemberMismatch("MessageModel.MessageType", "Ground", 2, "MessageModel.MessageType"), - Assert.Throws( - () => - Cannot_map_if_OSpace_enum_type_member_value_does_not_match_CSpace_enum_type_member_value(false)).Message); - } - - [Fact] - public void Cannot_map_OSpace_enum_type_to_CSpace_entity_type_with_the_same_name_NonPOCO() - { - Assert.Equal( - Strings.Mapping_EnumTypeMappingToNonEnumType("Model.MessageType", "Model.MessageType"), - Assert.Throws( - () => OSpace_enum_type_and_CSpace_entity_type_have_the_same_name(false)).Message); - } - - [Fact] - public void Cannot_map_OSpace_entity_type_to_CSpace_enum_type_with_the_same_name_NonPOCO() - { - Assert.Equal( - Strings.Mapping_EnumTypeMappingToNonEnumType("Model.MessageType", "Model.MessageType"), - Assert.Throws( - () => OSpace_entity_type_and_CSpace_enum_type_have_the_same_name(false)).Message); - } - - // non-POCO specific cases - - [Fact] - public void EnumTypeVerifiedWhenLoadingEntityWithPropertyOfThisEnumType_NonPOCO() - { - var oSpaceCsdl = EnumCsdl(); - - oSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Member") - .Single(m => (string)m.Attribute("Name") == "Ground" && (string)m.Parent.Attribute("Name") == "MessageType") - .SetAttributeValue("Value", "64"); - - var workspace = PrepareModel(oSpaceCsdl, EnumCsdl(), false); - - Assert.Equal( - Strings.Mapping_Enum_OCMapping_MemberMismatch( - "MessageModel.MessageType", - "Ground", - "2", - "MessageModel.MessageType"), - Assert.Throws( - () => - GetMappedType(oSpaceCsdl, EnumCsdl(), "MessageModel.Message", false)).Message); - } - - [Fact] - public void Can_use_EdmEnumType_attribute_to_map_OSpace_enum_type_to_CSpace_enum_type_with_different_name_NonPOCO() - { - var cSpaceCsdl = EnumCsdl(); - cSpaceCsdl - .Element("{http://schemas.microsoft.com/ado/2009/11/edm}Schema") - .SetAttributeValue("Namespace", "MessageModelModified"); - - foreach (var attribute in cSpaceCsdl - .Descendants() - .Attributes() - .Where(a => ((string)a).StartsWith("MessageModel."))) - { - attribute.SetValue(((string)attribute).Replace("MessageModel.", "MessageModelModified.")); - } - - cSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") - .Single(e => (string)e.Attribute("Name") == "MessageType") - .SetAttributeValue("Name", "NewMessageType"); - - foreach (var propertyElement in cSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") - .Where(p => (string)p.Attribute("Type") == "MessageModelModified.MessageType")) - { - propertyElement.SetAttributeValue("Type", "MessageModelModified.NewMessageType"); - } - - - var oSpaceCsdl = EnumCsdl(); - - foreach (var typeElement in oSpaceCsdl - .Element("{http://schemas.microsoft.com/ado/2009/11/edm}Schema") - .Elements() - .Where(e => new string[] { "EntityType", "ComplexType", "EnumType" }.Contains(e.Name.LocalName))) - { - if ((string)typeElement.Attribute("Name") == "MessageType") - { - typeElement.SetAttributeValue("{MappingTestExtension}OSpaceTypeName", "NewMessageType"); - } - typeElement.SetAttributeValue("{MappingTestExtension}OSpaceTypeNamespace", "MessageModelModified"); - } - - var workspace = PrepareModel(oSpaceCsdl, cSpaceCsdl, false); - - Assert.Equal( - "MessageModel.Message:MessageModelModified.Message", - workspace.GetMap("MessageModel.Message", DataSpace.OSpace, DataSpace.OCSpace).Identity); - - Assert.Equal( - "MessageModel.MessageType:MessageModelModified.NewMessageType", - workspace.GetMap("MessageModel.MessageType", DataSpace.OSpace, DataSpace.OCSpace).Identity); - } - - [Fact] - public void Cannot_use_OSpace_enum_type_as_property_type_if_it_does_not_have_EdmTypeAttribute() - { - var oSpaceCsdl = EnumCsdl(); - - oSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") - .Single(p => (string)p.Attribute("Name") == "MessageType") - .SetAttributeValue("{MappingTestExtension}SuppressEdmTypeAttribute", true); - - var exception = - Assert.Throws(() => PrepareModel(oSpaceCsdl, EnumCsdl(), false)); - - Assert.Contains( - Strings.Validator_OSpace_ScalarPropertyNotPrimitive( - "MessageType", - "MessageModel.Message", - "MessageModel.MessageType"), - exception.Message); - - Assert.Contains( - Strings.Validator_OSpace_ScalarPropertyNotPrimitive( - "TypeOfMessage", - "MessageModel.MessageTypeLookUp", - "MessageModel.MessageType"), - exception.Message); - } - - [Fact] - public void Cannot_have_2_OSpace_enum_types_mapped_to_single_CSpace_enum_type() - { - var additionalMatchingEnumType = EnumCsdl(); - additionalMatchingEnumType - .Element("{http://schemas.microsoft.com/ado/2009/11/edm}Schema") - .Elements() - .Where(e => (string)e.Attribute("Name") != "MessageType") - .Remove(); - - additionalMatchingEnumType - .Element("{http://schemas.microsoft.com/ado/2009/11/edm}Schema") - .SetAttributeValue("Namespace", "MessageModelAddendum"); - - var enumTypeElement = - additionalMatchingEnumType. - Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") - .Single(); - - enumTypeElement.SetAttributeValue("{MappingTestExtension}OSpaceTypeName", "MessageType"); - enumTypeElement.SetAttributeValue("{MappingTestExtension}OSpaceTypeNamespace", "MessageModel"); - - Assert.Equal( - Strings.Mapping_CannotMapCLRTypeMultipleTimes("MessageModel.MessageType"), - Assert.Throws(() => - CreateMetadataWorkspace( - EnumCsdl(), - BuildAssembly(false, EnumCsdl(), additionalMatchingEnumType), - false)).Message); - } - - #endregion - - private static void Verify_simple_enum_mapping(bool isPOCO) - { - var workspace = PrepareModel(/* oSpaceCsdl */ EnumCsdl(), /* cSpaceCsdl */ EnumCsdl(), isPOCO); - - Assert.Equal( - "MessageModel.MessageType:MessageModel.MessageType", - workspace.GetMap("MessageModel.MessageType", DataSpace.OSpace, DataSpace.OCSpace).Identity); - - Assert.Equal( - "MessageModel.Message:MessageModel.Message", - workspace.GetMap("MessageModel.Message", DataSpace.OSpace, DataSpace.OCSpace).Identity); - } - - private static void Complex_type_with_enum_property_is_mapped_correctly(bool isPOCO) - { - var complexType = XElement.Parse( -@" - -"); - - var csdl = EnumCsdl(); - - csdl - .Element("{http://schemas.microsoft.com/ado/2009/11/edm}Schema") - .Add(complexType); - - csdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EntityType") - .Single(e => (string)e.Attribute("Name") == "Message") - .Add(new XElement("{http://schemas.microsoft.com/ado/2009/11/edm}Property", - new XAttribute("Name", "ComplexProperty"), - new XAttribute("Type", "MessageModel.Complex"), - new XAttribute("Nullable", "false"))); - - var workspace = PrepareModel(/* oSpaceCsdl */ csdl, /* cSpaceCsdl */ csdl, isPOCO); - - Assert.Equal( - "MessageModel.MessageType:MessageModel.MessageType", - workspace.GetMap("MessageModel.MessageType", DataSpace.OSpace, DataSpace.OCSpace).Identity); - - Assert.Equal( - "MessageModel.Message:MessageModel.Message", - workspace.GetMap("MessageModel.Message", DataSpace.OSpace, DataSpace.OCSpace).Identity); - - Assert.Equal( - "MessageModel.Complex:MessageModel.Complex", - workspace.GetMap("MessageModel.Complex", DataSpace.OSpace, DataSpace.OCSpace).Identity); - } - - private static void Enums_with_members_with_same_values_are_mapped_even_if_order_is_different(bool isPOCO) - { - var oSpaceCsdl = EnumCsdl(); - var oSpaceEnumType = oSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") - .Single(e => (string)e.Attribute("Name") == "ContentsType"); - - oSpaceEnumType.Add(new XElement("{http://schemas.microsoft.com/ado/2009/11/edm}Member", - new XAttribute("Name", "LegacyType"), - new XAttribute("Value", 0))); - - var cSpaceCsdl = new XDocument(oSpaceCsdl); - var cSpaceEnumType = cSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") - .Single(e => (string)e.Attribute("Name") == "ContentsType"); - - var sortedMemberElements = cSpaceEnumType.Elements().OrderByDescending(e => (string)e.Attribute("Name")).ToArray(); - - cSpaceEnumType.Elements().Remove(); - cSpaceEnumType.Add(sortedMemberElements); - - Assert.Equal( - "MessageModel.ContentsType:MessageModel.ContentsType", - GetMappedType(oSpaceCsdl, cSpaceCsdl, "MessageModel.ContentsType", isPOCO).Identity); - } - - private static void Nullability_of_enum_properties_ignored_for_mapping(bool isPOCO) - { - var oSpaceCsdl = EnumCsdl(); - oSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") - .Single(e => (string)e.Attribute("Name") == "MessageType" && (string)e.Parent.Attribute("Name") == "Message") - .SetAttributeValue("Nullable", true); - - oSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") - .Single(e => (string)e.Attribute("Name") == "ContentsType") - .SetAttributeValue("Nullable", false); - - var cSpaceCsdl = EnumCsdl(); - cSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") - .Single(e => (string)e.Attribute("Name") == "MessageType" && (string)e.Parent.Attribute("Name") == "Message") - .SetAttributeValue("Nullable", false); - - cSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") - .Single(e => (string)e.Attribute("Name") == "ContentsType") - .SetAttributeValue("Nullable", true); - - Assert.Equal( - "MessageModel.Message:MessageModel.Message", - GetMappedType(oSpaceCsdl, cSpaceCsdl, "MessageModel.Message", isPOCO).Identity); - } - - private static void Can_map_enum_type_with_no_members(bool isPOCO) - { - var enumCsdl = EnumCsdl(); - enumCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Member") - .Remove(); - - Assert.Equal( - "MessageModel.Message:MessageModel.Message", - GetMappedType(enumCsdl, enumCsdl, "MessageModel.Message", isPOCO).Identity); - } - - private static void Cannot_map_OSpace_enum_type_with_unsupported_underlying_type(bool isPOCO) - { - var oSpaceCsdl = EnumCsdl(); - oSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") - .Single(p => (string)p.Attribute("Name") == "MessageType") - .SetAttributeValue("UnderlyingType", "UInt32"); - - PrepareModel(oSpaceCsdl, EnumCsdl(), isPOCO); - } - - private static void Cannot_map_enum_types_if_names_are_different(bool isPOCO) - { - var oSpaceCsdl = EnumCsdl(); - - oSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") - .Single(e => (string)e.Attribute("Name") == "PaymentMethod") - .SetAttributeValue("Name", "ShippingType"); - - oSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") - .Single(p => (string)p.Attribute("Name") == "PaymentMethod") - .SetAttributeValue("Type", "MessageModel.ShippingType"); - - GetMappedType(oSpaceCsdl, EnumCsdl(), "MessageModel.ShippingType", isPOCO); - } - - private static void Cannot_map_enum_types_if_underlying_types_dont_match(bool isPOCO) - { - var oSpaceCsdl = EnumCsdl(); - - oSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") - .Single(e => (string)e.Attribute("Name") == "MessageType") - .SetAttributeValue("UnderlyingType", "Int64"); - - GetMappedType(oSpaceCsdl, EnumCsdl(), "MessageModel.MessageType", isPOCO); - } - - private static void Cannot_map_OSpace_enum_type_with_fewer_members_than_CSpace_enum_type(bool isPOCO) - { - var oSpaceCsdl = EnumCsdl(); - - oSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Member") - .Where(m => (string)m.Attribute("Name") == "Ground" && (string)m.Parent.Attribute("Name") == "MessageType") - .Remove(); - - GetMappedType(oSpaceCsdl, EnumCsdl(), "MessageModel.MessageType", isPOCO); - } - - private static void Cannot_map_OSpace_enum_type_whose_member_name_does_not_match_CSpace_enum_type_member_name(bool isPOCO) - { - var oSpaceCsdl = EnumCsdl(); - - oSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Member") - .Single(m => (string)m.Attribute("Name") == "Ground" && (string)m.Parent.Attribute("Name") == "MessageType") - .SetAttributeValue("Name", "Ground1"); - - GetMappedType(oSpaceCsdl, EnumCsdl(), "MessageModel.MessageType", isPOCO); - } - - private static void Can_map_OSpace_enum_type_that_has_more_members_than_CSPace_enum_type_if_members_match(bool isPOCO) - { - var oSpaceCsdl = EnumCsdl(); - - var enumType = oSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") - .Single(e => (string)e.Attribute("Name") == "MessageType"); - - enumType.Add(new XElement("{http://schemas.microsoft.com/ado/2009/11/edm}Member", - new XAttribute("Name", "LegacyType"), - new XAttribute("Value", 0))); - - Assert.Equal( - "MessageModel.Message:MessageModel.Message", - GetMappedType(oSpaceCsdl, EnumCsdl(), "MessageModel.Message", isPOCO).Identity); - } - - private static void Can_map_CSpace_enum_type_with_no_enum_members(bool isPOCO) - { - var cSpaceCsdl = EnumCsdl(); - - cSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") - .Single(e => (string)e.Attribute("Name") == "MessageType") - .Elements() - .Remove(); - - Assert.Equal( - "MessageModel.Message:MessageModel.Message", - GetMappedType(EnumCsdl(), cSpaceCsdl, "MessageModel.Message", isPOCO).Identity); - } - - private static void Cannot_map_if_OSpace_enum_type_member_value_does_not_match_CSpace_enum_type_member_value(bool isPOCO) - { - var oSpaceCsdl = EnumCsdl(); - - oSpaceCsdl - .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Member") - .Single(m => (string)m.Attribute("Name") == "Ground" && (string)m.Parent.Attribute("Name") == "MessageType") - .SetAttributeValue("Value", "64"); - - GetMappedType(oSpaceCsdl, EnumCsdl(), "MessageModel.MessageType", isPOCO); - } - - private static void OSpace_enum_type_and_CSpace_entity_type_have_the_same_name(bool isPOCO) - { - var oSpaceCsdl = XDocument.Parse( -@" - -"); - - var cSpaceCsdl = XDocument.Parse( -@" - - - - - - -"); - - GetMappedType(oSpaceCsdl, cSpaceCsdl, "Model.MessageType", isPOCO); - } - - private static void OSpace_entity_type_and_CSpace_enum_type_have_the_same_name(bool isPOCO) - { - var oSpaceCsdl = XDocument.Parse( -@" - - - - - - -"); - - var cSpaceCsdl = XDocument.Parse( -@" - -"); - - GetMappedType(oSpaceCsdl, cSpaceCsdl, "Model.MessageType", isPOCO); - } - - private static Map GetMappedType(XDocument oSpaceCsdl, XDocument cSpaceCsdl, string oSpaceTypeName, bool isPOCO) - { - var workspace = PrepareModel(oSpaceCsdl, cSpaceCsdl, isPOCO); - return workspace.GetMap(oSpaceTypeName, DataSpace.OSpace, DataSpace.OCSpace); - } - - private static Assembly BuildAssembly(bool isPOCO, params XDocument[] oSpaceCsdl) - { - return - new CsdlToClrAssemblyConverter(isPOCO, oSpaceCsdl) - .BuildAssembly(Guid.NewGuid().ToString()); - } - - private static MetadataWorkspace PrepareModel(XDocument oSpaceCsdl, XDocument cSpaceCsdl, bool isPOCO) - { - return CreateMetadataWorkspace( - cSpaceCsdl, - BuildAssembly(isPOCO, oSpaceCsdl), - isPOCO); - } - - private static MetadataWorkspace CreateMetadataWorkspace(XDocument cSpaceCsdl, Assembly assembly, bool isPOCO) - { - var workspace = new MetadataWorkspace(); - - EdmItemCollection edmItemCollection; - - using (var csdlReader = cSpaceCsdl.CreateReader()) - { - edmItemCollection = new EdmItemCollection(new XmlReader[] { csdlReader }); - } - workspace.RegisterItemCollection(edmItemCollection); - - - // assembly can actually be an AssemblyBuilder. The following line ensures that we are - // using the actual assembly otherwise an Assert in ObjectItemAttributeAssemblyLoader.LoadType - // will fire. - assembly = assembly.GetTypes().First().Assembly; - var objectItemCollection = new ObjectItemCollection(); - - if (isPOCO) - { - objectItemCollection.LoadFromAssembly(assembly, edmItemCollection); - } - else - { - objectItemCollection.LoadFromAssembly(assembly); - } - - workspace.RegisterItemCollection(objectItemCollection); - - return workspace; - } - } -} + +namespace System.Data.Entity.MetadataMapping +{ + using System.Data.Entity.Core; + using System.Data.Entity.Core.Mapping; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.Resources; + using System.Data.Entity.TestHelpers; + using System.IO; + using System.Linq; + using System.Reflection; + using System.Xml; + using System.Xml.Linq; + using Xunit; + + public class EnumOCMappingTests : FunctionalTestBase + { + private static XDocument EnumCsdl() + { + return XDocument.Load( + Assembly + .GetExecutingAssembly() + .GetManifestResourceStream("System.Data.Entity.MetadataMapping.Enum.csdl")); + } + #region convention loader (POCO) + + [Fact] + public void Verify_simple_enum_mapping_POCO() + { + Verify_simple_enum_mapping(true); + } + + [Fact] + public void Complex_type_with_eumm_property_is_mapped_correctly_POCO() + { + Complex_type_with_enum_property_is_mapped_correctly(true); + } + + [Fact] + public void Enums_with_members_with_same_values_are_mapped_even_if_order_is_different_POCO() + { + Enums_with_members_with_same_values_are_mapped_even_if_order_is_different(true); + } + + [Fact] + public void Nullability_of_enum_properties_ignored_for_mapping_POCO() + { + Nullability_of_enum_properties_ignored_for_mapping(true); + } + + [Fact] + public void Can_map_enum_type_with_no_members_POCO() + { + Can_map_enum_type_with_no_members(true); + } + + [Fact] + public void Cannot_map_OSpace_enum_type_with_unsupported_underlying_type_POCO() + { + var exception = + Assert.Throws( + () => Cannot_map_OSpace_enum_type_with_unsupported_underlying_type(true)); + + Assert.Contains( + Strings.Validator_OSpace_Convention_MissingOSpaceType("MessageModel.MessageType"), + exception.Message); + + Assert.Contains( + Strings.Validator_UnsupportedEnumUnderlyingType("System.UInt32"), + exception.Message); + + } + + [Fact] + public void Cannot_map_enum_types_if_names_are_different_POCO() + { + Assert.Contains( + Strings.Validator_OSpace_Convention_MissingOSpaceType("MessageModel.PaymentMethod"), + Assert.Throws( + () => Cannot_map_enum_types_if_names_are_different(true)).Message); + } + + [Fact] + public void Cannot_map_enum_types_if_underlying_types_dont_match_POCO() + { + var exception = Assert.Throws( + () => Cannot_map_enum_types_if_underlying_types_dont_match(true)); + + Assert.Contains( + Strings.Validator_OSpace_Convention_MissingOSpaceType("MessageModel.MessageType"), + exception.Message); + + Assert.Contains( + Strings.Validator_OSpace_Convention_NonMatchingUnderlyingTypes, + exception.Message); + } + + [Fact] + public void Cannot_map_OSpace_enum_type_with_fewer_members_than_CSpace_enum_type_POCO() + { + var exception = Assert.Throws( + () => Cannot_map_OSpace_enum_type_with_fewer_members_than_CSpace_enum_type(true)); + + Assert.Contains( + Strings.Validator_OSpace_Convention_MissingOSpaceType("MessageModel.MessageType"), + exception.Message); + + Assert.Contains( + Strings.Mapping_Enum_OCMapping_MemberMismatch("MessageModel.MessageType", "Ground", 2, "MessageModel.MessageType"), + exception.Message); + } + + [Fact] + public void Cannot_map_OSpace_enum_type_whose_member_name_does_not_match_CSpace_enum_type_member_name_POCO() + { + var exception = Assert.Throws( + () => + Cannot_map_OSpace_enum_type_whose_member_name_does_not_match_CSpace_enum_type_member_name(true)); + + Assert.Contains( + Strings.Validator_OSpace_Convention_MissingOSpaceType("MessageModel.MessageType"), + exception.Message); + + Assert.Contains( + Strings.Mapping_Enum_OCMapping_MemberMismatch("MessageModel.MessageType", "Ground", 2, "MessageModel.MessageType"), + exception.Message); + } + + [Fact] + public void Can_map_OSpace_enum_type_that_has_more_members_than_CSPace_enum_type_if_members_match_POCO() + { + Can_map_OSpace_enum_type_that_has_more_members_than_CSPace_enum_type_if_members_match(true); + } + + [Fact] + public void Can_map_CSpace_enum_type_with_no_enum_members_POCO() + { + Can_map_CSpace_enum_type_with_no_enum_members(true); + } + + [Fact] + public void Cannot_map_if_OSpace_enum_type_member_value_does_not_match_CSpace_enum_type_member_value_POCO() + { + var exception = Assert.Throws( + () => + Cannot_map_if_OSpace_enum_type_member_value_does_not_match_CSpace_enum_type_member_value(true)); + + Assert.Contains( + Strings.Validator_OSpace_Convention_MissingOSpaceType("MessageModel.MessageType"), + exception.Message); + + Assert.Contains( + Strings.Mapping_Enum_OCMapping_MemberMismatch("MessageModel.MessageType", "Ground", 2, "MessageModel.MessageType"), + exception.Message); + } + + [Fact] + public void Verify_OSpace_enum_type_is_not_mapped_to_CSpace_entity_type_with_same_name_POCO() + { + Assert.Equal( + Strings.Mapping_Object_InvalidType("Model.MessageType"), + Assert.Throws( + () => OSpace_enum_type_and_CSpace_entity_type_have_the_same_name(true)).Message); + } + + [Fact] + public void Verify_OSpace_entity_type_is_not_mapped_to_CSpace_enum_type_with_same_name_POCO() + { + Assert.Equal( + Strings.Mapping_Object_InvalidType("Model.MessageType"), + Assert.Throws( + () => OSpace_entity_type_and_CSpace_enum_type_have_the_same_name(true)).Message); + } + + // POCO specific cases + + [Fact] + public void Correct_CSpace_enum_type_is_mapped_if_multiple_OSpace_enum_types_exist_but_only_one_matches() + { + var additionalEnumType = XDocument.Parse( +@" + +"); + + var workspace = + CreateMetadataWorkspace( + EnumCsdl(), + BuildAssembly(true, EnumCsdl(), additionalEnumType), + true); + + Assert.Equal( + "MessageModel.MessageType:MessageModel.MessageType", + workspace.GetMap("MessageModel.MessageType", DataSpace.OSpace, DataSpace.OCSpace).Identity); + + Assert.Equal( + "MessageModel.Message:MessageModel.Message", + workspace.GetMap("MessageModel.Message", DataSpace.OSpace, DataSpace.OCSpace).Identity); + } + + [Fact] + public void Mapping_fails_for_multiple_OSpace_enum_types_matching_the_same_CSpace_enum_type_POCO() + { + var additionalMatchingEnumType = XDocument.Parse( +@" + + + + + + +"); + + var assembly = BuildAssembly(true, EnumCsdl(), additionalMatchingEnumType); + Assert.Contains( + Strings.Validator_OSpace_Convention_AmbiguousClrType( + "MessageType", + "MessageModel.MessageType", + "MessageModel1.MessageType"), + Assert.Throws( + () => CreateMetadataWorkspace(EnumCsdl(), assembly, true)).Message); + } + + [Fact] + public void Cannot_create_workspace_if_OSpace_enum_property_does_not_have_getter() + { + var oSpaceCsdl = EnumCsdl(); + oSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") + .Single(p => (string)p.Attribute("Name") == "MessageType") + .SetAttributeValue("{MappingTestExtension}SuppressGetter", true); + + var assembly = BuildAssembly(true, oSpaceCsdl); + + Assert.Contains( + Strings.Validator_OSpace_Convention_ScalarPropertyMissginGetterOrSetter( + "MessageType", + "MessageModel.Message", + assembly.FullName), + Assert.Throws( + () => CreateMetadataWorkspace(EnumCsdl(), assembly, true)).Message); + } + + [Fact] + public void Cannot_create_workspace_if_OSpace_enum_property_does_not_have_setter() + { + var oSpaceCsdl = EnumCsdl(); + oSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") + .Single(p => (string)p.Attribute("Name") == "MessageType") + .SetAttributeValue("{MappingTestExtension}SuppressSetter", true); + + var assembly = BuildAssembly(true, oSpaceCsdl); + + Assert.Contains( + Strings.Validator_OSpace_Convention_ScalarPropertyMissginGetterOrSetter( + "MessageType", + "MessageModel.Message", + assembly.FullName), + Assert.Throws( + () => CreateMetadataWorkspace(EnumCsdl(), assembly, true)).Message); + } + + [Fact] + public void Can_load_entity_with_property_of_enum_type_from_different_assembly() + { + const bool isPOCO = true; + + var enumTypeCsdl = XDocument.Parse( +@" + +"); + + var entityTypeCsdl = XDocument.Parse( +@" + + + + + + + + + + +"); + + var assemblyWithEnumType = BuildAssembly(isPOCO, enumTypeCsdl); + var assemblyWithEntityType = BuildAssembly(isPOCO, entityTypeCsdl); + + EdmItemCollection edmItemCollection; + + var workspace = new MetadataWorkspace(); + using (var enumTypeReader = enumTypeCsdl.CreateReader()) + using (var entityTypeReader = entityTypeCsdl.CreateReader()) + { + edmItemCollection = + new EdmItemCollection( + new XmlReader[] { enumTypeReader, entityTypeReader }); + } + workspace.RegisterItemCollection(edmItemCollection); + + var objectItemCollection = new ObjectItemCollection(); + + objectItemCollection.LoadFromAssembly(assemblyWithEnumType, edmItemCollection); + objectItemCollection.LoadFromAssembly(assemblyWithEntityType, edmItemCollection); + workspace.RegisterItemCollection(objectItemCollection); + + Assert.Equal( + "EnumModel.Entity:EnumModel.Entity", + workspace.GetMap("EnumModel.Entity", DataSpace.OSpace, DataSpace.OCSpace).Identity); + } + + + #endregion + + #region attribute loader (non-POCO) + + [Fact] + public void Verify_simple_enum_mapping_non_POCO() + { + Verify_simple_enum_mapping(false); + } + + [Fact] + public void Complex_type_with_enum_property_is_mapped_correctly_NonPOCO() + { + Complex_type_with_enum_property_is_mapped_correctly(false); + } + + [Fact] + public void Enums_with_members_with_same_values_are_mapped_even_if_order_is_different_NonPOCO() + { + Enums_with_members_with_same_values_are_mapped_even_if_order_is_different(false); + } + + [Fact] + public void Nullability_of_enum_properties_ignored_for_mapping_NonPOCO() + { + Nullability_of_enum_properties_ignored_for_mapping(false); + } + + [Fact] + public void Can_map_enum_type_with_no_members_NonPOCO() + { + Can_map_enum_type_with_no_members(false); + } + + [Fact] + public void Cannot_map_OSpace_enum_type_with_unsupported_underlying_NonPOCO() + { + var exception = + Assert.Throws( + () => Cannot_map_OSpace_enum_type_with_unsupported_underlying_type(false)); + + Assert.Contains( + Strings.Validator_OSpace_ScalarPropertyNotPrimitive( + "TypeOfMessage", + "MessageModel.MessageTypeLookUp", + "MessageModel.MessageType"), + exception.Message); + + Assert.Contains( + Strings.Validator_UnsupportedEnumUnderlyingType("System.UInt32"), + exception.Message); + + } + + [Fact] + public void Cannot_map_enum_types_if_names_are_different_NonPOCO() + { + Assert.Equal( + Strings.Mapping_Object_InvalidType("MessageModel.ShippingType"), + Assert.Throws( + () => Cannot_map_enum_types_if_names_are_different(false)).Message); + + } + + [Fact] + public void OSpaceEnumUnderlyingTypeDoesNotMatchCSpaceEnumUnderlyingTypeName_NonPOCO() + { + Assert.Contains( + Strings.Mapping_Enum_OCMapping_UnderlyingTypesMismatch("Int32", "MessageModel.MessageType", "Int64", "MessageModel.MessageType"), + Assert.Throws( + () => Cannot_map_enum_types_if_underlying_types_dont_match(false)).Message); + } + + [Fact] + public void Cannot_map_OSpace_enum_type_with_fewer_members_than_CSpace_enum_type_NonPOCO() + { + Assert.Equal( + Strings.Mapping_Enum_OCMapping_MemberMismatch("MessageModel.MessageType", "Ground", 2, "MessageModel.MessageType"), + Assert.Throws( + () => Cannot_map_OSpace_enum_type_with_fewer_members_than_CSpace_enum_type(false)).Message); + } + + [Fact] + public void OSpaceEnumTypeMemberNameDoesNotMatchCSpaceEnumTypeMemberName_NonPOCO() + { + Assert.Equal( + Strings.Mapping_Enum_OCMapping_MemberMismatch("MessageModel.MessageType", "Ground", 2, "MessageModel.MessageType"), + Assert.Throws( + () => + Cannot_map_OSpace_enum_type_whose_member_name_does_not_match_CSpace_enum_type_member_name(false)) + .Message); + } + + [Fact] + public void Can_map_OSpace_enum_type_that_has_more_members_than_CSPace_enum_type_if_members_match_NonPOCO() + { + Can_map_OSpace_enum_type_that_has_more_members_than_CSPace_enum_type_if_members_match(false); + } + + [Fact] + public void Can_map_CSpace_enum_type_with_no_enum_members_NonPOCO() + { + Can_map_CSpace_enum_type_with_no_enum_members(false); + } + + [Fact] + public void Cannot_map_if_OSpace_enum_type_member_value_does_not_match_CSpace_enum_type_member_value_NonPOCO() + { + Assert.Equal( + Strings.Mapping_Enum_OCMapping_MemberMismatch("MessageModel.MessageType", "Ground", 2, "MessageModel.MessageType"), + Assert.Throws( + () => + Cannot_map_if_OSpace_enum_type_member_value_does_not_match_CSpace_enum_type_member_value(false)).Message); + } + + [Fact] + public void Cannot_map_OSpace_enum_type_to_CSpace_entity_type_with_the_same_name_NonPOCO() + { + Assert.Equal( + Strings.Mapping_EnumTypeMappingToNonEnumType("Model.MessageType", "Model.MessageType"), + Assert.Throws( + () => OSpace_enum_type_and_CSpace_entity_type_have_the_same_name(false)).Message); + } + + [Fact] + public void Cannot_map_OSpace_entity_type_to_CSpace_enum_type_with_the_same_name_NonPOCO() + { + Assert.Equal( + Strings.Mapping_EnumTypeMappingToNonEnumType("Model.MessageType", "Model.MessageType"), + Assert.Throws( + () => OSpace_entity_type_and_CSpace_enum_type_have_the_same_name(false)).Message); + } + + // non-POCO specific cases + + [Fact] + public void EnumTypeVerifiedWhenLoadingEntityWithPropertyOfThisEnumType_NonPOCO() + { + var oSpaceCsdl = EnumCsdl(); + + oSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Member") + .Single(m => (string)m.Attribute("Name") == "Ground" && (string)m.Parent.Attribute("Name") == "MessageType") + .SetAttributeValue("Value", "64"); + + var workspace = PrepareModel(oSpaceCsdl, EnumCsdl(), false); + + Assert.Equal( + Strings.Mapping_Enum_OCMapping_MemberMismatch( + "MessageModel.MessageType", + "Ground", + "2", + "MessageModel.MessageType"), + Assert.Throws( + () => + GetMappedType(oSpaceCsdl, EnumCsdl(), "MessageModel.Message", false)).Message); + } + + [Fact] + public void Can_use_EdmEnumType_attribute_to_map_OSpace_enum_type_to_CSpace_enum_type_with_different_name_NonPOCO() + { + var cSpaceCsdl = EnumCsdl(); + cSpaceCsdl + .Element("{http://schemas.microsoft.com/ado/2009/11/edm}Schema") + .SetAttributeValue("Namespace", "MessageModelModified"); + + foreach (var attribute in cSpaceCsdl + .Descendants() + .Attributes() + .Where(a => ((string)a).StartsWith("MessageModel."))) + { + attribute.SetValue(((string)attribute).Replace("MessageModel.", "MessageModelModified.")); + } + + cSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") + .Single(e => (string)e.Attribute("Name") == "MessageType") + .SetAttributeValue("Name", "NewMessageType"); + + foreach (var propertyElement in cSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") + .Where(p => (string)p.Attribute("Type") == "MessageModelModified.MessageType")) + { + propertyElement.SetAttributeValue("Type", "MessageModelModified.NewMessageType"); + } + + + var oSpaceCsdl = EnumCsdl(); + + foreach (var typeElement in oSpaceCsdl + .Element("{http://schemas.microsoft.com/ado/2009/11/edm}Schema") + .Elements() + .Where(e => new string[] { "EntityType", "ComplexType", "EnumType" }.Contains(e.Name.LocalName))) + { + if ((string)typeElement.Attribute("Name") == "MessageType") + { + typeElement.SetAttributeValue("{MappingTestExtension}OSpaceTypeName", "NewMessageType"); + } + typeElement.SetAttributeValue("{MappingTestExtension}OSpaceTypeNamespace", "MessageModelModified"); + } + + var workspace = PrepareModel(oSpaceCsdl, cSpaceCsdl, false); + + Assert.Equal( + "MessageModel.Message:MessageModelModified.Message", + workspace.GetMap("MessageModel.Message", DataSpace.OSpace, DataSpace.OCSpace).Identity); + + Assert.Equal( + "MessageModel.MessageType:MessageModelModified.NewMessageType", + workspace.GetMap("MessageModel.MessageType", DataSpace.OSpace, DataSpace.OCSpace).Identity); + } + + [Fact] + public void Cannot_use_OSpace_enum_type_as_property_type_if_it_does_not_have_EdmTypeAttribute() + { + var oSpaceCsdl = EnumCsdl(); + + oSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") + .Single(p => (string)p.Attribute("Name") == "MessageType") + .SetAttributeValue("{MappingTestExtension}SuppressEdmTypeAttribute", true); + + var exception = + Assert.Throws(() => PrepareModel(oSpaceCsdl, EnumCsdl(), false)); + + Assert.Contains( + Strings.Validator_OSpace_ScalarPropertyNotPrimitive( + "MessageType", + "MessageModel.Message", + "MessageModel.MessageType"), + exception.Message); + + Assert.Contains( + Strings.Validator_OSpace_ScalarPropertyNotPrimitive( + "TypeOfMessage", + "MessageModel.MessageTypeLookUp", + "MessageModel.MessageType"), + exception.Message); + } + + [Fact] + public void Cannot_have_2_OSpace_enum_types_mapped_to_single_CSpace_enum_type() + { + var additionalMatchingEnumType = EnumCsdl(); + additionalMatchingEnumType + .Element("{http://schemas.microsoft.com/ado/2009/11/edm}Schema") + .Elements() + .Where(e => (string)e.Attribute("Name") != "MessageType") + .Remove(); + + additionalMatchingEnumType + .Element("{http://schemas.microsoft.com/ado/2009/11/edm}Schema") + .SetAttributeValue("Namespace", "MessageModelAddendum"); + + var enumTypeElement = + additionalMatchingEnumType. + Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") + .Single(); + + enumTypeElement.SetAttributeValue("{MappingTestExtension}OSpaceTypeName", "MessageType"); + enumTypeElement.SetAttributeValue("{MappingTestExtension}OSpaceTypeNamespace", "MessageModel"); + + Assert.Equal( + Strings.Mapping_CannotMapCLRTypeMultipleTimes("MessageModel.MessageType"), + Assert.Throws(() => + CreateMetadataWorkspace( + EnumCsdl(), + BuildAssembly(false, EnumCsdl(), additionalMatchingEnumType), + false)).Message); + } + + #endregion + + private static void Verify_simple_enum_mapping(bool isPOCO) + { + var workspace = PrepareModel(/* oSpaceCsdl */ EnumCsdl(), /* cSpaceCsdl */ EnumCsdl(), isPOCO); + + Assert.Equal( + "MessageModel.MessageType:MessageModel.MessageType", + workspace.GetMap("MessageModel.MessageType", DataSpace.OSpace, DataSpace.OCSpace).Identity); + + Assert.Equal( + "MessageModel.Message:MessageModel.Message", + workspace.GetMap("MessageModel.Message", DataSpace.OSpace, DataSpace.OCSpace).Identity); + } + + private static void Complex_type_with_enum_property_is_mapped_correctly(bool isPOCO) + { + var complexType = XElement.Parse( +@" + +"); + + var csdl = EnumCsdl(); + + csdl + .Element("{http://schemas.microsoft.com/ado/2009/11/edm}Schema") + .Add(complexType); + + csdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EntityType") + .Single(e => (string)e.Attribute("Name") == "Message") + .Add(new XElement("{http://schemas.microsoft.com/ado/2009/11/edm}Property", + new XAttribute("Name", "ComplexProperty"), + new XAttribute("Type", "MessageModel.Complex"), + new XAttribute("Nullable", "false"))); + + var workspace = PrepareModel(/* oSpaceCsdl */ csdl, /* cSpaceCsdl */ csdl, isPOCO); + + Assert.Equal( + "MessageModel.MessageType:MessageModel.MessageType", + workspace.GetMap("MessageModel.MessageType", DataSpace.OSpace, DataSpace.OCSpace).Identity); + + Assert.Equal( + "MessageModel.Message:MessageModel.Message", + workspace.GetMap("MessageModel.Message", DataSpace.OSpace, DataSpace.OCSpace).Identity); + + Assert.Equal( + "MessageModel.Complex:MessageModel.Complex", + workspace.GetMap("MessageModel.Complex", DataSpace.OSpace, DataSpace.OCSpace).Identity); + } + + private static void Enums_with_members_with_same_values_are_mapped_even_if_order_is_different(bool isPOCO) + { + var oSpaceCsdl = EnumCsdl(); + var oSpaceEnumType = oSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") + .Single(e => (string)e.Attribute("Name") == "ContentsType"); + + oSpaceEnumType.Add(new XElement("{http://schemas.microsoft.com/ado/2009/11/edm}Member", + new XAttribute("Name", "LegacyType"), + new XAttribute("Value", 0))); + + var cSpaceCsdl = new XDocument(oSpaceCsdl); + var cSpaceEnumType = cSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") + .Single(e => (string)e.Attribute("Name") == "ContentsType"); + + var sortedMemberElements = cSpaceEnumType.Elements().OrderByDescending(e => (string)e.Attribute("Name")).ToArray(); + + cSpaceEnumType.Elements().Remove(); + cSpaceEnumType.Add(sortedMemberElements); + + Assert.Equal( + "MessageModel.ContentsType:MessageModel.ContentsType", + GetMappedType(oSpaceCsdl, cSpaceCsdl, "MessageModel.ContentsType", isPOCO).Identity); + } + + private static void Nullability_of_enum_properties_ignored_for_mapping(bool isPOCO) + { + var oSpaceCsdl = EnumCsdl(); + oSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") + .Single(e => (string)e.Attribute("Name") == "MessageType" && (string)e.Parent.Attribute("Name") == "Message") + .SetAttributeValue("Nullable", true); + + oSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") + .Single(e => (string)e.Attribute("Name") == "ContentsType") + .SetAttributeValue("Nullable", false); + + var cSpaceCsdl = EnumCsdl(); + cSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") + .Single(e => (string)e.Attribute("Name") == "MessageType" && (string)e.Parent.Attribute("Name") == "Message") + .SetAttributeValue("Nullable", false); + + cSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") + .Single(e => (string)e.Attribute("Name") == "ContentsType") + .SetAttributeValue("Nullable", true); + + Assert.Equal( + "MessageModel.Message:MessageModel.Message", + GetMappedType(oSpaceCsdl, cSpaceCsdl, "MessageModel.Message", isPOCO).Identity); + } + + private static void Can_map_enum_type_with_no_members(bool isPOCO) + { + var enumCsdl = EnumCsdl(); + enumCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Member") + .Remove(); + + Assert.Equal( + "MessageModel.Message:MessageModel.Message", + GetMappedType(enumCsdl, enumCsdl, "MessageModel.Message", isPOCO).Identity); + } + + private static void Cannot_map_OSpace_enum_type_with_unsupported_underlying_type(bool isPOCO) + { + var oSpaceCsdl = EnumCsdl(); + oSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") + .Single(p => (string)p.Attribute("Name") == "MessageType") + .SetAttributeValue("UnderlyingType", "UInt32"); + + PrepareModel(oSpaceCsdl, EnumCsdl(), isPOCO); + } + + private static void Cannot_map_enum_types_if_names_are_different(bool isPOCO) + { + var oSpaceCsdl = EnumCsdl(); + + oSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") + .Single(e => (string)e.Attribute("Name") == "PaymentMethod") + .SetAttributeValue("Name", "ShippingType"); + + oSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Property") + .Single(p => (string)p.Attribute("Name") == "PaymentMethod") + .SetAttributeValue("Type", "MessageModel.ShippingType"); + + GetMappedType(oSpaceCsdl, EnumCsdl(), "MessageModel.ShippingType", isPOCO); + } + + private static void Cannot_map_enum_types_if_underlying_types_dont_match(bool isPOCO) + { + var oSpaceCsdl = EnumCsdl(); + + oSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") + .Single(e => (string)e.Attribute("Name") == "MessageType") + .SetAttributeValue("UnderlyingType", "Int64"); + + GetMappedType(oSpaceCsdl, EnumCsdl(), "MessageModel.MessageType", isPOCO); + } + + private static void Cannot_map_OSpace_enum_type_with_fewer_members_than_CSpace_enum_type(bool isPOCO) + { + var oSpaceCsdl = EnumCsdl(); + + oSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Member") + .Where(m => (string)m.Attribute("Name") == "Ground" && (string)m.Parent.Attribute("Name") == "MessageType") + .Remove(); + + GetMappedType(oSpaceCsdl, EnumCsdl(), "MessageModel.MessageType", isPOCO); + } + + private static void Cannot_map_OSpace_enum_type_whose_member_name_does_not_match_CSpace_enum_type_member_name(bool isPOCO) + { + var oSpaceCsdl = EnumCsdl(); + + oSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Member") + .Single(m => (string)m.Attribute("Name") == "Ground" && (string)m.Parent.Attribute("Name") == "MessageType") + .SetAttributeValue("Name", "Ground1"); + + GetMappedType(oSpaceCsdl, EnumCsdl(), "MessageModel.MessageType", isPOCO); + } + + private static void Can_map_OSpace_enum_type_that_has_more_members_than_CSPace_enum_type_if_members_match(bool isPOCO) + { + var oSpaceCsdl = EnumCsdl(); + + var enumType = oSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") + .Single(e => (string)e.Attribute("Name") == "MessageType"); + + enumType.Add(new XElement("{http://schemas.microsoft.com/ado/2009/11/edm}Member", + new XAttribute("Name", "LegacyType"), + new XAttribute("Value", 0))); + + Assert.Equal( + "MessageModel.Message:MessageModel.Message", + GetMappedType(oSpaceCsdl, EnumCsdl(), "MessageModel.Message", isPOCO).Identity); + } + + private static void Can_map_CSpace_enum_type_with_no_enum_members(bool isPOCO) + { + var cSpaceCsdl = EnumCsdl(); + + cSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}EnumType") + .Single(e => (string)e.Attribute("Name") == "MessageType") + .Elements() + .Remove(); + + Assert.Equal( + "MessageModel.Message:MessageModel.Message", + GetMappedType(EnumCsdl(), cSpaceCsdl, "MessageModel.Message", isPOCO).Identity); + } + + private static void Cannot_map_if_OSpace_enum_type_member_value_does_not_match_CSpace_enum_type_member_value(bool isPOCO) + { + var oSpaceCsdl = EnumCsdl(); + + oSpaceCsdl + .Descendants("{http://schemas.microsoft.com/ado/2009/11/edm}Member") + .Single(m => (string)m.Attribute("Name") == "Ground" && (string)m.Parent.Attribute("Name") == "MessageType") + .SetAttributeValue("Value", "64"); + + GetMappedType(oSpaceCsdl, EnumCsdl(), "MessageModel.MessageType", isPOCO); + } + + private static void OSpace_enum_type_and_CSpace_entity_type_have_the_same_name(bool isPOCO) + { + var oSpaceCsdl = XDocument.Parse( +@" + +"); + + var cSpaceCsdl = XDocument.Parse( +@" + + + + + + +"); + + GetMappedType(oSpaceCsdl, cSpaceCsdl, "Model.MessageType", isPOCO); + } + + private static void OSpace_entity_type_and_CSpace_enum_type_have_the_same_name(bool isPOCO) + { + var oSpaceCsdl = XDocument.Parse( +@" + + + + + + +"); + + var cSpaceCsdl = XDocument.Parse( +@" + +"); + + GetMappedType(oSpaceCsdl, cSpaceCsdl, "Model.MessageType", isPOCO); + } + + private static Map GetMappedType(XDocument oSpaceCsdl, XDocument cSpaceCsdl, string oSpaceTypeName, bool isPOCO) + { + var workspace = PrepareModel(oSpaceCsdl, cSpaceCsdl, isPOCO); + return workspace.GetMap(oSpaceTypeName, DataSpace.OSpace, DataSpace.OCSpace); + } + + private static Assembly BuildAssembly(bool isPOCO, params XDocument[] oSpaceCsdl) + { + return + new CsdlToClrAssemblyConverter(isPOCO, oSpaceCsdl) + .BuildAssembly(Guid.NewGuid().ToString()); + } + + private static MetadataWorkspace PrepareModel(XDocument oSpaceCsdl, XDocument cSpaceCsdl, bool isPOCO) + { + return CreateMetadataWorkspace( + cSpaceCsdl, + BuildAssembly(isPOCO, oSpaceCsdl), + isPOCO); + } + + private static MetadataWorkspace CreateMetadataWorkspace(XDocument cSpaceCsdl, Assembly assembly, bool isPOCO) + { + var workspace = new MetadataWorkspace(); + + EdmItemCollection edmItemCollection; + + using (var csdlReader = cSpaceCsdl.CreateReader()) + { + edmItemCollection = new EdmItemCollection(new XmlReader[] { csdlReader }); + } + workspace.RegisterItemCollection(edmItemCollection); + + + // assembly can actually be an AssemblyBuilder. The following line ensures that we are + // using the actual assembly otherwise an Assert in ObjectItemAttributeAssemblyLoader.LoadType + // will fire. + assembly = assembly.GetTypes().First().Assembly; + var objectItemCollection = new ObjectItemCollection(); + + if (isPOCO) + { + objectItemCollection.LoadFromAssembly(assembly, edmItemCollection); + } + else + { + objectItemCollection.LoadFromAssembly(assembly); + } + + workspace.RegisterItemCollection(objectItemCollection); + + return workspace; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/Migrations/BasicMigrationScenarios.cs b/test/EntityFramework/FunctionalTests.Transitional/Migrations/BasicMigrationScenarios.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/Migrations/BasicMigrationScenarios.cs rename to test/EntityFramework/FunctionalTests.Transitional/Migrations/BasicMigrationScenarios.cs index f3ff8a2e..c22278f8 100644 --- a/test/EntityFramework/FunctionalTests/Migrations/BasicMigrationScenarios.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Migrations/BasicMigrationScenarios.cs @@ -1,693 +1,693 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - using System.Data.Entity.Migrations.Design; - using System.Data.Entity.Migrations.History; - using System.Data.Entity.Migrations.Infrastructure; - using System.Data.Entity.Utilities; - using System.IO; - using System.Linq; - using System.Text.RegularExpressions; - using Xunit; - - [Variant(DatabaseProvider.SqlClient, ProgrammingLanguage.CSharp)] - [Variant(DatabaseProvider.SqlServerCe, ProgrammingLanguage.CSharp)] - [Variant(DatabaseProvider.SqlClient, ProgrammingLanguage.VB)] - public class BasicMigrationScenarios : DbTestCase - { - [MigrationsTheory] - public void GetHistory_should_return_migrations_list() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - Assert.True(!migrator.GetDatabaseMigrations().Any()); - - migrator.Update(); - - Assert.Equal(1, migrator.GetDatabaseMigrations().Count()); - } - - [MigrationsTheory] - public void ScaffoldInitialCreate_should_return_null_when_db_not_initialized() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - migrator.Update(); - - var scaffoldedMigration = migrator.ScaffoldInitialCreate("Foo"); - - Assert.Null(scaffoldedMigration); - } - - [MigrationsTheory] - public void ScaffoldInitialCreate_should_return_scaffolded_migration_when_db_initialized() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - var initialCreate = new MigrationScaffolder(migrator.Configuration).Scaffold("InitialCreate"); - - migrator = CreateMigrator(scaffoldedMigrations: initialCreate, contextKey: typeof(ShopContext_v1).FullName); - - migrator.Update(); - - migrator = CreateMigrator(contextKey: "NewOne"); - - var scaffoldedMigration = migrator.ScaffoldInitialCreate("Foo"); - - Assert.NotNull(scaffoldedMigration); - Assert.NotSame(initialCreate, scaffoldedMigration); - Assert.Equal(initialCreate.MigrationId, scaffoldedMigration.MigrationId); - } - - [MigrationsTheory] - public void ScaffoldInitialCreate_should_return_scaffolded_migration_when_db_initialized_and_schema_specified() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - var initialCreate = new MigrationScaffolder(migrator.Configuration).Scaffold("InitialCreate"); - - migrator = CreateMigrator(scaffoldedMigrations: initialCreate, contextKey: typeof(ShopContext_v5).FullName); - - migrator.Update(); - - migrator = CreateMigrator(contextKey: "NewOne"); - - var scaffoldedMigration = migrator.ScaffoldInitialCreate("Foo"); - - Assert.NotNull(scaffoldedMigration); - Assert.NotSame(initialCreate, scaffoldedMigration); - Assert.Equal(initialCreate.MigrationId, scaffoldedMigration.MigrationId); - } - - [MigrationsTheory] - public void Generate_should_create_custom_migration_step() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); - - Assert.NotNull(generatedMigration); - Assert.True(generatedMigration.MigrationId.Contains("Migration")); - } - - [MigrationsTheory] - public void Generate_should_emit_null_source_when_last_migration_was_explicit() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration1"); - - migrator = CreateMigrator(scaffoldedMigrations: generatedMigration); - - migrator.Update(); - - migrator = CreateMigrator(); - - generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration2"); - - Assert.True( - generatedMigration.DesignerCode.Contains("return null") - || generatedMigration.DesignerCode.Contains("Return Nothing")); - } - - [MigrationsTheory] - public void Generate_should_emit_source_when_last_migration_was_automatic() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - migrator.Update(); - - migrator = CreateMigrator(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration2"); - - Assert.True( - generatedMigration.DesignerCode - .Contains("Resources.GetString(\"Source\")")); - } - - [MigrationsTheory] - public void Update_should_execute_pending_custom_scripts() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); - - migrator = CreateMigrator( - automaticMigrationsEnabled: false, - scaffoldedMigrations: generatedMigration); - - migrator.Update(); - - Assert.True(TableExists("MigrationsCustomers")); - } - - [MigrationsTheory] - public void Generate_when_model_up_to_date_should_create_stub_migration() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - migrator.Update(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); - - Assert.True(generatedMigration.UserCode.Length > 300); - } - - [MigrationsTheory] - public void Update_blocks_automatic_migration_when_explicit_source_model() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - migrator.Update(); - - migrator = CreateMigrator(automaticDataLossEnabled: true); - - migrator.Update(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration1"); - - ResetDatabase(); - - migrator = CreateMigrator(); - - migrator.Update(); - - // Fix-up migrationId to come after previous automatic migration - var oldMigrationId = generatedMigration.MigrationId; - var newMigrationId = MigrationAssembly.CreateMigrationId(oldMigrationId.MigrationName()); - generatedMigration.MigrationId = newMigrationId; - generatedMigration.DesignerCode = generatedMigration.DesignerCode.Replace(oldMigrationId, newMigrationId); - - migrator - = CreateMigrator( - automaticMigrationsEnabled: false, - automaticDataLossEnabled: false, - scaffoldedMigrations: generatedMigration); - - Assert.Throws(() => migrator.Update()) - .ValidateMessage("AutomaticDataLoss"); - } - - [MigrationsTheory] - public void Update_down_when_target_migration_id_valid_should_migrate_to_target_version_without_timestamp_part() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - var generatedMigration1 = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration1"); - - migrator = CreateMigrator( - automaticMigrationsEnabled: false, - scaffoldedMigrations: generatedMigration1); - - migrator.Update(); - - migrator = CreateMigrator(); - - var generatedMigration2 = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration2"); - - migrator = CreateMigrator( - automaticMigrationsEnabled: false, - scaffoldedMigrations: new[] { generatedMigration1, generatedMigration2 }); - - migrator.Update(); - - Assert.True(TableExists("crm.tbl_customers")); - - migrator.Update("Migration1"); - - Assert.True(TableExists("MigrationsCustomers")); - } - - [MigrationsTheory] - public void Can_specify_target_up_migration_without_timestamp_part() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); - - migrator = CreateMigrator( - automaticMigrationsEnabled: false, - scaffoldedMigrations: generatedMigration); - - migrator.Update("Migration"); - - Assert.True(TableExists("MigrationsCustomers")); - } - - [MigrationsTheory] - public void Update_when_target_migration_id_invalid_should_throw() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); - - migrator = CreateMigrator( - automaticMigrationsEnabled: false, - scaffoldedMigrations: generatedMigration); - - migrator.Update(); - - Assert.Throws(() => migrator.Update("balony")) - .ValidateMessage("MigrationNotFound", "balony"); - } - - [MigrationsTheory] - public void Update_when_target_migration_id_valid_should_migrate_to_target_version() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - var generatedMigration1 = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration1"); - - migrator = CreateMigrator(); - - var generatedMigration2 = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration2"); - - migrator = CreateMigrator( - automaticMigrationsEnabled: false, - scaffoldedMigrations: new[] { generatedMigration1, generatedMigration2 }); - - migrator.Update(generatedMigration1.MigrationId); - - Assert.True(TableExists("MigrationsCustomers")); - } - - [MigrationsTheory] - public void Update_down_when_target_migration_id_valid_should_migrate_to_target_version() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - var generatedMigration1 = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration1"); - - migrator = CreateMigrator( - automaticMigrationsEnabled: false, - scaffoldedMigrations: generatedMigration1); - - migrator.Update(); - - migrator = CreateMigrator(); - - var generatedMigration2 = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration2"); - - migrator = CreateMigrator( - automaticMigrationsEnabled: false, - scaffoldedMigrations: generatedMigration2); - - migrator.Update(); - - var generatedMigration3 = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration3"); - - migrator = CreateMigrator( - automaticMigrationsEnabled: false, - scaffoldedMigrations: new[] { generatedMigration1, generatedMigration2, generatedMigration3 }); - - migrator.Update(); - - Assert.True(TableExists("crm.tbl_customers")); - - migrator.Update(generatedMigration1.MigrationId); - - Assert.True(TableExists("MigrationsCustomers")); - } - - [MigrationsTheory] - public void Update_down_when_automatic_should_migrate_to_target_version() - { - ResetDatabase(); - - var migrator = CreateMigrator(automaticDataLossEnabled: true); - - migrator.Update(); - - Assert.True(TableExists("MigrationsCustomers")); - - migrator.Update(DbMigrator.InitialDatabase); - - Assert.False(TableExists("MigrationsCustomers")); - - Assert.Null( - new HistoryRepository( - ConnectionString, ProviderFactory, - "System.Data.Entity.Migrations.DbMigrationsConfiguration").GetLastModel()); - - migrator.Update(); - - Assert.True(TableExists("MigrationsCustomers")); - Assert.NotNull( - new HistoryRepository( - ConnectionString, ProviderFactory, - "System.Data.Entity.Migrations.DbMigrationsConfiguration").GetLastModel()); - } - - [MigrationsTheory] - public void Update_down_when_automatic_and_multiple_steps_should_migrate_to_target_version() - { - ResetDatabase(); - - var historyRepository = new HistoryRepository(ConnectionString, ProviderFactory, "MyKey"); - - var migrator = CreateMigrator(automaticDataLossEnabled: true); - - migrator.Update(); - - Assert.True(TableExists("MigrationsCustomers")); - - migrator = CreateMigrator(automaticDataLossEnabled: true); - - migrator.Update(); - - Assert.True(TableExists("crm.tbl_customers")); - - migrator.Update(DbMigrator.InitialDatabase); - - Assert.False(TableExists("MigrationsCustomers")); - Assert.False(TableExists("tbl_customers")); - Assert.Null(historyRepository.GetLastModel()); - } - - [MigrationsTheory] - public void Update_down_when_explicit_should_migrate_to_target_version() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration1"); - - migrator = CreateMigrator( - automaticMigrationsEnabled: false, - scaffoldedMigrations: generatedMigration); - - migrator.Update(); - - Assert.True(TableExists("MigrationsCustomers")); - - migrator.Update(DbMigrator.InitialDatabase); - - Assert.False(TableExists("MigrationsCustomers")); - - var historyRepository = new HistoryRepository(ConnectionString, ProviderFactory, "MyKey"); - - Assert.Null(historyRepository.GetLastModel()); - } - - [MigrationsTheory] - public void Update_down_when_initial_version_and_no_database_should_be_noop() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration1"); - - migrator = CreateMigrator( - automaticMigrationsEnabled: false, - scaffoldedMigrations: generatedMigration); - - migrator.Update(); - - Assert.True(TableExists("MigrationsCustomers")); - - DropDatabase(); - - migrator.Update(DbMigrator.InitialDatabase); - - Assert.False(migrator.GetDatabaseMigrations().Any()); - } - - [MigrationsTheory] - public void Update_down_when_explicit_and_automatic_should_migrate_to_target_version() - { - ResetDatabase(); - - var historyRepository = new HistoryRepository(ConnectionString, ProviderFactory, "MyKey"); - - var migrator = CreateMigrator(); - - migrator.Update(); - - Assert.True(TableExists("MigrationsCustomers")); - - migrator = CreateMigrator(automaticDataLossEnabled: true); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); - - migrator = CreateMigrator( - automaticDataLossEnabled: true, - scaffoldedMigrations: generatedMigration); - - migrator.Update(); - - Assert.True(TableExists("crm.tbl_customers")); - - migrator.Update(DbMigrator.InitialDatabase); - - Assert.False(TableExists("MigrationsCustomers")); - Assert.False(TableExists("tbl_customers")); - Assert.Null(historyRepository.GetLastModel()); - } - - [MigrationsTheory] - public void Generate_when_empty_source_database_should_diff_against_empty_model() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); - - Assert.Equal(4, Regex.Matches(generatedMigration.UserCode, "CreateTable").Count); - } - - [MigrationsTheory] - public void Can_generate_and_update_against_empty_source_model() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration_v1"); - - migrator = CreateMigrator(false, scaffoldedMigrations: generatedMigration); - - migrator.Update(); - - Assert.True(TableExists("MigrationsProducts")); - } - - [MigrationsTheory] - public void Can_generate_against_existing_model() - { - Can_generate_and_update_against_empty_source_model(); - - var migrator = CreateMigrator(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration_v2"); - - Assert.Equal(2, Regex.Matches(generatedMigration.UserCode, "RenameTable").Count); - } - - [MigrationsTheory] - public void Can_generate_migration_with_store_side_renames() - { - ResetDatabase(); - - CreateMigrator().Update(); - - var migrator = CreateMigrator(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); - - Assert.True(generatedMigration.UserCode.Contains("RenameTable")); - WhenNotSqlCe(() => Assert.True(generatedMigration.UserCode.Contains("RenameColumn"))); - } - - [MigrationsTheory] - public void Can_update_generate_update_when_empty_target_database() - { - ResetDatabase(); - - CreateMigrator().Update(); - - Assert.True(TableExists("MigrationsProducts")); - - var migrator = CreateMigrator(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); - - migrator = CreateMigrator(false, scaffoldedMigrations: generatedMigration); - - migrator.Update(); - - Assert.True(TableExists("crm.tbl_customers")); - } - - [MigrationsTheory] - public void Can_auto_update_v1_when_target_database_does_not_exist() - { - var migrator = CreateMigrator(targetDatabase: Path.GetRandomFileName()); - - try - { - migrator.Update(); - - Assert.True(TableExists("MigrationsProducts")); - } - finally - { - DropDatabase(); - } - } - - [MigrationsTheory] - public void Update_throws_on_automatic_data_loss() - { - ResetDatabase(); - - CreateMigrator().Update(); - - var migrator = CreateMigrator(); - - Assert.Equal( - new AutomaticDataLossException("Automatic migration was not applied because it would result in data loss.").Message, - Assert.Throws(() => migrator.Update()).Message); - } - - [MigrationsTheory] - public void Update_can_process_automatic_data_loss() - { - ResetDatabase(); - - CreateMigrator().Update(); - - var migrator = CreateMigrator(automaticDataLossEnabled: true); - - migrator.Update(); - - Assert.False(TableExists("MigrationsBlogs")); - } - - [MigrationsTheory] - public void Can_update_multiple_migrations_having_a_trailing_automatic_migration() - { - ResetDatabase(); - - CreateMigrator().Update(); - - var migrator = CreateMigrator(); - - var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Version 2"); - - ResetDatabase(); - - CreateMigrator(scaffoldedMigrations: generatedMigration).Update(); - - Assert.True(TableExists("MigrationsStores")); - } - - [MigrationsTheory] - public void Can_downgrade_with_leading_automatic_when_database_empty() - { - ResetDatabase(); - - CreateMigrator().Update(); - - var migrator = CreateMigrator(); - - var scaffoldedMigration - = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); - - migrator - = CreateMigrator( - scaffoldedMigrations: scaffoldedMigration, - automaticDataLossEnabled: true); - - ResetDatabase(); - - migrator.Update(); - - Assert.True(TableExists("OrderLines")); - - migrator.Update("0"); - - Assert.False(TableExists("OrderLines")); - } - - [MigrationsTheory] - public void Update_when_new_earlier_migration_should_throw_auto_disabled_exception() - { - ResetDatabase(); - - var migratorA = CreateMigrator(); - var m1 = new MigrationScaffolder(migratorA.Configuration).Scaffold("M1"); - - var migratorB = CreateMigrator(); - var m2 = new MigrationScaffolder(migratorB.Configuration).Scaffold("M2"); - - CreateMigrator(scaffoldedMigrations: m2).Update(); - - Assert.Throws( - () => CreateMigrator( - scaffoldedMigrations: new[] { m1, m2 }, - automaticMigrationsEnabled: false) - .Update()); - } - } - - public class MultiUserContextA : DbContext - { - public DbSet As { get; set; } - } - - public class MultiUserContextB : DbContext - { - public DbSet Bs { get; set; } - } - - public class MultiUserContextAB : DbContext - { - public DbSet As { get; set; } - public DbSet Bs { get; set; } - } - - public class MultiUserA - { - public int Id { get; set; } - } - - public class MultiUserB - { - public int Id { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Migrations +{ + using System.Data.Entity.Migrations.Design; + using System.Data.Entity.Migrations.History; + using System.Data.Entity.Migrations.Infrastructure; + using System.Data.Entity.Utilities; + using System.IO; + using System.Linq; + using System.Text.RegularExpressions; + using Xunit; + + [Variant(DatabaseProvider.SqlClient, ProgrammingLanguage.CSharp)] + [Variant(DatabaseProvider.SqlServerCe, ProgrammingLanguage.CSharp)] + [Variant(DatabaseProvider.SqlClient, ProgrammingLanguage.VB)] + public class BasicMigrationScenarios : DbTestCase + { + [MigrationsTheory] + public void GetHistory_should_return_migrations_list() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + Assert.True(!migrator.GetDatabaseMigrations().Any()); + + migrator.Update(); + + Assert.Equal(1, migrator.GetDatabaseMigrations().Count()); + } + + [MigrationsTheory] + public void ScaffoldInitialCreate_should_return_null_when_db_not_initialized() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + migrator.Update(); + + var scaffoldedMigration = migrator.ScaffoldInitialCreate("Foo"); + + Assert.Null(scaffoldedMigration); + } + + [MigrationsTheory] + public void ScaffoldInitialCreate_should_return_scaffolded_migration_when_db_initialized() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + var initialCreate = new MigrationScaffolder(migrator.Configuration).Scaffold("InitialCreate"); + + migrator = CreateMigrator(scaffoldedMigrations: initialCreate, contextKey: typeof(ShopContext_v1).FullName); + + migrator.Update(); + + migrator = CreateMigrator(contextKey: "NewOne"); + + var scaffoldedMigration = migrator.ScaffoldInitialCreate("Foo"); + + Assert.NotNull(scaffoldedMigration); + Assert.NotSame(initialCreate, scaffoldedMigration); + Assert.Equal(initialCreate.MigrationId, scaffoldedMigration.MigrationId); + } + + [MigrationsTheory] + public void ScaffoldInitialCreate_should_return_scaffolded_migration_when_db_initialized_and_schema_specified() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + var initialCreate = new MigrationScaffolder(migrator.Configuration).Scaffold("InitialCreate"); + + migrator = CreateMigrator(scaffoldedMigrations: initialCreate, contextKey: typeof(ShopContext_v5).FullName); + + migrator.Update(); + + migrator = CreateMigrator(contextKey: "NewOne"); + + var scaffoldedMigration = migrator.ScaffoldInitialCreate("Foo"); + + Assert.NotNull(scaffoldedMigration); + Assert.NotSame(initialCreate, scaffoldedMigration); + Assert.Equal(initialCreate.MigrationId, scaffoldedMigration.MigrationId); + } + + [MigrationsTheory] + public void Generate_should_create_custom_migration_step() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); + + Assert.NotNull(generatedMigration); + Assert.True(generatedMigration.MigrationId.Contains("Migration")); + } + + [MigrationsTheory] + public void Generate_should_emit_null_source_when_last_migration_was_explicit() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration1"); + + migrator = CreateMigrator(scaffoldedMigrations: generatedMigration); + + migrator.Update(); + + migrator = CreateMigrator(); + + generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration2"); + + Assert.True( + generatedMigration.DesignerCode.Contains("return null") + || generatedMigration.DesignerCode.Contains("Return Nothing")); + } + + [MigrationsTheory] + public void Generate_should_emit_source_when_last_migration_was_automatic() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + migrator.Update(); + + migrator = CreateMigrator(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration2"); + + Assert.True( + generatedMigration.DesignerCode + .Contains("Resources.GetString(\"Source\")")); + } + + [MigrationsTheory] + public void Update_should_execute_pending_custom_scripts() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); + + migrator = CreateMigrator( + automaticMigrationsEnabled: false, + scaffoldedMigrations: generatedMigration); + + migrator.Update(); + + Assert.True(TableExists("MigrationsCustomers")); + } + + [MigrationsTheory] + public void Generate_when_model_up_to_date_should_create_stub_migration() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + migrator.Update(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); + + Assert.True(generatedMigration.UserCode.Length > 300); + } + + [MigrationsTheory] + public void Update_blocks_automatic_migration_when_explicit_source_model() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + migrator.Update(); + + migrator = CreateMigrator(automaticDataLossEnabled: true); + + migrator.Update(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration1"); + + ResetDatabase(); + + migrator = CreateMigrator(); + + migrator.Update(); + + // Fix-up migrationId to come after previous automatic migration + var oldMigrationId = generatedMigration.MigrationId; + var newMigrationId = MigrationAssembly.CreateMigrationId(oldMigrationId.MigrationName()); + generatedMigration.MigrationId = newMigrationId; + generatedMigration.DesignerCode = generatedMigration.DesignerCode.Replace(oldMigrationId, newMigrationId); + + migrator + = CreateMigrator( + automaticMigrationsEnabled: false, + automaticDataLossEnabled: false, + scaffoldedMigrations: generatedMigration); + + Assert.Throws(() => migrator.Update()) + .ValidateMessage("AutomaticDataLoss"); + } + + [MigrationsTheory] + public void Update_down_when_target_migration_id_valid_should_migrate_to_target_version_without_timestamp_part() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + var generatedMigration1 = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration1"); + + migrator = CreateMigrator( + automaticMigrationsEnabled: false, + scaffoldedMigrations: generatedMigration1); + + migrator.Update(); + + migrator = CreateMigrator(); + + var generatedMigration2 = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration2"); + + migrator = CreateMigrator( + automaticMigrationsEnabled: false, + scaffoldedMigrations: new[] { generatedMigration1, generatedMigration2 }); + + migrator.Update(); + + Assert.True(TableExists("crm.tbl_customers")); + + migrator.Update("Migration1"); + + Assert.True(TableExists("MigrationsCustomers")); + } + + [MigrationsTheory] + public void Can_specify_target_up_migration_without_timestamp_part() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); + + migrator = CreateMigrator( + automaticMigrationsEnabled: false, + scaffoldedMigrations: generatedMigration); + + migrator.Update("Migration"); + + Assert.True(TableExists("MigrationsCustomers")); + } + + [MigrationsTheory] + public void Update_when_target_migration_id_invalid_should_throw() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); + + migrator = CreateMigrator( + automaticMigrationsEnabled: false, + scaffoldedMigrations: generatedMigration); + + migrator.Update(); + + Assert.Throws(() => migrator.Update("balony")) + .ValidateMessage("MigrationNotFound", "balony"); + } + + [MigrationsTheory] + public void Update_when_target_migration_id_valid_should_migrate_to_target_version() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + var generatedMigration1 = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration1"); + + migrator = CreateMigrator(); + + var generatedMigration2 = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration2"); + + migrator = CreateMigrator( + automaticMigrationsEnabled: false, + scaffoldedMigrations: new[] { generatedMigration1, generatedMigration2 }); + + migrator.Update(generatedMigration1.MigrationId); + + Assert.True(TableExists("MigrationsCustomers")); + } + + [MigrationsTheory] + public void Update_down_when_target_migration_id_valid_should_migrate_to_target_version() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + var generatedMigration1 = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration1"); + + migrator = CreateMigrator( + automaticMigrationsEnabled: false, + scaffoldedMigrations: generatedMigration1); + + migrator.Update(); + + migrator = CreateMigrator(); + + var generatedMigration2 = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration2"); + + migrator = CreateMigrator( + automaticMigrationsEnabled: false, + scaffoldedMigrations: generatedMigration2); + + migrator.Update(); + + var generatedMigration3 = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration3"); + + migrator = CreateMigrator( + automaticMigrationsEnabled: false, + scaffoldedMigrations: new[] { generatedMigration1, generatedMigration2, generatedMigration3 }); + + migrator.Update(); + + Assert.True(TableExists("crm.tbl_customers")); + + migrator.Update(generatedMigration1.MigrationId); + + Assert.True(TableExists("MigrationsCustomers")); + } + + [MigrationsTheory] + public void Update_down_when_automatic_should_migrate_to_target_version() + { + ResetDatabase(); + + var migrator = CreateMigrator(automaticDataLossEnabled: true); + + migrator.Update(); + + Assert.True(TableExists("MigrationsCustomers")); + + migrator.Update(DbMigrator.InitialDatabase); + + Assert.False(TableExists("MigrationsCustomers")); + + Assert.Null( + new HistoryRepository( + ConnectionString, ProviderFactory, + "System.Data.Entity.Migrations.DbMigrationsConfiguration").GetLastModel()); + + migrator.Update(); + + Assert.True(TableExists("MigrationsCustomers")); + Assert.NotNull( + new HistoryRepository( + ConnectionString, ProviderFactory, + "System.Data.Entity.Migrations.DbMigrationsConfiguration").GetLastModel()); + } + + [MigrationsTheory] + public void Update_down_when_automatic_and_multiple_steps_should_migrate_to_target_version() + { + ResetDatabase(); + + var historyRepository = new HistoryRepository(ConnectionString, ProviderFactory, "MyKey"); + + var migrator = CreateMigrator(automaticDataLossEnabled: true); + + migrator.Update(); + + Assert.True(TableExists("MigrationsCustomers")); + + migrator = CreateMigrator(automaticDataLossEnabled: true); + + migrator.Update(); + + Assert.True(TableExists("crm.tbl_customers")); + + migrator.Update(DbMigrator.InitialDatabase); + + Assert.False(TableExists("MigrationsCustomers")); + Assert.False(TableExists("tbl_customers")); + Assert.Null(historyRepository.GetLastModel()); + } + + [MigrationsTheory] + public void Update_down_when_explicit_should_migrate_to_target_version() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration1"); + + migrator = CreateMigrator( + automaticMigrationsEnabled: false, + scaffoldedMigrations: generatedMigration); + + migrator.Update(); + + Assert.True(TableExists("MigrationsCustomers")); + + migrator.Update(DbMigrator.InitialDatabase); + + Assert.False(TableExists("MigrationsCustomers")); + + var historyRepository = new HistoryRepository(ConnectionString, ProviderFactory, "MyKey"); + + Assert.Null(historyRepository.GetLastModel()); + } + + [MigrationsTheory] + public void Update_down_when_initial_version_and_no_database_should_be_noop() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration1"); + + migrator = CreateMigrator( + automaticMigrationsEnabled: false, + scaffoldedMigrations: generatedMigration); + + migrator.Update(); + + Assert.True(TableExists("MigrationsCustomers")); + + DropDatabase(); + + migrator.Update(DbMigrator.InitialDatabase); + + Assert.False(migrator.GetDatabaseMigrations().Any()); + } + + [MigrationsTheory] + public void Update_down_when_explicit_and_automatic_should_migrate_to_target_version() + { + ResetDatabase(); + + var historyRepository = new HistoryRepository(ConnectionString, ProviderFactory, "MyKey"); + + var migrator = CreateMigrator(); + + migrator.Update(); + + Assert.True(TableExists("MigrationsCustomers")); + + migrator = CreateMigrator(automaticDataLossEnabled: true); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); + + migrator = CreateMigrator( + automaticDataLossEnabled: true, + scaffoldedMigrations: generatedMigration); + + migrator.Update(); + + Assert.True(TableExists("crm.tbl_customers")); + + migrator.Update(DbMigrator.InitialDatabase); + + Assert.False(TableExists("MigrationsCustomers")); + Assert.False(TableExists("tbl_customers")); + Assert.Null(historyRepository.GetLastModel()); + } + + [MigrationsTheory] + public void Generate_when_empty_source_database_should_diff_against_empty_model() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); + + Assert.Equal(4, Regex.Matches(generatedMigration.UserCode, "CreateTable").Count); + } + + [MigrationsTheory] + public void Can_generate_and_update_against_empty_source_model() + { + ResetDatabase(); + + var migrator = CreateMigrator(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration_v1"); + + migrator = CreateMigrator(false, scaffoldedMigrations: generatedMigration); + + migrator.Update(); + + Assert.True(TableExists("MigrationsProducts")); + } + + [MigrationsTheory] + public void Can_generate_against_existing_model() + { + Can_generate_and_update_against_empty_source_model(); + + var migrator = CreateMigrator(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration_v2"); + + Assert.Equal(2, Regex.Matches(generatedMigration.UserCode, "RenameTable").Count); + } + + [MigrationsTheory] + public void Can_generate_migration_with_store_side_renames() + { + ResetDatabase(); + + CreateMigrator().Update(); + + var migrator = CreateMigrator(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); + + Assert.True(generatedMigration.UserCode.Contains("RenameTable")); + WhenNotSqlCe(() => Assert.True(generatedMigration.UserCode.Contains("RenameColumn"))); + } + + [MigrationsTheory] + public void Can_update_generate_update_when_empty_target_database() + { + ResetDatabase(); + + CreateMigrator().Update(); + + Assert.True(TableExists("MigrationsProducts")); + + var migrator = CreateMigrator(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); + + migrator = CreateMigrator(false, scaffoldedMigrations: generatedMigration); + + migrator.Update(); + + Assert.True(TableExists("crm.tbl_customers")); + } + + [MigrationsTheory] + public void Can_auto_update_v1_when_target_database_does_not_exist() + { + var migrator = CreateMigrator(targetDatabase: Path.GetRandomFileName()); + + try + { + migrator.Update(); + + Assert.True(TableExists("MigrationsProducts")); + } + finally + { + DropDatabase(); + } + } + + [MigrationsTheory] + public void Update_throws_on_automatic_data_loss() + { + ResetDatabase(); + + CreateMigrator().Update(); + + var migrator = CreateMigrator(); + + Assert.Equal( + new AutomaticDataLossException("Automatic migration was not applied because it would result in data loss.").Message, + Assert.Throws(() => migrator.Update()).Message); + } + + [MigrationsTheory] + public void Update_can_process_automatic_data_loss() + { + ResetDatabase(); + + CreateMigrator().Update(); + + var migrator = CreateMigrator(automaticDataLossEnabled: true); + + migrator.Update(); + + Assert.False(TableExists("MigrationsBlogs")); + } + + [MigrationsTheory] + public void Can_update_multiple_migrations_having_a_trailing_automatic_migration() + { + ResetDatabase(); + + CreateMigrator().Update(); + + var migrator = CreateMigrator(); + + var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Version 2"); + + ResetDatabase(); + + CreateMigrator(scaffoldedMigrations: generatedMigration).Update(); + + Assert.True(TableExists("MigrationsStores")); + } + + [MigrationsTheory] + public void Can_downgrade_with_leading_automatic_when_database_empty() + { + ResetDatabase(); + + CreateMigrator().Update(); + + var migrator = CreateMigrator(); + + var scaffoldedMigration + = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration"); + + migrator + = CreateMigrator( + scaffoldedMigrations: scaffoldedMigration, + automaticDataLossEnabled: true); + + ResetDatabase(); + + migrator.Update(); + + Assert.True(TableExists("OrderLines")); + + migrator.Update("0"); + + Assert.False(TableExists("OrderLines")); + } + + [MigrationsTheory] + public void Update_when_new_earlier_migration_should_throw_auto_disabled_exception() + { + ResetDatabase(); + + var migratorA = CreateMigrator(); + var m1 = new MigrationScaffolder(migratorA.Configuration).Scaffold("M1"); + + var migratorB = CreateMigrator(); + var m2 = new MigrationScaffolder(migratorB.Configuration).Scaffold("M2"); + + CreateMigrator(scaffoldedMigrations: m2).Update(); + + Assert.Throws( + () => CreateMigrator( + scaffoldedMigrations: new[] { m1, m2 }, + automaticMigrationsEnabled: false) + .Update()); + } + } + + public class MultiUserContextA : DbContext + { + public DbSet As { get; set; } + } + + public class MultiUserContextB : DbContext + { + public DbSet Bs { get; set; } + } + + public class MultiUserContextAB : DbContext + { + public DbSet As { get; set; } + public DbSet Bs { get; set; } + } + + public class MultiUserA + { + public int Id { get; set; } + } + + public class MultiUserB + { + public int Id { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/Migrations/CustomHistoryScenarios.cs b/test/EntityFramework/FunctionalTests.Transitional/Migrations/CustomHistoryScenarios.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/Migrations/CustomHistoryScenarios.cs rename to test/EntityFramework/FunctionalTests.Transitional/Migrations/CustomHistoryScenarios.cs diff --git a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/DatabaseProviderFixture.cs b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/DatabaseProviderFixture.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/Migrations/TestHelpers/DatabaseProviderFixture.cs rename to test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/DatabaseProviderFixture.cs index 6d4b21a1..c1edaf22 100644 --- a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/DatabaseProviderFixture.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/DatabaseProviderFixture.cs @@ -1,69 +1,69 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - using System.Collections.Generic; - using System.Data.Entity.Migrations.Design; - - public class DatabaseProviderFixture - { - public const string DefaultDatabaseName = "MigrationsTest"; - - private readonly Dictionary _testDatabases = new Dictionary(); - - private readonly Dictionary _codeGenerators = - new Dictionary(); - - private readonly Dictionary _migrationCompilers = - new Dictionary(); - - public DatabaseProviderFixture() - { - foreach (DatabaseProvider provider in Enum.GetValues(typeof(DatabaseProvider))) - { - _testDatabases[provider] = InitializeTestDatabase(provider, DefaultDatabaseName); - } - _testDatabases[DatabaseProvider.SqlClient] = InitializeTestDatabase(DatabaseProvider.SqlClient, DefaultDatabaseName); - - _codeGenerators[ProgrammingLanguage.CSharp] = new CSharpMigrationCodeGenerator(); - _migrationCompilers[ProgrammingLanguage.CSharp] = new MigrationCompiler("cs"); - ; - _codeGenerators[ProgrammingLanguage.VB] = new VisualBasicMigrationCodeGenerator(); - _migrationCompilers[ProgrammingLanguage.VB] = new MigrationCompiler("vb"); - } - - public Dictionary TestDatabases - { - get { return _testDatabases; } - } - - public Dictionary CodeGenerators - { - get { return _codeGenerators; } - } - - public Dictionary MigrationCompilers - { - get { return _migrationCompilers; } - } - - public static TestDatabase InitializeTestDatabase(DatabaseProvider provider, string databaseName) - { - TestDatabase testDatabase; - switch (provider) - { - case DatabaseProvider.SqlClient: - testDatabase = new SqlTestDatabase(databaseName); - break; - case DatabaseProvider.SqlServerCe: - testDatabase = new SqlCeTestDatabase(databaseName); - break; - default: - throw new InvalidOperationException("Unsupported provider"); - } - - testDatabase.EnsureDatabase(); - return testDatabase; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Migrations +{ + using System.Collections.Generic; + using System.Data.Entity.Migrations.Design; + + public class DatabaseProviderFixture + { + public const string DefaultDatabaseName = "MigrationsTest"; + + private readonly Dictionary _testDatabases = new Dictionary(); + + private readonly Dictionary _codeGenerators = + new Dictionary(); + + private readonly Dictionary _migrationCompilers = + new Dictionary(); + + public DatabaseProviderFixture() + { + foreach (DatabaseProvider provider in Enum.GetValues(typeof(DatabaseProvider))) + { + _testDatabases[provider] = InitializeTestDatabase(provider, DefaultDatabaseName); + } + _testDatabases[DatabaseProvider.SqlClient] = InitializeTestDatabase(DatabaseProvider.SqlClient, DefaultDatabaseName); + + _codeGenerators[ProgrammingLanguage.CSharp] = new CSharpMigrationCodeGenerator(); + _migrationCompilers[ProgrammingLanguage.CSharp] = new MigrationCompiler("cs"); + ; + _codeGenerators[ProgrammingLanguage.VB] = new VisualBasicMigrationCodeGenerator(); + _migrationCompilers[ProgrammingLanguage.VB] = new MigrationCompiler("vb"); + } + + public Dictionary TestDatabases + { + get { return _testDatabases; } + } + + public Dictionary CodeGenerators + { + get { return _codeGenerators; } + } + + public Dictionary MigrationCompilers + { + get { return _migrationCompilers; } + } + + public static TestDatabase InitializeTestDatabase(DatabaseProvider provider, string databaseName) + { + TestDatabase testDatabase; + switch (provider) + { + case DatabaseProvider.SqlClient: + testDatabase = new SqlTestDatabase(databaseName); + break; + case DatabaseProvider.SqlServerCe: + testDatabase = new SqlCeTestDatabase(databaseName); + break; + default: + throw new InvalidOperationException("Unsupported provider"); + } + + testDatabase.EnsureDatabase(); + return testDatabase; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/DbMigratorExtensions.cs b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/DbMigratorExtensions.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/Migrations/TestHelpers/DbMigratorExtensions.cs rename to test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/DbMigratorExtensions.cs index 9b04a218..017e48c4 100644 --- a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/DbMigratorExtensions.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/DbMigratorExtensions.cs @@ -1,27 +1,27 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - using System.Collections.Generic; - using System.Data.Entity.Migrations.Model; - using System.Linq; - using System.Reflection; - - public static class DbMigratorExtensions - { - private static readonly PropertyInfo _operationsProperty - = typeof(DbMigration).GetProperty("Operations", BindingFlags.Instance | BindingFlags.NonPublic); - - public static IList GetOperations(this DbMigration migration) - { - var migrationOperations = (IList)_operationsProperty.GetValue(migration, null); - - if (!migrationOperations.Any()) - { - migration.Up(); - } - - return migrationOperations; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Migrations +{ + using System.Collections.Generic; + using System.Data.Entity.Migrations.Model; + using System.Linq; + using System.Reflection; + + public static class DbMigratorExtensions + { + private static readonly PropertyInfo _operationsProperty + = typeof(DbMigration).GetProperty("Operations", BindingFlags.Instance | BindingFlags.NonPublic); + + public static IList GetOperations(this DbMigration migration) + { + var migrationOperations = (IList)_operationsProperty.GetValue(migration, null); + + if (!migrationOperations.Any()) + { + migration.Up(); + } + + return migrationOperations; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/DbTestCase.cs b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/DbTestCase.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/Migrations/TestHelpers/DbTestCase.cs rename to test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/DbTestCase.cs index bcd2653a..2cf10934 100644 --- a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/DbTestCase.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/DbTestCase.cs @@ -1,332 +1,332 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - using System.Data.Common; - using System.Data.Entity.Infrastructure; - using System.Data.Entity.Migrations.Design; - using System.Data.Entity.Migrations.Edm; - using System.Data.Entity.Migrations.History; - using System.Data.Entity.Migrations.Infrastructure; - using System.Data.Entity.Migrations.Model; - using System.Data.Entity.Migrations.Sql; - using System.Data.Entity.Migrations.Utilities; - using System.Data.Entity.Utilities; - using System.Linq; - using Xunit; - - public enum DatabaseProvider - { - SqlClient, - SqlServerCe - } - - public enum ProgrammingLanguage - { - CSharp, - VB - } - - public abstract class DbTestCase : TestBase, IUseFixture - { - private DatabaseProviderFixture _databaseProviderFixture; - - private DatabaseProvider _databaseProvider = DatabaseProvider.SqlClient; - private ProgrammingLanguage _programmingLanguage = ProgrammingLanguage.CSharp; - - public DatabaseProvider DatabaseProvider - { - get { return _databaseProvider; } - set - { - _databaseProvider = value; - TestDatabase = _databaseProviderFixture.TestDatabases[_databaseProvider]; - } - } - - public ProgrammingLanguage ProgrammingLanguage - { - get { return _programmingLanguage; } - set - { - _programmingLanguage = value; - CodeGenerator = _databaseProviderFixture.CodeGenerators[_programmingLanguage]; - MigrationCompiler = _databaseProviderFixture.MigrationCompilers[_programmingLanguage]; - } - } - - public TestDatabase TestDatabase { get; private set; } - - public MigrationCodeGenerator CodeGenerator { get; private set; } - - public MigrationCompiler MigrationCompiler { get; private set; } - - public virtual void Init(DatabaseProvider provider, ProgrammingLanguage language) - { - try - { - _databaseProvider = provider; - _programmingLanguage = language; - - TestDatabase = _databaseProviderFixture.TestDatabases[_databaseProvider]; - CodeGenerator = _databaseProviderFixture.CodeGenerators[_programmingLanguage]; - MigrationCompiler = _databaseProviderFixture.MigrationCompilers[_programmingLanguage]; - } - catch (Exception e) - { - Console.WriteLine(e); - - throw; - } - } - - public void WhenSqlCe(Action action) - { - if (_databaseProvider == DatabaseProvider.SqlServerCe) - { - action(); - } - } - - public void WhenNotSqlCe(Action action) - { - if (_databaseProvider != DatabaseProvider.SqlServerCe) - { - action(); - } - } - - public DbMigrator CreateMigrator() - where TContext : DbContext - where TMigration : DbMigration, new() - { - var migrationsConfiguration = CreateMigrationsConfiguration(); - - migrationsConfiguration.MigrationsAssembly = typeof(TMigration).Assembly; - - return new DbMigrator(migrationsConfiguration, null); - } - - public DbMigrator CreateMigrator(DbMigration migration) - where TContext : DbContext - { - var modelCompressor = new ModelCompressor(); - - var generatedMigration - = CodeGenerator - .Generate( - UtcNowGenerator.UtcNowAsMigrationIdTimestamp() + "_" + migration.GetType().Name, - migration.GetOperations(), - Convert.ToBase64String(modelCompressor.Compress(CreateContext().GetModel())), - Convert.ToBase64String(modelCompressor.Compress(CreateContext().GetModel())), - "System.Data.Entity.Migrations", - migration.GetType().Name); - - return new DbMigrator(CreateMigrationsConfiguration(scaffoldedMigrations: generatedMigration)); - } - - public DbMigrator CreateMigrator( - bool automaticMigrationsEnabled = true, - bool automaticDataLossEnabled = false, - string targetDatabase = null, - string contextKey = null, - IHistoryContextFactory historyContextFactory = null, - params ScaffoldedMigration[] scaffoldedMigrations) - where TContext : DbContext - { - return new DbMigrator( - CreateMigrationsConfiguration( - automaticMigrationsEnabled, - automaticDataLossEnabled, - targetDatabase, - contextKey, - historyContextFactory, - scaffoldedMigrations)); - } - - public DbMigrationsConfiguration CreateMigrationsConfiguration( - bool automaticMigrationsEnabled = true, - bool automaticDataLossEnabled = false, - string targetDatabase = null, - string contextKey = null, - IHistoryContextFactory historyContextFactory = null, - params ScaffoldedMigration[] scaffoldedMigrations) - where TContext : DbContext - { - var migrationsConfiguration - = new DbMigrationsConfiguration - { - AutomaticMigrationsEnabled = automaticMigrationsEnabled, - AutomaticMigrationDataLossAllowed = automaticDataLossEnabled, - ContextType = typeof(TContext), - MigrationsAssembly = SystemComponentModelDataAnnotationsAssembly, - MigrationsNamespace = typeof(TContext).Namespace, - HistoryContextFactory = historyContextFactory - }; - - if (!string.IsNullOrWhiteSpace(contextKey)) - { - migrationsConfiguration.ContextKey = contextKey; - } - - if (!string.IsNullOrWhiteSpace(targetDatabase)) - { - TestDatabase = DatabaseProviderFixture.InitializeTestDatabase(DatabaseProvider, targetDatabase); - } - - if ((scaffoldedMigrations != null) - && scaffoldedMigrations.Any()) - { - migrationsConfiguration.MigrationsAssembly = MigrationCompiler.Compile( - migrationsConfiguration.MigrationsNamespace, - scaffoldedMigrations); - } - - migrationsConfiguration.TargetDatabase = new DbConnectionInfo(TestDatabase.ConnectionString, TestDatabase.ProviderName); - - migrationsConfiguration.CodeGenerator = CodeGenerator; - - return migrationsConfiguration; - } - - public void ConfigureMigrationsConfiguration(DbMigrationsConfiguration migrationsConfiguration) - { - migrationsConfiguration.TargetDatabase = new DbConnectionInfo(TestDatabase.ConnectionString, TestDatabase.ProviderName); - migrationsConfiguration.CodeGenerator = CodeGenerator; - - migrationsConfiguration.MigrationsAssembly = SystemComponentModelDataAnnotationsAssembly; - } - - public TContext CreateContext() - where TContext : DbContext - { - var contextInfo = new DbContextInfo( - typeof(TContext), new DbConnectionInfo(TestDatabase.ConnectionString, TestDatabase.ProviderName)); - - return (TContext)contextInfo.CreateInstance(); - } - - public void ResetDatabase() - { - if (DatabaseExists()) - { - TestDatabase.ResetDatabase(); - } - else - { - TestDatabase.EnsureDatabase(); - } - } - - public void DropDatabase() - { - if (DatabaseExists()) - { - TestDatabase.DropDatabase(); - } - } - - public bool DatabaseExists() - { - return TestDatabase.Exists(); - } - - public bool TableExists(string name) - { - return Info.TableExists(name); - } - - public bool ColumnExists(string table, string name) - { - return Info.ColumnExists(table, name); - } - - public string ConnectionString - { - get { return TestDatabase.ConnectionString; } - } - - public DbProviderFactory ProviderFactory - { - get { return DbProviderFactories.GetFactory(TestDatabase.ProviderName); } - } - - public string ProviderManifestToken - { - get { return TestDatabase.ProviderManifestToken; } - } - - public DbProviderInfo ProviderInfo - { - get { return new DbProviderInfo(TestDatabase.ProviderName, ProviderManifestToken); } - } - - public MigrationSqlGenerator SqlGenerator - { - get { return TestDatabase.SqlGenerator; } - } - - public InfoContext Info - { - get { return TestDatabase.Info; } - } - - public void SetFixture(DatabaseProviderFixture databaseProviderFixture) - { - _databaseProviderFixture = databaseProviderFixture; - } - - public void ExecuteOperations(params MigrationOperation[] operations) - { - using (var connection = ProviderFactory.CreateConnection()) - { - connection.ConnectionString = ConnectionString; - - foreach (var migrationStatement in SqlGenerator.Generate(operations, ProviderManifestToken)) - { - using (var command = connection.CreateCommand()) - { - if (connection.State - != ConnectionState.Open) - { - connection.Open(); - } - - command.CommandText = migrationStatement.Sql; - command.ExecuteNonQuery(); - } - } - } - } - - public CreateTableOperation GetCreateHistoryTableOperation(string defaultSchema = null) - { - using (var connection = ProviderFactory.CreateConnection()) - { - connection.ConnectionString = ConnectionString; - - return (CreateTableOperation) - new EdmModelDiffer().Diff( - new DbModelBuilder().Build(ProviderInfo).GetModel(), - new HistoryContext(connection, contextOwnsConnection: true, defaultSchema: defaultSchema).GetModel(), - includeSystemOperations: true) - .Single(); - } - } - - public DropTableOperation GetDropHistoryTableOperation() - { - using (var connection = ProviderFactory.CreateConnection()) - { - connection.ConnectionString = ConnectionString; - - return (DropTableOperation) - new EdmModelDiffer().Diff( - new HistoryContext(connection, contextOwnsConnection: true, defaultSchema: null).GetModel(), - new DbModelBuilder().Build(ProviderInfo).GetModel(), - includeSystemOperations: true) - .Single(); - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Migrations +{ + using System.Data.Common; + using System.Data.Entity.Infrastructure; + using System.Data.Entity.Migrations.Design; + using System.Data.Entity.Migrations.Edm; + using System.Data.Entity.Migrations.History; + using System.Data.Entity.Migrations.Infrastructure; + using System.Data.Entity.Migrations.Model; + using System.Data.Entity.Migrations.Sql; + using System.Data.Entity.Migrations.Utilities; + using System.Data.Entity.Utilities; + using System.Linq; + using Xunit; + + public enum DatabaseProvider + { + SqlClient, + SqlServerCe + } + + public enum ProgrammingLanguage + { + CSharp, + VB + } + + public abstract class DbTestCase : TestBase, IUseFixture + { + private DatabaseProviderFixture _databaseProviderFixture; + + private DatabaseProvider _databaseProvider = DatabaseProvider.SqlClient; + private ProgrammingLanguage _programmingLanguage = ProgrammingLanguage.CSharp; + + public DatabaseProvider DatabaseProvider + { + get { return _databaseProvider; } + set + { + _databaseProvider = value; + TestDatabase = _databaseProviderFixture.TestDatabases[_databaseProvider]; + } + } + + public ProgrammingLanguage ProgrammingLanguage + { + get { return _programmingLanguage; } + set + { + _programmingLanguage = value; + CodeGenerator = _databaseProviderFixture.CodeGenerators[_programmingLanguage]; + MigrationCompiler = _databaseProviderFixture.MigrationCompilers[_programmingLanguage]; + } + } + + public TestDatabase TestDatabase { get; private set; } + + public MigrationCodeGenerator CodeGenerator { get; private set; } + + public MigrationCompiler MigrationCompiler { get; private set; } + + public virtual void Init(DatabaseProvider provider, ProgrammingLanguage language) + { + try + { + _databaseProvider = provider; + _programmingLanguage = language; + + TestDatabase = _databaseProviderFixture.TestDatabases[_databaseProvider]; + CodeGenerator = _databaseProviderFixture.CodeGenerators[_programmingLanguage]; + MigrationCompiler = _databaseProviderFixture.MigrationCompilers[_programmingLanguage]; + } + catch (Exception e) + { + Console.WriteLine(e); + + throw; + } + } + + public void WhenSqlCe(Action action) + { + if (_databaseProvider == DatabaseProvider.SqlServerCe) + { + action(); + } + } + + public void WhenNotSqlCe(Action action) + { + if (_databaseProvider != DatabaseProvider.SqlServerCe) + { + action(); + } + } + + public DbMigrator CreateMigrator() + where TContext : DbContext + where TMigration : DbMigration, new() + { + var migrationsConfiguration = CreateMigrationsConfiguration(); + + migrationsConfiguration.MigrationsAssembly = typeof(TMigration).Assembly; + + return new DbMigrator(migrationsConfiguration, null); + } + + public DbMigrator CreateMigrator(DbMigration migration) + where TContext : DbContext + { + var modelCompressor = new ModelCompressor(); + + var generatedMigration + = CodeGenerator + .Generate( + UtcNowGenerator.UtcNowAsMigrationIdTimestamp() + "_" + migration.GetType().Name, + migration.GetOperations(), + Convert.ToBase64String(modelCompressor.Compress(CreateContext().GetModel())), + Convert.ToBase64String(modelCompressor.Compress(CreateContext().GetModel())), + "System.Data.Entity.Migrations", + migration.GetType().Name); + + return new DbMigrator(CreateMigrationsConfiguration(scaffoldedMigrations: generatedMigration)); + } + + public DbMigrator CreateMigrator( + bool automaticMigrationsEnabled = true, + bool automaticDataLossEnabled = false, + string targetDatabase = null, + string contextKey = null, + IHistoryContextFactory historyContextFactory = null, + params ScaffoldedMigration[] scaffoldedMigrations) + where TContext : DbContext + { + return new DbMigrator( + CreateMigrationsConfiguration( + automaticMigrationsEnabled, + automaticDataLossEnabled, + targetDatabase, + contextKey, + historyContextFactory, + scaffoldedMigrations)); + } + + public DbMigrationsConfiguration CreateMigrationsConfiguration( + bool automaticMigrationsEnabled = true, + bool automaticDataLossEnabled = false, + string targetDatabase = null, + string contextKey = null, + IHistoryContextFactory historyContextFactory = null, + params ScaffoldedMigration[] scaffoldedMigrations) + where TContext : DbContext + { + var migrationsConfiguration + = new DbMigrationsConfiguration + { + AutomaticMigrationsEnabled = automaticMigrationsEnabled, + AutomaticMigrationDataLossAllowed = automaticDataLossEnabled, + ContextType = typeof(TContext), + MigrationsAssembly = SystemComponentModelDataAnnotationsAssembly, + MigrationsNamespace = typeof(TContext).Namespace, + HistoryContextFactory = historyContextFactory + }; + + if (!string.IsNullOrWhiteSpace(contextKey)) + { + migrationsConfiguration.ContextKey = contextKey; + } + + if (!string.IsNullOrWhiteSpace(targetDatabase)) + { + TestDatabase = DatabaseProviderFixture.InitializeTestDatabase(DatabaseProvider, targetDatabase); + } + + if ((scaffoldedMigrations != null) + && scaffoldedMigrations.Any()) + { + migrationsConfiguration.MigrationsAssembly = MigrationCompiler.Compile( + migrationsConfiguration.MigrationsNamespace, + scaffoldedMigrations); + } + + migrationsConfiguration.TargetDatabase = new DbConnectionInfo(TestDatabase.ConnectionString, TestDatabase.ProviderName); + + migrationsConfiguration.CodeGenerator = CodeGenerator; + + return migrationsConfiguration; + } + + public void ConfigureMigrationsConfiguration(DbMigrationsConfiguration migrationsConfiguration) + { + migrationsConfiguration.TargetDatabase = new DbConnectionInfo(TestDatabase.ConnectionString, TestDatabase.ProviderName); + migrationsConfiguration.CodeGenerator = CodeGenerator; + + migrationsConfiguration.MigrationsAssembly = SystemComponentModelDataAnnotationsAssembly; + } + + public TContext CreateContext() + where TContext : DbContext + { + var contextInfo = new DbContextInfo( + typeof(TContext), new DbConnectionInfo(TestDatabase.ConnectionString, TestDatabase.ProviderName)); + + return (TContext)contextInfo.CreateInstance(); + } + + public void ResetDatabase() + { + if (DatabaseExists()) + { + TestDatabase.ResetDatabase(); + } + else + { + TestDatabase.EnsureDatabase(); + } + } + + public void DropDatabase() + { + if (DatabaseExists()) + { + TestDatabase.DropDatabase(); + } + } + + public bool DatabaseExists() + { + return TestDatabase.Exists(); + } + + public bool TableExists(string name) + { + return Info.TableExists(name); + } + + public bool ColumnExists(string table, string name) + { + return Info.ColumnExists(table, name); + } + + public string ConnectionString + { + get { return TestDatabase.ConnectionString; } + } + + public DbProviderFactory ProviderFactory + { + get { return DbProviderFactories.GetFactory(TestDatabase.ProviderName); } + } + + public string ProviderManifestToken + { + get { return TestDatabase.ProviderManifestToken; } + } + + public DbProviderInfo ProviderInfo + { + get { return new DbProviderInfo(TestDatabase.ProviderName, ProviderManifestToken); } + } + + public MigrationSqlGenerator SqlGenerator + { + get { return TestDatabase.SqlGenerator; } + } + + public InfoContext Info + { + get { return TestDatabase.Info; } + } + + public void SetFixture(DatabaseProviderFixture databaseProviderFixture) + { + _databaseProviderFixture = databaseProviderFixture; + } + + public void ExecuteOperations(params MigrationOperation[] operations) + { + using (var connection = ProviderFactory.CreateConnection()) + { + connection.ConnectionString = ConnectionString; + + foreach (var migrationStatement in SqlGenerator.Generate(operations, ProviderManifestToken)) + { + using (var command = connection.CreateCommand()) + { + if (connection.State + != ConnectionState.Open) + { + connection.Open(); + } + + command.CommandText = migrationStatement.Sql; + command.ExecuteNonQuery(); + } + } + } + } + + public CreateTableOperation GetCreateHistoryTableOperation(string defaultSchema = null) + { + using (var connection = ProviderFactory.CreateConnection()) + { + connection.ConnectionString = ConnectionString; + + return (CreateTableOperation) + new EdmModelDiffer().Diff( + new DbModelBuilder().Build(ProviderInfo).GetModel(), + new HistoryContext(connection, contextOwnsConnection: true, defaultSchema: defaultSchema).GetModel(), + includeSystemOperations: true) + .Single(); + } + } + + public DropTableOperation GetDropHistoryTableOperation() + { + using (var connection = ProviderFactory.CreateConnection()) + { + connection.ConnectionString = ConnectionString; + + return (DropTableOperation) + new EdmModelDiffer().Diff( + new HistoryContext(connection, contextOwnsConnection: true, defaultSchema: null).GetModel(), + new DbModelBuilder().Build(ProviderInfo).GetModel(), + includeSystemOperations: true) + .Single(); + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/InfoContext.cs b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/InfoContext.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/Migrations/TestHelpers/InfoContext.cs rename to test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/InfoContext.cs index 1f1a79cc..554f8549 100644 --- a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/InfoContext.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/InfoContext.cs @@ -1,332 +1,332 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - using System.Collections.Generic; - using System.Data.Common; - using System.Data.Entity.Infrastructure; - using System.Data.SqlServerCe; - using System.Linq; - - public class InfoContext : DbContext - { - private readonly bool _supportsSchema; - - static InfoContext() - { - Database.SetInitializer(null); - } - - public InfoContext(DbConnection connection, bool supportsSchema = true) - : base(connection, true) - { - _supportsSchema = supportsSchema; - } - - public DbQuery Tables - { - get { return Set().AsNoTracking(); } - } - - public DbQuery Columns - { - get { return Set().AsNoTracking(); } - } - - public DbQuery TableConstraints - { - get { return Set().AsNoTracking(); } - } - - public DbQuery KeyColumnUsages - { - get { return Set().AsNoTracking(); } - } - - public bool ColumnExists(string tableName, string columnName) - { - var tuple = ParseTableName(tableName); - var candidates = Columns.Where(c => c.Table.Name == tuple.Item2 && c.Name == columnName).Include(c => c.Table).ToList(); - - if (!candidates.Any()) - { - return false; - } - - return candidates.Any(c => SchemaEquals(tuple.Item1, c.Table)); - } - - public bool TableExists(string name) - { - var tuple = ParseTableName(name); - var candidates = Tables.Where(t => t.Name == tuple.Item2).ToList(); - - if (!candidates.Any()) - { - return false; - } - - return candidates.Any(t => SchemaEquals(tuple.Item1, t)); - } - - public override int SaveChanges() - { - throw new InvalidOperationException("This context is read-only."); - } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - var table = modelBuilder.Entity(); - table.ToTable("TABLES", "INFORMATION_SCHEMA"); - table.Property(t => t.Schema).HasColumnName("TABLE_SCHEMA"); - table.Property(t => t.Name).HasColumnName("TABLE_NAME"); - table.HasKey( - t => new - { - t.Schema, - t.Name - }); - table.HasMany(t => t.Columns).WithRequired(c => c.Table).HasForeignKey( - c => new - { - c.TableSchema, - c.TableName - }); - table.HasMany(t => t.Constraints).WithRequired(tc => tc.Table).HasForeignKey( - c => new - { - c.TableSchema, - c.TableName - }); - - var column = modelBuilder.Entity(); - column.ToTable("COLUMNS", "INFORMATION_SCHEMA"); - column.Property(c => c.TableSchema).HasColumnName("TABLE_SCHEMA"); - column.Property(c => c.TableName).HasColumnName("TABLE_NAME"); - column.Property(c => c.Name).HasColumnName("COLUMN_NAME"); - column.Property(c => c.Position).HasColumnName("ORDINAL_POSITION"); - column.Property(c => c.Default).HasColumnName("COLUMN_DEFAULT"); - column.Property(c => c.IsNullable).HasColumnName("IS_NULLABLE"); - column.Property(c => c.Type).HasColumnName("DATA_TYPE"); - column.Property(c => c.MaxLength).HasColumnName("CHARACTER_MAXIMUM_LENGTH"); - column.Property(c => c.NumericPrecision).HasColumnName("NUMERIC_PRECISION"); - column.Property(c => c.Scale).HasColumnName("NUMERIC_SCALE"); - column.Property(c => c.DateTimePrecision).HasColumnName("DATETIME_PRECISION"); - column.HasKey( - c => new - { - c.TableSchema, - c.TableName, - c.Name - }); - - var tableConstraint = modelBuilder.Entity(); - tableConstraint.ToTable("TABLE_CONSTRAINTS", "INFORMATION_SCHEMA"); - tableConstraint.Property(tc => tc.Schema).HasColumnName("CONSTRAINT_SCHEMA"); - tableConstraint.Property(tc => tc.Name).HasColumnName("CONSTRAINT_NAME"); - tableConstraint.Property(tc => tc.TableSchema).HasColumnName("TABLE_SCHEMA"); - tableConstraint.Property(tc => tc.TableName).HasColumnName("TABLE_NAME"); - tableConstraint.HasKey( - tc => new - { - tc.Schema, - tc.Name - }); - - var uniqueConstraint = modelBuilder.Entity(); - uniqueConstraint.Map(m => m.Requires("CONSTRAINT_TYPE").HasValue("UNIQUE")); - - var primaryKeyConstraint = modelBuilder.Entity(); - primaryKeyConstraint.Map(m => m.Requires("CONSTRAINT_TYPE").HasValue("PRIMARY KEY")); - - var foreignKeyConstraint = modelBuilder.Entity(); - foreignKeyConstraint.Map(m => m.Requires("CONSTRAINT_TYPE").HasValue("FOREIGN KEY")); - - var referentialConstraint = modelBuilder.Entity(); - referentialConstraint.ToTable("REFERENTIAL_CONSTRAINTS", "INFORMATION_SCHEMA"); - referentialConstraint.Property(rc => rc.UniqueConstraintSchema).HasColumnName("UNIQUE_CONSTRAINT_SCHEMA"); - referentialConstraint.Property(rc => rc.UniqueConstraintName).HasColumnName("UNIQUE_CONSTRAINT_NAME"); - referentialConstraint.Property(rc => rc.DeleteRule).HasColumnName("DELETE_RULE"); - referentialConstraint.HasRequired(rc => rc.UniqueConstraint).WithMany(uc => uc.ReferentialConstraints).HasForeignKey( - rc => new - { - rc.UniqueConstraintSchema, - rc.UniqueConstraintName - }); - - var keyColumnUsage = modelBuilder.Entity(); - keyColumnUsage.ToTable("KEY_COLUMN_USAGE", "INFORMATION_SCHEMA"); - keyColumnUsage.Property(kcu => kcu.ConstraintSchema).HasColumnName("CONSTRAINT_SCHEMA"); - keyColumnUsage.Property(kcu => kcu.ConstraintName).HasColumnName("CONSTRAINT_NAME"); - keyColumnUsage.Property(kcu => kcu.ColumnTableSchema).HasColumnName("TABLE_SCHEMA"); - keyColumnUsage.Property(kcu => kcu.ColumnTableName).HasColumnName("TABLE_NAME"); - keyColumnUsage.Property(kcu => kcu.ColumnName).HasColumnName("COLUMN_NAME"); - keyColumnUsage.Property(kcu => kcu.Position).HasColumnName("ORDINAL_POSITION"); - keyColumnUsage.HasKey( - kcu => new - { - kcu.ConstraintSchema, - kcu.ConstraintName, - kcu.ColumnTableSchema, - kcu.ColumnTableName, - kcu.ColumnName - }); - keyColumnUsage.HasRequired(kcu => kcu.Constraint).WithMany(kc => kc.KeyColumnUsages).HasForeignKey( - kcu => new - { - kcu.ConstraintSchema, - kcu.ConstraintName - }); - keyColumnUsage.HasRequired(kcu => kcu.Column).WithMany(c => c.KeyColumnUsages).HasForeignKey( - kcu => new - { - kcu.ColumnTableSchema, - kcu.ColumnTableName, - kcu.ColumnName - }); - - if (Database.Connection is SqlCeConnection) - { - column.Property(c => c.NumericPrecision).HasColumnType("smallint"); - column.Property(c => c.DateTimePrecision).HasColumnType("int"); - } - else - { - column.Property(c => c.Scale).HasColumnType("int"); - } - } - - private static Tuple ParseTableName(string name) - { - var lastDot = name.LastIndexOf('.'); - - if (lastDot == -1) - { - return new Tuple(null, name); - } - - return new Tuple( - name.Substring(0, lastDot), - name.Substring(lastDot + 1)); - } - - private bool SchemaEquals(string schema, TableInfo table) - { - if (!_supportsSchema - || string.IsNullOrWhiteSpace(schema)) - { - return true; - } - - return table.Schema == schema; - } - } - - #region Entity types - - public class TableInfo - { - public TableInfo() - { - Columns = new HashSet(); - Constraints = new HashSet(); - } - - public string Schema { get; set; } - public string Name { get; set; } - - public virtual ICollection Columns { get; protected set; } - public virtual ICollection Constraints { get; protected set; } - } - - public class ColumnInfo - { - public ColumnInfo() - { - KeyColumnUsages = new HashSet(); - } - - public string TableSchema { get; set; } - public string TableName { get; set; } - public virtual TableInfo Table { get; set; } - - public string Name { get; set; } - public int Position { get; set; } - public string Default { get; set; } - public string IsNullable { get; set; } - public string Type { get; set; } - public int? MaxLength { get; set; } - public byte? NumericPrecision { get; set; } - public short? Scale { get; set; } - public short? DateTimePrecision { get; set; } - - public virtual ICollection KeyColumnUsages { get; protected set; } - } - - public class TableConstraintInfo - { - public string Schema { get; set; } - public string Name { get; set; } - - public string TableSchema { get; set; } - public string TableName { get; set; } - public virtual TableInfo Table { get; set; } - } - - public abstract class KeyConstraintInfo : TableConstraintInfo - { - public KeyConstraintInfo() - { - KeyColumnUsages = new HashSet(); - } - - public virtual ICollection KeyColumnUsages { get; protected set; } - } - - public abstract class UniqueConstraintInfoBase : KeyConstraintInfo - { - protected UniqueConstraintInfoBase() - { - ReferentialConstraints = new HashSet(); - } - - public virtual ICollection ReferentialConstraints { get; protected set; } - } - - public class UniqueConstraintInfo : UniqueConstraintInfoBase - { - } - - public class PrimaryKeyConstraintInfo : UniqueConstraintInfoBase - { - } - - public abstract class ForeignKeyConstraintInfo : KeyConstraintInfo - { - } - - public class ReferentialConstraintInfo : ForeignKeyConstraintInfo - { - public string UniqueConstraintSchema { get; set; } - public string UniqueConstraintName { get; set; } - public virtual UniqueConstraintInfoBase UniqueConstraint { get; set; } - - public string DeleteRule { get; set; } - } - - public class KeyColumnUsageInfo - { - public string ConstraintSchema { get; set; } - public string ConstraintName { get; set; } - public KeyConstraintInfo Constraint { get; set; } - - public string ColumnTableSchema { get; set; } - public string ColumnTableName { get; set; } - public string ColumnName { get; set; } - public ColumnInfo Column { get; set; } - - public int Position { get; set; } - } - - #endregion -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Migrations +{ + using System.Collections.Generic; + using System.Data.Common; + using System.Data.Entity.Infrastructure; + using System.Data.SqlServerCe; + using System.Linq; + + public class InfoContext : DbContext + { + private readonly bool _supportsSchema; + + static InfoContext() + { + Database.SetInitializer(null); + } + + public InfoContext(DbConnection connection, bool supportsSchema = true) + : base(connection, true) + { + _supportsSchema = supportsSchema; + } + + public DbQuery Tables + { + get { return Set().AsNoTracking(); } + } + + public DbQuery Columns + { + get { return Set().AsNoTracking(); } + } + + public DbQuery TableConstraints + { + get { return Set().AsNoTracking(); } + } + + public DbQuery KeyColumnUsages + { + get { return Set().AsNoTracking(); } + } + + public bool ColumnExists(string tableName, string columnName) + { + var tuple = ParseTableName(tableName); + var candidates = Columns.Where(c => c.Table.Name == tuple.Item2 && c.Name == columnName).Include(c => c.Table).ToList(); + + if (!candidates.Any()) + { + return false; + } + + return candidates.Any(c => SchemaEquals(tuple.Item1, c.Table)); + } + + public bool TableExists(string name) + { + var tuple = ParseTableName(name); + var candidates = Tables.Where(t => t.Name == tuple.Item2).ToList(); + + if (!candidates.Any()) + { + return false; + } + + return candidates.Any(t => SchemaEquals(tuple.Item1, t)); + } + + public override int SaveChanges() + { + throw new InvalidOperationException("This context is read-only."); + } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + var table = modelBuilder.Entity(); + table.ToTable("TABLES", "INFORMATION_SCHEMA"); + table.Property(t => t.Schema).HasColumnName("TABLE_SCHEMA"); + table.Property(t => t.Name).HasColumnName("TABLE_NAME"); + table.HasKey( + t => new + { + t.Schema, + t.Name + }); + table.HasMany(t => t.Columns).WithRequired(c => c.Table).HasForeignKey( + c => new + { + c.TableSchema, + c.TableName + }); + table.HasMany(t => t.Constraints).WithRequired(tc => tc.Table).HasForeignKey( + c => new + { + c.TableSchema, + c.TableName + }); + + var column = modelBuilder.Entity(); + column.ToTable("COLUMNS", "INFORMATION_SCHEMA"); + column.Property(c => c.TableSchema).HasColumnName("TABLE_SCHEMA"); + column.Property(c => c.TableName).HasColumnName("TABLE_NAME"); + column.Property(c => c.Name).HasColumnName("COLUMN_NAME"); + column.Property(c => c.Position).HasColumnName("ORDINAL_POSITION"); + column.Property(c => c.Default).HasColumnName("COLUMN_DEFAULT"); + column.Property(c => c.IsNullable).HasColumnName("IS_NULLABLE"); + column.Property(c => c.Type).HasColumnName("DATA_TYPE"); + column.Property(c => c.MaxLength).HasColumnName("CHARACTER_MAXIMUM_LENGTH"); + column.Property(c => c.NumericPrecision).HasColumnName("NUMERIC_PRECISION"); + column.Property(c => c.Scale).HasColumnName("NUMERIC_SCALE"); + column.Property(c => c.DateTimePrecision).HasColumnName("DATETIME_PRECISION"); + column.HasKey( + c => new + { + c.TableSchema, + c.TableName, + c.Name + }); + + var tableConstraint = modelBuilder.Entity(); + tableConstraint.ToTable("TABLE_CONSTRAINTS", "INFORMATION_SCHEMA"); + tableConstraint.Property(tc => tc.Schema).HasColumnName("CONSTRAINT_SCHEMA"); + tableConstraint.Property(tc => tc.Name).HasColumnName("CONSTRAINT_NAME"); + tableConstraint.Property(tc => tc.TableSchema).HasColumnName("TABLE_SCHEMA"); + tableConstraint.Property(tc => tc.TableName).HasColumnName("TABLE_NAME"); + tableConstraint.HasKey( + tc => new + { + tc.Schema, + tc.Name + }); + + var uniqueConstraint = modelBuilder.Entity(); + uniqueConstraint.Map(m => m.Requires("CONSTRAINT_TYPE").HasValue("UNIQUE")); + + var primaryKeyConstraint = modelBuilder.Entity(); + primaryKeyConstraint.Map(m => m.Requires("CONSTRAINT_TYPE").HasValue("PRIMARY KEY")); + + var foreignKeyConstraint = modelBuilder.Entity(); + foreignKeyConstraint.Map(m => m.Requires("CONSTRAINT_TYPE").HasValue("FOREIGN KEY")); + + var referentialConstraint = modelBuilder.Entity(); + referentialConstraint.ToTable("REFERENTIAL_CONSTRAINTS", "INFORMATION_SCHEMA"); + referentialConstraint.Property(rc => rc.UniqueConstraintSchema).HasColumnName("UNIQUE_CONSTRAINT_SCHEMA"); + referentialConstraint.Property(rc => rc.UniqueConstraintName).HasColumnName("UNIQUE_CONSTRAINT_NAME"); + referentialConstraint.Property(rc => rc.DeleteRule).HasColumnName("DELETE_RULE"); + referentialConstraint.HasRequired(rc => rc.UniqueConstraint).WithMany(uc => uc.ReferentialConstraints).HasForeignKey( + rc => new + { + rc.UniqueConstraintSchema, + rc.UniqueConstraintName + }); + + var keyColumnUsage = modelBuilder.Entity(); + keyColumnUsage.ToTable("KEY_COLUMN_USAGE", "INFORMATION_SCHEMA"); + keyColumnUsage.Property(kcu => kcu.ConstraintSchema).HasColumnName("CONSTRAINT_SCHEMA"); + keyColumnUsage.Property(kcu => kcu.ConstraintName).HasColumnName("CONSTRAINT_NAME"); + keyColumnUsage.Property(kcu => kcu.ColumnTableSchema).HasColumnName("TABLE_SCHEMA"); + keyColumnUsage.Property(kcu => kcu.ColumnTableName).HasColumnName("TABLE_NAME"); + keyColumnUsage.Property(kcu => kcu.ColumnName).HasColumnName("COLUMN_NAME"); + keyColumnUsage.Property(kcu => kcu.Position).HasColumnName("ORDINAL_POSITION"); + keyColumnUsage.HasKey( + kcu => new + { + kcu.ConstraintSchema, + kcu.ConstraintName, + kcu.ColumnTableSchema, + kcu.ColumnTableName, + kcu.ColumnName + }); + keyColumnUsage.HasRequired(kcu => kcu.Constraint).WithMany(kc => kc.KeyColumnUsages).HasForeignKey( + kcu => new + { + kcu.ConstraintSchema, + kcu.ConstraintName + }); + keyColumnUsage.HasRequired(kcu => kcu.Column).WithMany(c => c.KeyColumnUsages).HasForeignKey( + kcu => new + { + kcu.ColumnTableSchema, + kcu.ColumnTableName, + kcu.ColumnName + }); + + if (Database.Connection is SqlCeConnection) + { + column.Property(c => c.NumericPrecision).HasColumnType("smallint"); + column.Property(c => c.DateTimePrecision).HasColumnType("int"); + } + else + { + column.Property(c => c.Scale).HasColumnType("int"); + } + } + + private static Tuple ParseTableName(string name) + { + var lastDot = name.LastIndexOf('.'); + + if (lastDot == -1) + { + return new Tuple(null, name); + } + + return new Tuple( + name.Substring(0, lastDot), + name.Substring(lastDot + 1)); + } + + private bool SchemaEquals(string schema, TableInfo table) + { + if (!_supportsSchema + || string.IsNullOrWhiteSpace(schema)) + { + return true; + } + + return table.Schema == schema; + } + } + + #region Entity types + + public class TableInfo + { + public TableInfo() + { + Columns = new HashSet(); + Constraints = new HashSet(); + } + + public string Schema { get; set; } + public string Name { get; set; } + + public virtual ICollection Columns { get; protected set; } + public virtual ICollection Constraints { get; protected set; } + } + + public class ColumnInfo + { + public ColumnInfo() + { + KeyColumnUsages = new HashSet(); + } + + public string TableSchema { get; set; } + public string TableName { get; set; } + public virtual TableInfo Table { get; set; } + + public string Name { get; set; } + public int Position { get; set; } + public string Default { get; set; } + public string IsNullable { get; set; } + public string Type { get; set; } + public int? MaxLength { get; set; } + public byte? NumericPrecision { get; set; } + public short? Scale { get; set; } + public short? DateTimePrecision { get; set; } + + public virtual ICollection KeyColumnUsages { get; protected set; } + } + + public class TableConstraintInfo + { + public string Schema { get; set; } + public string Name { get; set; } + + public string TableSchema { get; set; } + public string TableName { get; set; } + public virtual TableInfo Table { get; set; } + } + + public abstract class KeyConstraintInfo : TableConstraintInfo + { + public KeyConstraintInfo() + { + KeyColumnUsages = new HashSet(); + } + + public virtual ICollection KeyColumnUsages { get; protected set; } + } + + public abstract class UniqueConstraintInfoBase : KeyConstraintInfo + { + protected UniqueConstraintInfoBase() + { + ReferentialConstraints = new HashSet(); + } + + public virtual ICollection ReferentialConstraints { get; protected set; } + } + + public class UniqueConstraintInfo : UniqueConstraintInfoBase + { + } + + public class PrimaryKeyConstraintInfo : UniqueConstraintInfoBase + { + } + + public abstract class ForeignKeyConstraintInfo : KeyConstraintInfo + { + } + + public class ReferentialConstraintInfo : ForeignKeyConstraintInfo + { + public string UniqueConstraintSchema { get; set; } + public string UniqueConstraintName { get; set; } + public virtual UniqueConstraintInfoBase UniqueConstraint { get; set; } + + public string DeleteRule { get; set; } + } + + public class KeyColumnUsageInfo + { + public string ConstraintSchema { get; set; } + public string ConstraintName { get; set; } + public KeyConstraintInfo Constraint { get; set; } + + public string ColumnTableSchema { get; set; } + public string ColumnTableName { get; set; } + public string ColumnName { get; set; } + public ColumnInfo Column { get; set; } + + public int Position { get; set; } + } + + #endregion +} diff --git a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/MigrationCompiler.cs b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/MigrationCompiler.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/Migrations/TestHelpers/MigrationCompiler.cs rename to test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/MigrationCompiler.cs index 15248a63..aaee5ade 100644 --- a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/MigrationCompiler.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/MigrationCompiler.cs @@ -1,102 +1,102 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - using System.CodeDom.Compiler; - using System.Collections.Generic; - using System.ComponentModel; - using System.Data.Common; - using System.Data.Entity.Migrations.Design; - using System.Data.Entity.Spatial; - using System.Data.Entity.Utilities; - using System.IO; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; - using System.Resources; - using System.Text; - - public class MigrationCompiler - { - private readonly CodeDomProvider _codeProvider; - - public MigrationCompiler(string language) - { - _codeProvider = CodeDomProvider.CreateProvider(language); - } - - public Assembly Compile(string @namespace, params ScaffoldedMigration[] scaffoldedMigrations) - { - var options = new CompilerParameters - { - GenerateExecutable = false, - GenerateInMemory = true - }; - - options.ReferencedAssemblies.Add(typeof(string).Assembly.Location); - options.ReferencedAssemblies.Add(typeof(Expression).Assembly.Location); - options.ReferencedAssemblies.Add(typeof(DbMigrator).Assembly.Location); - options.ReferencedAssemblies.Add(typeof(DbContext).Assembly.Location); - options.ReferencedAssemblies.Add(typeof(DbConnection).Assembly.Location); - options.ReferencedAssemblies.Add(typeof(Component).Assembly.Location); - options.ReferencedAssemblies.Add(typeof(MigrationCompiler).Assembly.Location); - options.ReferencedAssemblies.Add(typeof(DbGeography).Assembly.Location); - - var embededResources = GenerateEmbeddedResources(scaffoldedMigrations, @namespace); - embededResources.Each(r => options.EmbeddedResources.Add(r)); - - var sources = scaffoldedMigrations.SelectMany(g => new[] { g.UserCode, g.DesignerCode }); - - var compilerResults = _codeProvider.CompileAssemblyFromSource(options, sources.ToArray()); - embededResources.Each(r => File.Delete(r)); - - if (compilerResults.Errors.Count > 0) - { - throw new InvalidOperationException(BuildCompileErrorMessage(compilerResults.Errors)); - } - - return compilerResults.CompiledAssembly; - } - - private static string BuildCompileErrorMessage(CompilerErrorCollection errors) - { - var stringBuilder = new StringBuilder(); - - foreach (CompilerError error in errors) - { - stringBuilder.AppendLine(error.ToString()); - } - - return stringBuilder.ToString(); - } - - private static IEnumerable GenerateEmbeddedResources( - IEnumerable scaffoldedMigrations, string @namespace) - { - foreach (var scaffoldedMigration in scaffoldedMigrations) - { - var className = GetClassName(scaffoldedMigration.MigrationId); - var embededResource = Path.Combine( - Path.GetTempPath(), - @namespace + "." + className + ".resources"); - - using (var writer = new ResourceWriter(embededResource)) - { - scaffoldedMigration - .Resources - .Each(e => writer.AddResource(e.Key, e.Value)); - } - - yield return embededResource; - } - } - - private static string GetClassName(string migrationId) - { - return migrationId - .Split(new[] { '_' }, 2) - .Last() - .Replace(" ", string.Empty); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Migrations +{ + using System.CodeDom.Compiler; + using System.Collections.Generic; + using System.ComponentModel; + using System.Data.Common; + using System.Data.Entity.Migrations.Design; + using System.Data.Entity.Spatial; + using System.Data.Entity.Utilities; + using System.IO; + using System.Linq; + using System.Linq.Expressions; + using System.Reflection; + using System.Resources; + using System.Text; + + public class MigrationCompiler + { + private readonly CodeDomProvider _codeProvider; + + public MigrationCompiler(string language) + { + _codeProvider = CodeDomProvider.CreateProvider(language); + } + + public Assembly Compile(string @namespace, params ScaffoldedMigration[] scaffoldedMigrations) + { + var options = new CompilerParameters + { + GenerateExecutable = false, + GenerateInMemory = true + }; + + options.ReferencedAssemblies.Add(typeof(string).Assembly.Location); + options.ReferencedAssemblies.Add(typeof(Expression).Assembly.Location); + options.ReferencedAssemblies.Add(typeof(DbMigrator).Assembly.Location); + options.ReferencedAssemblies.Add(typeof(DbContext).Assembly.Location); + options.ReferencedAssemblies.Add(typeof(DbConnection).Assembly.Location); + options.ReferencedAssemblies.Add(typeof(Component).Assembly.Location); + options.ReferencedAssemblies.Add(typeof(MigrationCompiler).Assembly.Location); + options.ReferencedAssemblies.Add(typeof(DbGeography).Assembly.Location); + + var embededResources = GenerateEmbeddedResources(scaffoldedMigrations, @namespace); + embededResources.Each(r => options.EmbeddedResources.Add(r)); + + var sources = scaffoldedMigrations.SelectMany(g => new[] { g.UserCode, g.DesignerCode }); + + var compilerResults = _codeProvider.CompileAssemblyFromSource(options, sources.ToArray()); + embededResources.Each(r => File.Delete(r)); + + if (compilerResults.Errors.Count > 0) + { + throw new InvalidOperationException(BuildCompileErrorMessage(compilerResults.Errors)); + } + + return compilerResults.CompiledAssembly; + } + + private static string BuildCompileErrorMessage(CompilerErrorCollection errors) + { + var stringBuilder = new StringBuilder(); + + foreach (CompilerError error in errors) + { + stringBuilder.AppendLine(error.ToString()); + } + + return stringBuilder.ToString(); + } + + private static IEnumerable GenerateEmbeddedResources( + IEnumerable scaffoldedMigrations, string @namespace) + { + foreach (var scaffoldedMigration in scaffoldedMigrations) + { + var className = GetClassName(scaffoldedMigration.MigrationId); + var embededResource = Path.Combine( + Path.GetTempPath(), + @namespace + "." + className + ".resources"); + + using (var writer = new ResourceWriter(embededResource)) + { + scaffoldedMigration + .Resources + .Each(e => writer.AddResource(e.Key, e.Value)); + } + + yield return embededResource; + } + } + + private static string GetClassName(string migrationId) + { + return migrationId + .Split(new[] { '_' }, 2) + .Last() + .Replace(" ", string.Empty); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/MigrationsTheoryAttribute.cs b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/MigrationsTheoryAttribute.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/Migrations/TestHelpers/MigrationsTheoryAttribute.cs rename to test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/MigrationsTheoryAttribute.cs index 41d52c60..528e9747 100644 --- a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/MigrationsTheoryAttribute.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/MigrationsTheoryAttribute.cs @@ -1,57 +1,57 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - using System.Collections.Generic; - using System.Linq; - using System.Reflection; - using Xunit.Extensions; - using Xunit.Sdk; - - public class MigrationsTheoryAttribute : TheoryAttribute - { - protected override IEnumerable EnumerateTestCommands(IMethodInfo method) - { - var _providerLanguageCombinations = GetCombinations(method.MethodInfo); - - var testCommands - = method.MethodInfo.GetParameters().Length == 0 - ? new[] { new FactCommand(method) } - : base.EnumerateTestCommands(method); - - return (from providerLanguageCombination in _providerLanguageCombinations - from testCommand in testCommands - select new MigrationsTheoryCommand( - testCommand, - providerLanguageCombination.DatabaseProvider, - providerLanguageCombination.ProgrammingLanguage)); - } - - private static IEnumerable GetCombinations(MethodInfo method) - { - var methodVariants - = method - .GetCustomAttributes(typeof(VariantAttribute), true) - .Cast() - .ToList(); - - if (methodVariants.Any()) - { - return methodVariants; - } - - var typeVariants - = method.DeclaringType - .GetCustomAttributes(typeof(VariantAttribute), true) - .Cast() - .ToList(); - - if (typeVariants.Any()) - { - return typeVariants; - } - - return new[] { new VariantAttribute(DatabaseProvider.SqlClient, ProgrammingLanguage.CSharp) }; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Migrations +{ + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + using Xunit.Extensions; + using Xunit.Sdk; + + public class MigrationsTheoryAttribute : TheoryAttribute + { + protected override IEnumerable EnumerateTestCommands(IMethodInfo method) + { + var _providerLanguageCombinations = GetCombinations(method.MethodInfo); + + var testCommands + = method.MethodInfo.GetParameters().Length == 0 + ? new[] { new FactCommand(method) } + : base.EnumerateTestCommands(method); + + return (from providerLanguageCombination in _providerLanguageCombinations + from testCommand in testCommands + select new MigrationsTheoryCommand( + testCommand, + providerLanguageCombination.DatabaseProvider, + providerLanguageCombination.ProgrammingLanguage)); + } + + private static IEnumerable GetCombinations(MethodInfo method) + { + var methodVariants + = method + .GetCustomAttributes(typeof(VariantAttribute), true) + .Cast() + .ToList(); + + if (methodVariants.Any()) + { + return methodVariants; + } + + var typeVariants + = method.DeclaringType + .GetCustomAttributes(typeof(VariantAttribute), true) + .Cast() + .ToList(); + + if (typeVariants.Any()) + { + return typeVariants; + } + + return new[] { new VariantAttribute(DatabaseProvider.SqlClient, ProgrammingLanguage.CSharp) }; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/MigrationsTheoryCommand.cs b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/MigrationsTheoryCommand.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/Migrations/TestHelpers/MigrationsTheoryCommand.cs rename to test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/MigrationsTheoryCommand.cs index 166efb00..2a958956 100644 --- a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/MigrationsTheoryCommand.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/MigrationsTheoryCommand.cs @@ -1,61 +1,61 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - using System.Xml; - using Xunit.Sdk; - - internal class MigrationsTheoryCommand : ITestCommand - { - private readonly ITestCommand _innerCommand; - private readonly DatabaseProvider _provider; - private readonly ProgrammingLanguage _language; - - public MigrationsTheoryCommand(ITestCommand innerCommand, DatabaseProvider provider, ProgrammingLanguage language) - { - _innerCommand = innerCommand; - _provider = provider; - _language = language; - } - - public MethodResult Execute(object testClass) - { - var dbTestClass = testClass as DbTestCase; - - if (dbTestClass == null) - { - throw new InvalidOperationException( - string.Format( - "Expected {0} to be derived from {1}", testClass.GetType().FullName, typeof(DbTestCase).FullName)); - } - - dbTestClass.Init(_provider, _language); - - return _innerCommand.Execute(testClass); - } - - public string DisplayName - { - get - { - return string.Format( - "{0} - DatabaseProvider: {1}, ProgrammingLanguage: {2}", _innerCommand.DisplayName, _provider, _language); - } - } - - public bool ShouldCreateInstance - { - get { return _innerCommand.ShouldCreateInstance; } - } - - public int Timeout - { - get { return _innerCommand.Timeout; } - } - - public XmlNode ToStartXml() - { - return _innerCommand.ToStartXml(); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Migrations +{ + using System.Xml; + using Xunit.Sdk; + + internal class MigrationsTheoryCommand : ITestCommand + { + private readonly ITestCommand _innerCommand; + private readonly DatabaseProvider _provider; + private readonly ProgrammingLanguage _language; + + public MigrationsTheoryCommand(ITestCommand innerCommand, DatabaseProvider provider, ProgrammingLanguage language) + { + _innerCommand = innerCommand; + _provider = provider; + _language = language; + } + + public MethodResult Execute(object testClass) + { + var dbTestClass = testClass as DbTestCase; + + if (dbTestClass == null) + { + throw new InvalidOperationException( + string.Format( + "Expected {0} to be derived from {1}", testClass.GetType().FullName, typeof(DbTestCase).FullName)); + } + + dbTestClass.Init(_provider, _language); + + return _innerCommand.Execute(testClass); + } + + public string DisplayName + { + get + { + return string.Format( + "{0} - DatabaseProvider: {1}, ProgrammingLanguage: {2}", _innerCommand.DisplayName, _provider, _language); + } + } + + public bool ShouldCreateInstance + { + get { return _innerCommand.ShouldCreateInstance; } + } + + public int Timeout + { + get { return _innerCommand.Timeout; } + } + + public XmlNode ToStartXml() + { + return _innerCommand.ToStartXml(); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/TestDatabase.cs b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/TestDatabase.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/Migrations/TestHelpers/TestDatabase.cs rename to test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/TestDatabase.cs index ad6425db..0e320dea 100644 --- a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/TestDatabase.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/TestDatabase.cs @@ -1,341 +1,341 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - using System.Data.Common; - using System.Data.Entity.Migrations.Sql; - using System.Data.SqlClient; - using System.Data.SqlServerCe; - using System.IO; - - public abstract class TestDatabase - { - public string ConnectionString { get; protected set; } - public string ProviderName { get; protected set; } - public string ProviderManifestToken { get; protected set; } - public MigrationSqlGenerator SqlGenerator { get; protected set; } - public virtual InfoContext Info { get; protected set; } - - public abstract bool Exists(); - - public abstract void EnsureDatabase(); - - public abstract void ResetDatabase(); - - public abstract void DropDatabase(); - - public abstract DbConnection CreateConnection(string connectionString); - - protected static InfoContext CreateInfoContext(DbConnection connection, bool supportsSchema = true) - { - var info = new InfoContext(connection, supportsSchema); - info.Database.Initialize(force: false); - - return info; - } - - protected void ExecuteNonQuery(string commandText, string connectionString = null) - { - Execute(commandText, c => c.ExecuteNonQuery(), connectionString); - } - - protected T ExecuteScalar(string commandText, string connectionString = null) - { - return Execute(commandText, c => (T)c.ExecuteScalar(), connectionString); - } - - private T Execute(string commandText, Func action, string connectionString = null) - { - connectionString = connectionString ?? ConnectionString; - - using (var connection = CreateConnection(connectionString)) - { - using (var command = connection.CreateCommand()) - { - connection.Open(); - command.CommandText = commandText; - - return action(command); - } - } - } - } - - public class SqlTestDatabase : TestDatabase - { - private readonly string _name; - - public SqlTestDatabase(string name) - { - _name = name; - - ConnectionString = ModelHelpers.SimpleConnectionString(name); - ProviderName = "System.Data.SqlClient"; - ProviderManifestToken = "2008"; - SqlGenerator = new SqlServerMigrationSqlGenerator(); - Info = CreateInfoContext(new SqlConnection(ConnectionString)); - } - - public override void EnsureDatabase() - { - var sql - = "IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = N'" + _name + "') " - + "CREATE DATABASE [" + _name + "]"; - - ExecuteNonQuery(sql, ModelHelpers.SimpleConnectionString("master")); - - ResetDatabase(); - } - - public override void ResetDatabase() - { - ExecuteNonQuery( - @"DECLARE @sql NVARCHAR(1024); - - DECLARE history_cursor CURSOR FOR - SELECT 'DROP TABLE ' + SCHEMA_NAME(schema_id) + '.' + object_name(object_id) + ';' - FROM sys.objects - WHERE name = '__MigrationHistory' - - OPEN history_cursor; - FETCH NEXT FROM history_cursor INTO @sql; - WHILE @@FETCH_STATUS = 0 - BEGIN - EXEC sp_executesql @sql; - FETCH NEXT FROM history_cursor INTO @sql; - END - CLOSE history_cursor; - DEALLOCATE history_cursor; - - DECLARE @constraint_name NVARCHAR(256), - @table_schema NVARCHAR(100), - @table_name NVARCHAR(100); - - DECLARE constraint_cursor CURSOR FOR - SELECT constraint_name, table_schema, table_name - FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS - WHERE constraint_catalog = 'MigrationsTest' - AND constraint_type = 'FOREIGN KEY' - - OPEN constraint_cursor; - FETCH NEXT FROM constraint_cursor INTO @constraint_name, @table_schema, @table_name; - WHILE @@FETCH_STATUS = 0 - BEGIN - SELECT @sql = 'ALTER TABLE [' + @table_schema + '].[' + @table_name + '] DROP CONSTRAINT [' + @constraint_name + ']'; - EXEC sp_executesql @sql; - FETCH NEXT FROM constraint_cursor INTO @constraint_name, @table_schema, @table_name; - END - CLOSE constraint_cursor; - DEALLOCATE constraint_cursor; - - EXEC sp_MSforeachtable 'DROP TABLE ?';" - ); - } - - public override void DropDatabase() - { - SqlConnection.ClearAllPools(); - ExecuteNonQuery( - @"ALTER DATABASE [" + _name - + "] SET OFFLINE WITH ROLLBACK IMMEDIATE;ALTER DATABASE [" + _name - + "] SET ONLINE;DROP DATABASE [" + _name + "]"); - } - - public override bool Exists() - { - return Database.Exists(ConnectionString); - } - - public override DbConnection CreateConnection(string connectionString) - { - return new SqlConnection(connectionString); - } - } - - public class SqlCeTestDatabase : TestDatabase - { - private readonly string _name; - - public SqlCeTestDatabase(string name) - { - _name = name; - - ConnectionString = ModelHelpers.SimpleCeConnectionString(name); - ProviderName = "System.Data.SqlServerCe.4.0"; - ProviderManifestToken = "4.0"; - SqlGenerator = new SqlCeMigrationSqlGenerator(); - Info = CreateInfoContext(new SqlCeConnection(ConnectionString), false); - } - - public override InfoContext Info - { - get - { - // This is not ideal, but the SqlCe provider does not support schemas. In order - // to map to these special schema-qualified views, we need to create wrappers for them. - SyncInfoWrappers(); - - return base.Info; - } - protected set { base.Info = value; } - } - - public override void EnsureDatabase() - { - if (!File.Exists(_name + ".sdf")) - { - using (var engine = new SqlCeEngine - { - LocalConnectionString = ConnectionString - }) - { - engine.CreateDatabase(); - } - } - } - - public override bool Exists() - { - return File.Exists(_name + ".sdf"); - } - - public override void ResetDatabase() - { - DropDatabase(); - EnsureDatabase(); - } - - public override void DropDatabase() - { - File.Delete(_name + ".sdf"); - } - - public override DbConnection CreateConnection(string connectionString) - { - return new SqlCeConnection(connectionString); - } - - private void SyncInfoWrappers() - { - if (!Exists()) - { - return; - } - - if (!TableExists("TABLES")) - { - ExecuteNonQuery( - @"CREATE TABLE TABLES ( - TABLE_SCHEMA nvarchar(128), - TABLE_NAME nvarchar(128), - PRIMARY KEY (TABLE_SCHEMA, TABLE_NAME) -)"); - } - - if (!TableExists("COLUMNS")) - { - ExecuteNonQuery( - @"CREATE TABLE COLUMNS ( - TABLE_SCHEMA nvarchar(128), - TABLE_NAME nvarchar(128), - COLUMN_NAME nvarchar(128), - ORDINAL_POSITION int, - COLUMN_DEFAULT nvarchar(4000), - IS_NULLABLE nvarchar(3), - DATA_TYPE nvarchar(128), - CHARACTER_MAXIMUM_LENGTH int, - NUMERIC_PRECISION smallint, - NUMERIC_SCALE smallint, - DATETIME_PRECISION int, - PRIMARY KEY (TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME) -)"); - } - - if (!TableExists("TABLE_CONSTRAINTS")) - { - ExecuteNonQuery( - @"CREATE TABLE TABLE_CONSTRAINTS ( - CONSTRAINT_SCHEMA nvarchar(128), - CONSTRAINT_NAME nvarchar(128), - TABLE_SCHEMA nvarchar(128), - TABLE_NAME nvarchar(128), - CONSTRAINT_TYPE nvarchar(128), - PRIMARY KEY (CONSTRAINT_SCHEMA, CONSTRAINT_NAME) -)"); - } - - if (!TableExists("REFERENTIAL_CONSTRAINTS")) - { - ExecuteNonQuery( - @"CREATE TABLE REFERENTIAL_CONSTRAINTS ( - CONSTRAINT_SCHEMA nvarchar(128), - CONSTRAINT_NAME nvarchar(128), - UNIQUE_CONSTRAINT_SCHEMA nvarchar(128), - UNIQUE_CONSTRAINT_NAME nvarchar(128), - DELETE_RULE nvarchar(128), - PRIMARY KEY (CONSTRAINT_SCHEMA, CONSTRAINT_NAME) -)"); - } - - if (!TableExists("KEY_COLUMN_USAGE")) - { - ExecuteNonQuery( - @"CREATE TABLE KEY_COLUMN_USAGE ( - CONSTRAINT_SCHEMA nvarchar(128), - CONSTRAINT_NAME nvarchar(128), - TABLE_SCHEMA nvarchar(128), - TABLE_NAME nvarchar(128), - COLUMN_NAME nvarchar(128), - ORDINAL_POSITION int, - PRIMARY KEY (CONSTRAINT_SCHEMA, CONSTRAINT_NAME, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME) -)"); - } - - ExecuteNonQuery("DELETE TABLES"); - ExecuteNonQuery( - @"INSERT TABLES -SELECT '' TABLE_SCHEMA, TABLE_NAME -FROM INFORMATION_SCHEMA.TABLES"); - - ExecuteNonQuery("DELETE COLUMNS"); - ExecuteNonQuery( - @"INSERT COLUMNS -SELECT - '' TABLE_SCHEMA, - TABLE_NAME, - COLUMN_NAME, - ORDINAL_POSITION, - COLUMN_DEFAULT, - IS_NULLABLE, - DATA_TYPE, - CHARACTER_MAXIMUM_LENGTH, - NUMERIC_PRECISION, - NUMERIC_SCALE, - DATETIME_PRECISION -FROM INFORMATION_SCHEMA.COLUMNS"); - - ExecuteNonQuery("DELETE TABLE_CONSTRAINTS"); - ExecuteNonQuery( - @"INSERT TABLE_CONSTRAINTS -SELECT '' CONSTRAINT_SCHEMA, CONSTRAINT_NAME, '' TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_TYPE -FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS"); - - ExecuteNonQuery("DELETE REFERENTIAL_CONSTRAINTS"); - ExecuteNonQuery( - @"INSERT REFERENTIAL_CONSTRAINTS -SELECT '' CONSTRAINT_SCHEMA, CONSTRAINT_NAME, '' UNIQUE_CONSTRAINT_SCHEMA, UNIQUE_CONSTRAINT_NAME, DELETE_RULE -FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS"); - - ExecuteNonQuery("DELETE KEY_COLUMN_USAGE"); - ExecuteNonQuery( - @"INSERT KEY_COLUMN_USAGE -SELECT '' CONSTRAINT_SCHEMA, CONSTRAINT_NAME, '' TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION -FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE"); - } - - private bool TableExists(string name) - { - return ExecuteScalar("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '" + name + "'") != 0; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Migrations +{ + using System.Data.Common; + using System.Data.Entity.Migrations.Sql; + using System.Data.SqlClient; + using System.Data.SqlServerCe; + using System.IO; + + public abstract class TestDatabase + { + public string ConnectionString { get; protected set; } + public string ProviderName { get; protected set; } + public string ProviderManifestToken { get; protected set; } + public MigrationSqlGenerator SqlGenerator { get; protected set; } + public virtual InfoContext Info { get; protected set; } + + public abstract bool Exists(); + + public abstract void EnsureDatabase(); + + public abstract void ResetDatabase(); + + public abstract void DropDatabase(); + + public abstract DbConnection CreateConnection(string connectionString); + + protected static InfoContext CreateInfoContext(DbConnection connection, bool supportsSchema = true) + { + var info = new InfoContext(connection, supportsSchema); + info.Database.Initialize(force: false); + + return info; + } + + protected void ExecuteNonQuery(string commandText, string connectionString = null) + { + Execute(commandText, c => c.ExecuteNonQuery(), connectionString); + } + + protected T ExecuteScalar(string commandText, string connectionString = null) + { + return Execute(commandText, c => (T)c.ExecuteScalar(), connectionString); + } + + private T Execute(string commandText, Func action, string connectionString = null) + { + connectionString = connectionString ?? ConnectionString; + + using (var connection = CreateConnection(connectionString)) + { + using (var command = connection.CreateCommand()) + { + connection.Open(); + command.CommandText = commandText; + + return action(command); + } + } + } + } + + public class SqlTestDatabase : TestDatabase + { + private readonly string _name; + + public SqlTestDatabase(string name) + { + _name = name; + + ConnectionString = ModelHelpers.SimpleConnectionString(name); + ProviderName = "System.Data.SqlClient"; + ProviderManifestToken = "2008"; + SqlGenerator = new SqlServerMigrationSqlGenerator(); + Info = CreateInfoContext(new SqlConnection(ConnectionString)); + } + + public override void EnsureDatabase() + { + var sql + = "IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = N'" + _name + "') " + + "CREATE DATABASE [" + _name + "]"; + + ExecuteNonQuery(sql, ModelHelpers.SimpleConnectionString("master")); + + ResetDatabase(); + } + + public override void ResetDatabase() + { + ExecuteNonQuery( + @"DECLARE @sql NVARCHAR(1024); + + DECLARE history_cursor CURSOR FOR + SELECT 'DROP TABLE ' + SCHEMA_NAME(schema_id) + '.' + object_name(object_id) + ';' + FROM sys.objects + WHERE name = '__MigrationHistory' + + OPEN history_cursor; + FETCH NEXT FROM history_cursor INTO @sql; + WHILE @@FETCH_STATUS = 0 + BEGIN + EXEC sp_executesql @sql; + FETCH NEXT FROM history_cursor INTO @sql; + END + CLOSE history_cursor; + DEALLOCATE history_cursor; + + DECLARE @constraint_name NVARCHAR(256), + @table_schema NVARCHAR(100), + @table_name NVARCHAR(100); + + DECLARE constraint_cursor CURSOR FOR + SELECT constraint_name, table_schema, table_name + FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS + WHERE constraint_catalog = 'MigrationsTest' + AND constraint_type = 'FOREIGN KEY' + + OPEN constraint_cursor; + FETCH NEXT FROM constraint_cursor INTO @constraint_name, @table_schema, @table_name; + WHILE @@FETCH_STATUS = 0 + BEGIN + SELECT @sql = 'ALTER TABLE [' + @table_schema + '].[' + @table_name + '] DROP CONSTRAINT [' + @constraint_name + ']'; + EXEC sp_executesql @sql; + FETCH NEXT FROM constraint_cursor INTO @constraint_name, @table_schema, @table_name; + END + CLOSE constraint_cursor; + DEALLOCATE constraint_cursor; + + EXEC sp_MSforeachtable 'DROP TABLE ?';" + ); + } + + public override void DropDatabase() + { + SqlConnection.ClearAllPools(); + ExecuteNonQuery( + @"ALTER DATABASE [" + _name + + "] SET OFFLINE WITH ROLLBACK IMMEDIATE;ALTER DATABASE [" + _name + + "] SET ONLINE;DROP DATABASE [" + _name + "]"); + } + + public override bool Exists() + { + return Database.Exists(ConnectionString); + } + + public override DbConnection CreateConnection(string connectionString) + { + return new SqlConnection(connectionString); + } + } + + public class SqlCeTestDatabase : TestDatabase + { + private readonly string _name; + + public SqlCeTestDatabase(string name) + { + _name = name; + + ConnectionString = ModelHelpers.SimpleCeConnectionString(name); + ProviderName = "System.Data.SqlServerCe.4.0"; + ProviderManifestToken = "4.0"; + SqlGenerator = new SqlCeMigrationSqlGenerator(); + Info = CreateInfoContext(new SqlCeConnection(ConnectionString), false); + } + + public override InfoContext Info + { + get + { + // This is not ideal, but the SqlCe provider does not support schemas. In order + // to map to these special schema-qualified views, we need to create wrappers for them. + SyncInfoWrappers(); + + return base.Info; + } + protected set { base.Info = value; } + } + + public override void EnsureDatabase() + { + if (!File.Exists(_name + ".sdf")) + { + using (var engine = new SqlCeEngine + { + LocalConnectionString = ConnectionString + }) + { + engine.CreateDatabase(); + } + } + } + + public override bool Exists() + { + return File.Exists(_name + ".sdf"); + } + + public override void ResetDatabase() + { + DropDatabase(); + EnsureDatabase(); + } + + public override void DropDatabase() + { + File.Delete(_name + ".sdf"); + } + + public override DbConnection CreateConnection(string connectionString) + { + return new SqlCeConnection(connectionString); + } + + private void SyncInfoWrappers() + { + if (!Exists()) + { + return; + } + + if (!TableExists("TABLES")) + { + ExecuteNonQuery( + @"CREATE TABLE TABLES ( + TABLE_SCHEMA nvarchar(128), + TABLE_NAME nvarchar(128), + PRIMARY KEY (TABLE_SCHEMA, TABLE_NAME) +)"); + } + + if (!TableExists("COLUMNS")) + { + ExecuteNonQuery( + @"CREATE TABLE COLUMNS ( + TABLE_SCHEMA nvarchar(128), + TABLE_NAME nvarchar(128), + COLUMN_NAME nvarchar(128), + ORDINAL_POSITION int, + COLUMN_DEFAULT nvarchar(4000), + IS_NULLABLE nvarchar(3), + DATA_TYPE nvarchar(128), + CHARACTER_MAXIMUM_LENGTH int, + NUMERIC_PRECISION smallint, + NUMERIC_SCALE smallint, + DATETIME_PRECISION int, + PRIMARY KEY (TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME) +)"); + } + + if (!TableExists("TABLE_CONSTRAINTS")) + { + ExecuteNonQuery( + @"CREATE TABLE TABLE_CONSTRAINTS ( + CONSTRAINT_SCHEMA nvarchar(128), + CONSTRAINT_NAME nvarchar(128), + TABLE_SCHEMA nvarchar(128), + TABLE_NAME nvarchar(128), + CONSTRAINT_TYPE nvarchar(128), + PRIMARY KEY (CONSTRAINT_SCHEMA, CONSTRAINT_NAME) +)"); + } + + if (!TableExists("REFERENTIAL_CONSTRAINTS")) + { + ExecuteNonQuery( + @"CREATE TABLE REFERENTIAL_CONSTRAINTS ( + CONSTRAINT_SCHEMA nvarchar(128), + CONSTRAINT_NAME nvarchar(128), + UNIQUE_CONSTRAINT_SCHEMA nvarchar(128), + UNIQUE_CONSTRAINT_NAME nvarchar(128), + DELETE_RULE nvarchar(128), + PRIMARY KEY (CONSTRAINT_SCHEMA, CONSTRAINT_NAME) +)"); + } + + if (!TableExists("KEY_COLUMN_USAGE")) + { + ExecuteNonQuery( + @"CREATE TABLE KEY_COLUMN_USAGE ( + CONSTRAINT_SCHEMA nvarchar(128), + CONSTRAINT_NAME nvarchar(128), + TABLE_SCHEMA nvarchar(128), + TABLE_NAME nvarchar(128), + COLUMN_NAME nvarchar(128), + ORDINAL_POSITION int, + PRIMARY KEY (CONSTRAINT_SCHEMA, CONSTRAINT_NAME, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME) +)"); + } + + ExecuteNonQuery("DELETE TABLES"); + ExecuteNonQuery( + @"INSERT TABLES +SELECT '' TABLE_SCHEMA, TABLE_NAME +FROM INFORMATION_SCHEMA.TABLES"); + + ExecuteNonQuery("DELETE COLUMNS"); + ExecuteNonQuery( + @"INSERT COLUMNS +SELECT + '' TABLE_SCHEMA, + TABLE_NAME, + COLUMN_NAME, + ORDINAL_POSITION, + COLUMN_DEFAULT, + IS_NULLABLE, + DATA_TYPE, + CHARACTER_MAXIMUM_LENGTH, + NUMERIC_PRECISION, + NUMERIC_SCALE, + DATETIME_PRECISION +FROM INFORMATION_SCHEMA.COLUMNS"); + + ExecuteNonQuery("DELETE TABLE_CONSTRAINTS"); + ExecuteNonQuery( + @"INSERT TABLE_CONSTRAINTS +SELECT '' CONSTRAINT_SCHEMA, CONSTRAINT_NAME, '' TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_TYPE +FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS"); + + ExecuteNonQuery("DELETE REFERENTIAL_CONSTRAINTS"); + ExecuteNonQuery( + @"INSERT REFERENTIAL_CONSTRAINTS +SELECT '' CONSTRAINT_SCHEMA, CONSTRAINT_NAME, '' UNIQUE_CONSTRAINT_SCHEMA, UNIQUE_CONSTRAINT_NAME, DELETE_RULE +FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS"); + + ExecuteNonQuery("DELETE KEY_COLUMN_USAGE"); + ExecuteNonQuery( + @"INSERT KEY_COLUMN_USAGE +SELECT '' CONSTRAINT_SCHEMA, CONSTRAINT_NAME, '' TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION +FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE"); + } + + private bool TableExists(string name) + { + return ExecuteScalar("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '" + name + "'") != 0; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/VariantAttribute.cs b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/VariantAttribute.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/Migrations/TestHelpers/VariantAttribute.cs rename to test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/VariantAttribute.cs index fbd7455b..fa4fbab3 100644 --- a/test/EntityFramework/FunctionalTests/Migrations/TestHelpers/VariantAttribute.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestHelpers/VariantAttribute.cs @@ -1,17 +1,17 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] - public class VariantAttribute : Attribute - { - public VariantAttribute(DatabaseProvider provider, ProgrammingLanguage language) - { - DatabaseProvider = provider; - ProgrammingLanguage = language; - } - - public DatabaseProvider DatabaseProvider { get; private set; } - public ProgrammingLanguage ProgrammingLanguage { get; private set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Migrations +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] + public class VariantAttribute : Attribute + { + public VariantAttribute(DatabaseProvider provider, ProgrammingLanguage language) + { + DatabaseProvider = provider; + ProgrammingLanguage = language; + } + + public DatabaseProvider DatabaseProvider { get; private set; } + public ProgrammingLanguage ProgrammingLanguage { get; private set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/Migrations/TestModel/TestModels.cs b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestModel/TestModels.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/Migrations/TestModel/TestModels.cs rename to test/EntityFramework/FunctionalTests.Transitional/Migrations/TestModel/TestModels.cs index dc0e9131..bfff5d3d 100644 --- a/test/EntityFramework/FunctionalTests/Migrations/TestModel/TestModels.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Migrations/TestModel/TestModels.cs @@ -1,401 +1,401 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - using System.Collections.Generic; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; - using System.Data.Entity.Spatial; - using System.Data.SqlServerCe; - - public class MigrationsCustomer - { - public MigrationsCustomer() - { - DateOfBirth = DateTime.Now; - HomeAddress = new MigrationsAddress(); - WorkAddress = new MigrationsAddress(); - } - - public int Id { get; set; } - public long CustomerNumber { get; set; } - public string Name { get; set; } - public string FullName { get; set; } - public DateTime DateOfBirth { get; set; } - public byte Age { get; set; } - public MigrationsAddress HomeAddress { get; set; } - public MigrationsAddress WorkAddress { get; set; } - public ICollection Orders { get; set; } - - [MaxLength(1024)] - public byte[] Photo { get; set; } - } - - public class SpecialCustomer : MigrationsCustomer - { - public int Points { get; set; } - } - - public class GoldCustomer : MigrationsCustomer - { - [Column("Gold_Points")] - public int Points { get; set; } - } - - [ComplexType] - public class MigrationsAddress - { - [MaxLength(150)] - public string City { get; set; } - } - - [Table("Orders", Schema = "ordering")] - public class Order - { - public int OrderId { get; set; } - public string Type { get; set; } - - [Timestamp] - public byte[] Version { get; set; } - - public ICollection OrderLines { get; set; } - } - - public class OrderLine - { - public int Id { get; set; } - public int OrderId { get; set; } - public short Quantity { get; set; } - public decimal Price { get; set; } - - [Column(TypeName = "money")] - public decimal Total { get; set; } - - public bool? IsShipped { get; set; } - public int ProductId { get; set; } - - [MaxLength(128)] - public string Sku { get; set; } - } - - public class MigrationsProduct - { - [Key] - [Column(Order = 0)] - public int ProductId { get; set; } - - [Key] - [Column(Order = 1)] - [MaxLength(128)] - public string Sku { get; set; } - - public string Name { get; set; } - - public byte[] Image { get; set; } - } - - public class MigrationsStore - { - public int Id { get; set; } - public string Name { get; set; } - - public MigrationsAddress Address { get; set; } - public DbGeography Location { get; set; } - public DbGeometry FloorPlan { get; set; } - public StoreKind Kind { get; set; } - - [Timestamp] - public byte[] RowVersion { get; set; } - } - - public enum StoreKind - { - Mall, - HighStreet, - Embedded, - } - - public class ShopContext_v1 : DbContext - { - public ShopContext_v1() - { - } - - public ShopContext_v1(string nameOrConnectionString) - : base(nameOrConnectionString) - { - } - - public DbSet Customers { get; set; } - public DbSet Products { get; set; } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - modelBuilder.Entity().Ignore(c => c.Total); - modelBuilder.Entity().Property(o => o.Type).IsUnicode(false); - modelBuilder.Entity(); - } - } - - public class ShopContext_v2 : ShopContext_v1 - { - public ShopContext_v2() - { - } - - public ShopContext_v2(string nameOrConnectionString) - : base(nameOrConnectionString) - { - } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - modelBuilder.Entity().ToTable("tbl_customers", "crm"); - - if (!(Database.Connection is SqlCeConnection)) - { - // NotSupported in CE - modelBuilder.Entity().Property(c => c.Name).HasColumnName("new_name"); - } - - modelBuilder.Entity().Property(c => c.FullName).HasMaxLength(25); - - modelBuilder.Entity().Property(o => o.Type).IsUnicode(false); - modelBuilder.Entity().HasMany(o => o.OrderLines).WithOptional().WillCascadeOnDelete(false); - - modelBuilder.Entity().Ignore(ol => ol.IsShipped); - modelBuilder.Entity().HasKey( - ol => new - { - ol.Id, - ol.OrderId - }); - modelBuilder.Entity(); - } - } - - public class ShopContext_v3 : ShopContext_v2 - { - public ShopContext_v3() - { - } - - public ShopContext_v3(string nameOrConnectionString) - : base(nameOrConnectionString) - { - } - - public DbSet Stores { get; set; } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); - - this.IgnoreSpatialTypesOnSqlCe(modelBuilder); - } - } - - public class ShopContext_v4 : ShopContext_v3 - { - public ShopContext_v4() - { - } - - public ShopContext_v4(string nameOrConnectionString) - : base(nameOrConnectionString) - { - } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); - - modelBuilder - .Entity() - .Property(s => s.Name) - .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); - } - } - - public class ShopContext_v5 : ShopContext_v1 - { - public ShopContext_v5() - { - } - - public ShopContext_v5(string nameOrConnectionString) - : base(nameOrConnectionString) - { - } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); - - modelBuilder.HasDefaultSchema("non_default_schema"); - } - } - - public class EmptyModel : DbContext - { - } - - public class NonEmptyModel : DbContext - { - public DbSet Blogs { get; set; } - } - - public class MigrationsBlog - { - public int MigrationsBlogId { get; set; } - public string Url { get; set; } - } - - internal class MappingScenariosContext : DbContext - { - public DbSet Employees { get; set; } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - modelBuilder.Entity() - .HasOptional(e => e.Manager) - .WithMany(m => m.DirectReports); - } - } - - internal class MigrationsEmployee - { - public int Id { get; set; } - - public int? ManagerId { get; set; } - public MigrationsEmployee Manager { get; set; } - - public ICollection DirectReports { get; set; } - } - - public class TypeCasts - { - public int Id { get; set; } - - public byte ByteToInt16 { get; set; } - public byte ByteToInt32 { get; set; } - public byte ByteToInt64 { get; set; } - public short Int16ToInt32 { get; set; } - public short Int16ToInt64 { get; set; } - public int Int32ToInt64 { get; set; } - public decimal Decimal6ToSingle { get; set; } - public decimal Decimal6ToDouble { get; set; } - public decimal Decimal7ToSingle { get; set; } - public float SingleToDecimal11 { get; set; } - public float SingleToDouble { get; set; } - public float SingleToDecimal16 { get; set; } - public decimal Decimal15ToDouble { get; set; } - public double DoubleToDecimal16 { get; set; } - - #region Version 2 - - [Column("ByteToInt16")] - public short ByteToInt16_v2 { get; set; } - - [Column("ByteToInt32")] - public int ByteToInt32_v2 { get; set; } - - [Column("ByteToInt64")] - public long ByteToInt64_v2 { get; set; } - - [Column("Int16ToInt32")] - public int Int16ToInt32_v2 { get; set; } - - [Column("Int16ToInt64")] - public long Int16ToInt64_v2 { get; set; } - - [Column("Int32ToInt64")] - public long Int32ToInt64_v2 { get; set; } - - [Column("Decimal6ToSingle")] - public float Decimal6ToSingle_v2 { get; set; } - - [Column("Decimal6ToDouble")] - public double Decimal6ToDouble_v2 { get; set; } - - [Column("Decimal7ToSingle")] - public float Decimal7ToSingle_v2 { get; set; } - - [Column("SingleToDecimal11")] - public decimal SingleToDecimal11_v2 { get; set; } - - [Column("SingleToDouble")] - public double SingleToDouble_v2 { get; set; } - - [Column("SingleToDecimal16")] - public decimal SingleToDecimal16_v2 { get; set; } - - [Column("Decimal15ToDouble")] - public double Decimal15ToDouble_v2 { get; set; } - - [Column("DoubleToDecimal16")] - public decimal DoubleToDecimal16_v2 { get; set; } - - #endregion - } - - public class Comment - { - public int Id { get; set; } - public int? MigrationsBlogId { get; set; } - public MigrationsBlog Blog { get; set; } - } - - namespace UserRoles_v1 - { - public class Role - { - public long Id { get; set; } - public virtual ICollection AssignedUsers { get; set; } - } - - public class User - { - public long Id { get; set; } - public virtual ICollection AssignedRoles { get; set; } - } - } - - namespace UserRoles_v2 - { - public class Role - { - public long Id { get; set; } - public virtual ICollection AssignedUsers { get; set; } - } - - public class User2 - { - public long Id { get; set; } - public virtual ICollection AssignedRoles { get; set; } - } - } - - public class ProcessedTransactionContext : DbContext - { - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - modelBuilder - .Entity() - .HasMany(e => e.ChildTransactions) - .WithOptional() - .HasForeignKey(e => e.ParentTransactionId); - } - } - - public class ProcessedTransaction - { - public int Id { get; set; } - - public int? ParentTransactionId { get; set; } - - public virtual ProcessedTransaction ParentTransaction { get; set; } - - public virtual ICollection ChildTransactions { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Migrations +{ + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + using System.ComponentModel.DataAnnotations.Schema; + using System.Data.Entity.Spatial; + using System.Data.SqlServerCe; + + public class MigrationsCustomer + { + public MigrationsCustomer() + { + DateOfBirth = DateTime.Now; + HomeAddress = new MigrationsAddress(); + WorkAddress = new MigrationsAddress(); + } + + public int Id { get; set; } + public long CustomerNumber { get; set; } + public string Name { get; set; } + public string FullName { get; set; } + public DateTime DateOfBirth { get; set; } + public byte Age { get; set; } + public MigrationsAddress HomeAddress { get; set; } + public MigrationsAddress WorkAddress { get; set; } + public ICollection Orders { get; set; } + + [MaxLength(1024)] + public byte[] Photo { get; set; } + } + + public class SpecialCustomer : MigrationsCustomer + { + public int Points { get; set; } + } + + public class GoldCustomer : MigrationsCustomer + { + [Column("Gold_Points")] + public int Points { get; set; } + } + + [ComplexType] + public class MigrationsAddress + { + [MaxLength(150)] + public string City { get; set; } + } + + [Table("Orders", Schema = "ordering")] + public class Order + { + public int OrderId { get; set; } + public string Type { get; set; } + + [Timestamp] + public byte[] Version { get; set; } + + public ICollection OrderLines { get; set; } + } + + public class OrderLine + { + public int Id { get; set; } + public int OrderId { get; set; } + public short Quantity { get; set; } + public decimal Price { get; set; } + + [Column(TypeName = "money")] + public decimal Total { get; set; } + + public bool? IsShipped { get; set; } + public int ProductId { get; set; } + + [MaxLength(128)] + public string Sku { get; set; } + } + + public class MigrationsProduct + { + [Key] + [Column(Order = 0)] + public int ProductId { get; set; } + + [Key] + [Column(Order = 1)] + [MaxLength(128)] + public string Sku { get; set; } + + public string Name { get; set; } + + public byte[] Image { get; set; } + } + + public class MigrationsStore + { + public int Id { get; set; } + public string Name { get; set; } + + public MigrationsAddress Address { get; set; } + public DbGeography Location { get; set; } + public DbGeometry FloorPlan { get; set; } + public StoreKind Kind { get; set; } + + [Timestamp] + public byte[] RowVersion { get; set; } + } + + public enum StoreKind + { + Mall, + HighStreet, + Embedded, + } + + public class ShopContext_v1 : DbContext + { + public ShopContext_v1() + { + } + + public ShopContext_v1(string nameOrConnectionString) + : base(nameOrConnectionString) + { + } + + public DbSet Customers { get; set; } + public DbSet Products { get; set; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + modelBuilder.Entity().Ignore(c => c.Total); + modelBuilder.Entity().Property(o => o.Type).IsUnicode(false); + modelBuilder.Entity(); + } + } + + public class ShopContext_v2 : ShopContext_v1 + { + public ShopContext_v2() + { + } + + public ShopContext_v2(string nameOrConnectionString) + : base(nameOrConnectionString) + { + } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + modelBuilder.Entity().ToTable("tbl_customers", "crm"); + + if (!(Database.Connection is SqlCeConnection)) + { + // NotSupported in CE + modelBuilder.Entity().Property(c => c.Name).HasColumnName("new_name"); + } + + modelBuilder.Entity().Property(c => c.FullName).HasMaxLength(25); + + modelBuilder.Entity().Property(o => o.Type).IsUnicode(false); + modelBuilder.Entity().HasMany(o => o.OrderLines).WithOptional().WillCascadeOnDelete(false); + + modelBuilder.Entity().Ignore(ol => ol.IsShipped); + modelBuilder.Entity().HasKey( + ol => new + { + ol.Id, + ol.OrderId + }); + modelBuilder.Entity(); + } + } + + public class ShopContext_v3 : ShopContext_v2 + { + public ShopContext_v3() + { + } + + public ShopContext_v3(string nameOrConnectionString) + : base(nameOrConnectionString) + { + } + + public DbSet Stores { get; set; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + this.IgnoreSpatialTypesOnSqlCe(modelBuilder); + } + } + + public class ShopContext_v4 : ShopContext_v3 + { + public ShopContext_v4() + { + } + + public ShopContext_v4(string nameOrConnectionString) + : base(nameOrConnectionString) + { + } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder + .Entity() + .Property(s => s.Name) + .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); + } + } + + public class ShopContext_v5 : ShopContext_v1 + { + public ShopContext_v5() + { + } + + public ShopContext_v5(string nameOrConnectionString) + : base(nameOrConnectionString) + { + } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.HasDefaultSchema("non_default_schema"); + } + } + + public class EmptyModel : DbContext + { + } + + public class NonEmptyModel : DbContext + { + public DbSet Blogs { get; set; } + } + + public class MigrationsBlog + { + public int MigrationsBlogId { get; set; } + public string Url { get; set; } + } + + internal class MappingScenariosContext : DbContext + { + public DbSet Employees { get; set; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + modelBuilder.Entity() + .HasOptional(e => e.Manager) + .WithMany(m => m.DirectReports); + } + } + + internal class MigrationsEmployee + { + public int Id { get; set; } + + public int? ManagerId { get; set; } + public MigrationsEmployee Manager { get; set; } + + public ICollection DirectReports { get; set; } + } + + public class TypeCasts + { + public int Id { get; set; } + + public byte ByteToInt16 { get; set; } + public byte ByteToInt32 { get; set; } + public byte ByteToInt64 { get; set; } + public short Int16ToInt32 { get; set; } + public short Int16ToInt64 { get; set; } + public int Int32ToInt64 { get; set; } + public decimal Decimal6ToSingle { get; set; } + public decimal Decimal6ToDouble { get; set; } + public decimal Decimal7ToSingle { get; set; } + public float SingleToDecimal11 { get; set; } + public float SingleToDouble { get; set; } + public float SingleToDecimal16 { get; set; } + public decimal Decimal15ToDouble { get; set; } + public double DoubleToDecimal16 { get; set; } + + #region Version 2 + + [Column("ByteToInt16")] + public short ByteToInt16_v2 { get; set; } + + [Column("ByteToInt32")] + public int ByteToInt32_v2 { get; set; } + + [Column("ByteToInt64")] + public long ByteToInt64_v2 { get; set; } + + [Column("Int16ToInt32")] + public int Int16ToInt32_v2 { get; set; } + + [Column("Int16ToInt64")] + public long Int16ToInt64_v2 { get; set; } + + [Column("Int32ToInt64")] + public long Int32ToInt64_v2 { get; set; } + + [Column("Decimal6ToSingle")] + public float Decimal6ToSingle_v2 { get; set; } + + [Column("Decimal6ToDouble")] + public double Decimal6ToDouble_v2 { get; set; } + + [Column("Decimal7ToSingle")] + public float Decimal7ToSingle_v2 { get; set; } + + [Column("SingleToDecimal11")] + public decimal SingleToDecimal11_v2 { get; set; } + + [Column("SingleToDouble")] + public double SingleToDouble_v2 { get; set; } + + [Column("SingleToDecimal16")] + public decimal SingleToDecimal16_v2 { get; set; } + + [Column("Decimal15ToDouble")] + public double Decimal15ToDouble_v2 { get; set; } + + [Column("DoubleToDecimal16")] + public decimal DoubleToDecimal16_v2 { get; set; } + + #endregion + } + + public class Comment + { + public int Id { get; set; } + public int? MigrationsBlogId { get; set; } + public MigrationsBlog Blog { get; set; } + } + + namespace UserRoles_v1 + { + public class Role + { + public long Id { get; set; } + public virtual ICollection AssignedUsers { get; set; } + } + + public class User + { + public long Id { get; set; } + public virtual ICollection AssignedRoles { get; set; } + } + } + + namespace UserRoles_v2 + { + public class Role + { + public long Id { get; set; } + public virtual ICollection AssignedUsers { get; set; } + } + + public class User2 + { + public long Id { get; set; } + public virtual ICollection AssignedRoles { get; set; } + } + } + + public class ProcessedTransactionContext : DbContext + { + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + modelBuilder + .Entity() + .HasMany(e => e.ChildTransactions) + .WithOptional() + .HasForeignKey(e => e.ParentTransactionId); + } + } + + public class ProcessedTransaction + { + public int Id { get; set; } + + public int? ParentTransactionId { get; set; } + + public virtual ProcessedTransaction ParentTransaction { get; set; } + + public virtual ICollection ChildTransactions { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/Migrations/UpgradeScenarios.cs b/test/EntityFramework/FunctionalTests.Transitional/Migrations/UpgradeScenarios.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/Migrations/UpgradeScenarios.cs rename to test/EntityFramework/FunctionalTests.Transitional/Migrations/UpgradeScenarios.cs diff --git a/test/EntityFramework/FunctionalTests/Objects/TransactionsModel.csdl b/test/EntityFramework/FunctionalTests.Transitional/Objects/TransactionsModel.csdl similarity index 96% rename from test/EntityFramework/FunctionalTests/Objects/TransactionsModel.csdl rename to test/EntityFramework/FunctionalTests.Transitional/Objects/TransactionsModel.csdl index a7b03639..0b9dd38e 100644 --- a/test/EntityFramework/FunctionalTests/Objects/TransactionsModel.csdl +++ b/test/EntityFramework/FunctionalTests.Transitional/Objects/TransactionsModel.csdl @@ -1,13 +1,13 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/Objects/TransactionsModel.msl b/test/EntityFramework/FunctionalTests.Transitional/Objects/TransactionsModel.msl similarity index 97% rename from test/EntityFramework/FunctionalTests/Objects/TransactionsModel.msl rename to test/EntityFramework/FunctionalTests.Transitional/Objects/TransactionsModel.msl index 39958e98..c8c50708 100644 --- a/test/EntityFramework/FunctionalTests/Objects/TransactionsModel.msl +++ b/test/EntityFramework/FunctionalTests.Transitional/Objects/TransactionsModel.msl @@ -1,21 +1,21 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/Objects/TransactionsModel.ssdl b/test/EntityFramework/FunctionalTests.Transitional/Objects/TransactionsModel.ssdl similarity index 97% rename from test/EntityFramework/FunctionalTests/Objects/TransactionsModel.ssdl rename to test/EntityFramework/FunctionalTests.Transitional/Objects/TransactionsModel.ssdl index 4fe90299..e1013cf9 100644 --- a/test/EntityFramework/FunctionalTests/Objects/TransactionsModel.ssdl +++ b/test/EntityFramework/FunctionalTests.Transitional/Objects/TransactionsModel.ssdl @@ -1,14 +1,14 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/Objects/TransactionsTests.cs b/test/EntityFramework/FunctionalTests.Transitional/Objects/TransactionsTests.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/Objects/TransactionsTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/Objects/TransactionsTests.cs index 4fa33c5f..c6b532c8 100644 --- a/test/EntityFramework/FunctionalTests/Objects/TransactionsTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Objects/TransactionsTests.cs @@ -1,1463 +1,1463 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Objects -{ - using System.Data.Common; - using System.Data.Entity.Core; - using System.Data.Entity.Core.EntityClient; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.Core.Objects; - using System.Data.Entity.Infrastructure; - using System.Data.Entity.Resources; - using System.Data.SqlClient; - using System.Diagnostics; - using System.Linq; - using System.Reflection; - using System.Transactions; - using Xunit; - - public class TransactionLogEntry - { - public int ID { get; set; } - public int TransactionCount { get; set; } - } - - public class TransactionContext : ObjectContext - { - public TransactionContext(string connectionString) - : base(connectionString) - { - } - - public TransactionContext(EntityConnection connection) - : base(connection) - { - } - - public IQueryable LogEntries - { - get { return CreateObjectSet("Entities.TransactionLog"); } - } - } - - public class TransactionDbContext : DbContext - { - public TransactionDbContext(string connectionString) - : base(connectionString) - { - } - - public TransactionDbContext(EntityConnection connection, bool contextOwnsConnection) - : base(connection, contextOwnsConnection) - { - } - - public TransactionDbContext(SqlConnection connection, DbCompiledModel model, bool contextOwnsConnection) - : base(connection, model, contextOwnsConnection) - { - } - - public DbSet LogEntries { get; set; } - } - - public class TransactionsTests : FunctionalTestBase, IUseFixture - { - private string connectionString; - private string modelDirectory; - - private MetadataWorkspace workspace; - private SqlConnection globalConnection; - private DbCompiledModel compiledModel; - - public void SetFixture(TransactionFixture data) - { - globalConnection = data.GlobalConnection; - compiledModel = data.CompiledModel; - - connectionString = string.Format( - @"metadata=res://EntityFramework.FunctionalTests/System.Data.Entity.Objects.TransactionsModel.csdl|res://EntityFramework.FunctionalTests/System.Data.Entity.Objects.TransactionsModel.ssdl|res://EntityFramework.FunctionalTests/System.Data.Entity.Objects.TransactionsModel.msl;provider=System.Data.SqlClient;provider connection string=""{0}""", - ModelHelpers.SimpleConnectionString("tempdb")); - } - - [Fact] - public void Verify_implicit_transaction_is_created_when_using_DbContext_and_no_transaction_created_by_user_and_connection_is_closed() - { - try - { - using (var ctx = CreateTransactionDbContext()) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - - // Implicit transaction committed. 1 entity expected. - Assert.Equal(1, LogEntriesCount()); - Assert.Equal(ConnectionState.Closed, ctx.Database.Connection.State); - } - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_implicit_transaction_is_created_when_using_DbContext_and_no_transaction_created_by_user_and_EntityConnection_is_opened_and_context_owns_connection() - { - try - { - var entityConnection = new EntityConnection(connectionString); - entityConnection.Open(); - - using (var ctx = CreateTransactionDbContext(entityConnection, contextOwnsConnection: true)) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - - // Implicit transaction committed. 1 entity expected. - Assert.Equal(1, LogEntriesCount()); - Assert.Equal(ConnectionState.Open, ctx.Database.Connection.State); - } - - Assert.Equal(ConnectionState.Closed, entityConnection.State); - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_implicit_transaction_is_created_when_using_DbContext_and_no_transaction_created_by_user_and_EntityConnection_is_opened_and_context_does_not_own_connection() - { - try - { - var entityConnection = new EntityConnection(connectionString); - entityConnection.Open(); - using (var ctx = CreateTransactionDbContext(entityConnection, contextOwnsConnection: false)) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - - // Implicit transaction committed. 1 entity expected. - Assert.Equal(1, LogEntriesCount()); - } - - Assert.Equal(ConnectionState.Open, entityConnection.StoreConnection.State); - Assert.Equal(ConnectionState.Open, entityConnection.State); - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_implicit_transaction_is_created_when_using_DbContext_and_no_transaction_created_by_user_and_SqlConnection_is_opened_and_context_owns_connection() - { - try - { - var sqlConnection = new SqlConnection(globalConnection.ConnectionString); - sqlConnection.Open(); - - using (var ctx = CreateTransactionDbContext(sqlConnection, compiledModel, contextOwnsConnection: true)) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - - // Implicit transaction committed. 1 entity expected. - Assert.Equal(1, LogEntriesCount()); - Assert.Equal(ConnectionState.Open, ctx.Database.Connection.State); - } - - Assert.Equal(ConnectionState.Closed, sqlConnection.State); - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_implicit_transaction_is_created_when_using_DbContext_and_no_transaction_created_by_user_and_SqlConnection_is_opened_and_context_does_not_own_connection() - { - try - { - var sqlConnection = new SqlConnection(globalConnection.ConnectionString); - sqlConnection.Open(); - - using (var ctx = CreateTransactionDbContext(sqlConnection, compiledModel, contextOwnsConnection: false)) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - - // Implicit transaction committed. 1 entity expected. - Assert.Equal(1, LogEntriesCount()); - } - - Assert.Equal(ConnectionState.Open, sqlConnection.State); - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_implicit_transaction_is_not_created_when_using_DbContext_and_user_creates_transaction_using_TransactionScope_and_EntityConnection_is_closed() - { - var entityConnection = new EntityConnection(connectionString); - using (new TransactionScope()) - { - using (var ctx = CreateTransactionDbContext(entityConnection, true)) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - } - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_implicit_transaction_is_not_created_when_using_DbContext_and_user_creates_transaction_using_TransactionScope_and_SqlConnection_is_closed() - { - var connection = new SqlConnection(globalConnection.ConnectionString); - using (new TransactionScope()) - { - using (var ctx = CreateTransactionDbContext(connection, compiledModel, contextOwnsConnection: true)) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - } - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_implicit_transaction_is_not_created_when_using_DbContext_and_user_creates_transaction_using_TransactionScope_and_EntityConnection_is_opened_inside_transaction_scope() - { - var connection = new EntityConnection(connectionString); - using (new TransactionScope()) - { - connection.Open(); - using (var ctx = CreateTransactionDbContext(connection, contextOwnsConnection: true)) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - } - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - } - - // Fails for now - MSDTC on server 'MAUMARDEV\SQLEXPRESS' is unavailable. See Issue #771 for details - ////[Fact] - ////public void Verify_implicit_transaction_is_not_created_when_using_DbContext_and_user_creates_transaction_using_TransactionScope_and_connection_is_opened_inside_transaction_scope() - ////{ - //// try - //// { - //// var connection = new SqlConnection(globalConnection.ConnectionString); - //// using (var transactionScope = new TransactionScope()) - //// { - //// connection.Open(); - //// using (var ctx = CreateTransactionDbContext(connection, compiledModel, contextOwnsConnection: true)) - //// { - //// var transactionLogEntry = AddLogEntryToDatabase(ctx); - //// Assert.Equal(1, transactionLogEntry.TransactionCount); - //// } - //// } - - //// // "Transaction not commited. No entities should be saved to the database." - //// Assert.Equal(0, LogEntriesCount()); - //// } - //// finally - //// { - //// ResetTables(); - //// } - ////} - - // What should be the correct behavior for this? See Issue #777 for details - ////[Fact] - ////public void Verify_implicit_transaction_is_not_created_when_using_DbContext_and_user_creates_transaction_using_TransactionScope_and_EntityConnection_is_opened_outside_transaction_scope() - ////{ - //// try - //// { - //// var entityConnection = new EntityConnection(connectionString); - //// entityConnection.Open(); - //// using (var transactionScope = new TransactionScope()) - //// { - //// using (var ctx = CreateTransactionDbContext(entityConnection, contextOwnsConnection: true)) - //// { - //// var transactionLogEntry = AddLogEntryToDatabase(ctx); - //// Assert.Equal(1, transactionLogEntry.TransactionCount); - //// } - //// } - - //// // "Transaction not commited. No entities should be saved to the database." - //// Assert.Equal(0, LogEntriesCount()); - //// } - //// finally - //// { - //// ResetTables(); - //// } - ////} - - // Fails for now - MSDTC on server 'MAUMARDEV\SQLEXPRESS' is unavailable. See Issue #771 for details - ////[Fact] - ////public void Verify_implicit_transaction_is_not_created_when_using_DbContext_and_user_creates_transaction_using_TransactionScope_and_connection_is_opened_outside_transaction_scope() - ////{ - //// try - //// { - //// var connection = new SqlConnection(globalConnection.ConnectionString); - - //// connection.Open(); - //// using (var transactionScope = new TransactionScope()) - //// { - //// using (var ctx = CreateTransactionDbContext(connection, compiledModel, contextOwnsConnection: true)) - //// { - //// var transactionLogEntry = AddLogEntryToDatabase(ctx); - //// Assert.Equal(1, transactionLogEntry.TransactionCount); - //// } - //// } - - //// // "Transaction not commited. No entities should be saved to the database." - //// Assert.Equal(0, LogEntriesCount()); - //// } - //// finally - //// { - //// ResetTables(); - //// } - ////} - - [Fact] - public void Verify_implicit_transaction_is_created_when_no_transaction_created_by_user_and_connection_is_closed() - { - try - { - using (var ctx = CreateTransactionContext()) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - - // Implicit transaction committed. 1 entity expected. - Assert.Equal(1, LogEntriesCount()); - Assert.Equal(ConnectionState.Closed, ctx.Connection.State); - } - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_implicit_transaction_is_created_when_no_transaction_created_by_user_and_connection_is_created_outside_context_and_is_closed() - { - try - { - var connection = new EntityConnection(connectionString); - using (var ctx = CreateTransactionContext(connection)) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - - // Implicit transaction committed. 1 entity expected. - Assert.Equal(1, LogEntriesCount(connection)); - Assert.Equal(ConnectionState.Closed, ctx.Connection.State); - } - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_implicit_transaction_is_created_when_no_transaction_created_by_user_and_connection_is_open() - { - try - { - using (var ctx = CreateTransactionContext()) - { - ctx.Connection.Open(); - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - - // Implicit transaction committed. 1 entity expected. - Assert.Equal(1, LogEntriesCount()); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_implicit_transaction_is_created_when_no_transaction_created_by_user_and_connection_is_created_outside_context_and_is_open() - { - try - { - var connection = new EntityConnection(connectionString); - connection.Open(); - using (var ctx = CreateTransactionContext(connection)) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - - // Implicit transaction committed. 1 entity expected. - Assert.Equal(1, LogEntriesCount(connection)); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_is_closed() - { - using (new TransactionScope()) - { - using (var ctx = CreateTransactionContext()) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Closed, ctx.Connection.State); - } - } - - // Transaction not commited. No entities should be saved to the database. - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_outside_context_and_is_closed() - { - using (new TransactionScope()) - { - var connection = new EntityConnection(connectionString); - using (var ctx = CreateTransactionContext(connection)) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Closed, ctx.Connection.State); - } - } - - // Transaction not commited. No entities should be saved to the database. - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_outside_context_and_is_closed_plus_AdoNet_calls() - { - using (new TransactionScope()) - { - var connection = new EntityConnection(connectionString); - AddLogEntryUsingAdoNet((SqlConnection)connection.StoreConnection); - - using (var ctx = CreateTransactionContext(connection)) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Closed, ctx.Connection.State); - } - } - - // Transaction not commited. No entities should be saved to the database. - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_outside_transaction_scope_and_is_closed() - { - var connection = new EntityConnection(connectionString); - using (new TransactionScope()) - { - using (var ctx = CreateTransactionContext(connection)) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Closed, ctx.Connection.State); - } - } - - // Transaction not commited. No entities should be saved to the database. - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_outside_transaction_scope_and_is_closed_plus_AdoNet_calls() - { - var connection = new EntityConnection(connectionString); - using (new TransactionScope()) - { - AddLogEntryUsingAdoNet((SqlConnection)connection.StoreConnection); - using (var ctx = CreateTransactionContext(connection)) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Closed, ctx.Connection.State); - } - } - - // Transaction not commited. No entities should be saved to the database. - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_only_one_transaction_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_outside_transaction_scope_and_is_closed_plus_AdoNet_calls_and_transaction_is_completed() - { - try - { - var connection = new EntityConnection(connectionString); - using (var transactionScope = new TransactionScope()) - { - AddLogEntryUsingAdoNet((SqlConnection)connection.StoreConnection); - using (var ctx = CreateTransactionContext(connection)) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - transactionScope.Complete(); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Closed, ctx.Connection.State); - } - } - - // verify that there are two entries (one for AdoNet and one for EF, but only one transaction - using (var ctx = CreateTransactionContext()) - { - var transactionCountEntries = ctx.LogEntries.Select(e => e.TransactionCount).OrderBy(c => c).ToList(); - Assert.Equal(2, transactionCountEntries.Count()); - Assert.Equal(-1, transactionCountEntries[0]); - Assert.Equal(1, transactionCountEntries[1]); - } - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_is_open() - { - using (new TransactionScope()) - { - using (var ctx = CreateTransactionContext()) - { - ctx.Connection.Open(); - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - } - - // Transaction not commited. No entities should be saved to the database. - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_outside_context_and_is_open() - { - using (new TransactionScope()) - { - var connection = new EntityConnection(connectionString); - connection.Open(); - using (var ctx = CreateTransactionContext(connection)) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - } - - // Transaction not commited. No entities should be saved to the database. - Assert.Equal(0, LogEntriesCount()); - } - - // What should be the correct behavior for this? See Issue #777 for details - ////[Fact] - ////public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_and_opened_outside_transaction_scope() - ////{ - //// try - //// { - //// var connection = new EntityConnection(connectionString); - //// connection.Open(); - //// using (var transactionScope = new TransactionScope()) - //// { - //// using (var ctx = CreateTransactionContext(connection)) - //// { - //// var transactionLogEntry = AddLogEntryToDatabase(ctx); - //// Assert.Equal(1, transactionLogEntry.TransactionCount); - //// Assert.Equal(ConnectionState.Open, ctx.Connection.State); - //// } - //// } - - //// // Transaction not commited. No entities should be saved to the database. - //// Assert.Equal(0, CreateTransactionContext().LogEntries.Count()); - //// } - //// finally - //// { - //// ResetTables(); - //// } - ////} - - // What should be the correct behavior for this? See Issue #777 for details - ////[Fact] - ////public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_and_opened_outside_transaction_scope_plus_AdoNet_calls() - ////{ - //// try - //// { - //// var connection = new EntityConnection(connectionString); - //// connection.Open(); - //// using (var transactionScope = new TransactionScope()) - //// { - //// // need to enlist store connection so that AdoNet calls execute inside a transaction - //// connection.StoreConnection.EnlistTransaction(Transaction.Current); - //// AddLogEntryUsingAdoNet((SqlConnection)connection.StoreConnection); - //// using (var ctx = CreateTransactionContext(connection)) - //// { - //// var transactionLogEntry = AddLogEntryToDatabase(ctx); - //// Assert.Equal(1, transactionLogEntry.TransactionCount); - //// Assert.Equal(ConnectionState.Open, ctx.Connection.State); - //// } - //// } - - //// // Transaction not commited. No entities should be saved to the database. - //// Assert.Equal(0, LogEntriesCount()); - //// } - //// finally - //// { - //// ResetTables(); - //// } - ////} - - // What should be the correct behavior for this? See Issue #777 for details - ////[Fact] - ////public void Verify_only_one_transaction_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_outside_transaction_scope_and_is_open_plus_AdoNet_calls_and_transaction_is_completed() - ////{ - //// try - //// { - //// var connection = new EntityConnection(connectionString); - //// connection.Open(); - //// using (var transactionScope = new TransactionScope()) - //// { - //// // need to enlist store connection so that AdoNet calls execute inside a transaction - //// connection.StoreConnection.EnlistTransaction(Transaction.Current); - //// AddLogEntryUsingAdoNet((SqlConnection)connection.StoreConnection); - //// using (var ctx = CreateTransactionContext(connection)) - //// { - //// var transactionLogEntry = AddLogEntryToDatabase(ctx); - //// transactionScope.Complete(); - //// Assert.Equal(1, transactionLogEntry.TransactionCount); - //// Assert.Equal(ConnectionState.Open, ctx.Connection.State); - //// } - //// } - - //// // verify that there are two entries (one for AdoNet and one for EF, but only one transaction - //// using (var ctx = CreateTransactionContext()) - //// { - //// var transactionCountEntries = ctx.LogEntries.Select(e => e.TransactionCount).OrderBy(c => c).ToList(); - //// Assert.Equal(2, transactionCountEntries.Count()); - //// Assert.Equal(-1, transactionCountEntries[0]); - //// Assert.Equal(1, transactionCountEntries[1]); - //// } - //// } - //// finally - //// { - //// ResetTables(); - //// } - ////} - - [Fact] - public void Verify_implicit_transaction_is_not_created_when_executing_multiple_operations_in_the_same_TransactionScope() - { - using (new TransactionScope()) - { - using (var ctx = CreateTransactionContext()) - { - ctx.Connection.Open(); - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - - transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - } - - // What should be the correct behavior for this? See Issue #777 for details - ////[Fact] - ////public void Verify_implicit_transaction_is_not_created_when_executing_multiple_operations_in_the_same_TransactionScope_and_connection_is_opened_outside_transaction_scope() - ////{ - //// try - //// { - //// var connection = new EntityConnection(connectionString); - //// connection.Open(); - //// using (var transactionScope = new TransactionScope()) - //// { - //// using (var ctx = CreateTransactionContext(connection)) - //// { - //// var transactionLogEntry = AddLogEntryToDatabase(ctx); - //// Assert.Equal(1, transactionLogEntry.TransactionCount); - //// Assert.Equal(ConnectionState.Open, ctx.Connection.State); - - //// transactionLogEntry = AddLogEntryToDatabase(ctx); - //// Assert.Equal(1, transactionLogEntry.TransactionCount); - //// Assert.Equal(ConnectionState.Open, ctx.Connection.State); - //// } - //// } - - //// // "Transaction not commited. No entities should be saved to the database." - //// Assert.Equal(0, LogEntriesCount()); - //// } - //// finally - //// { - //// ResetTables(); - //// } - ////} - - [Fact] - public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_explicitly_using_CommittableTransaction() - { - using (var ctx = CreateTransactionContext()) - { - ctx.Connection.Open(); - using (var committableTransaction = new CommittableTransaction()) - { - ctx.Connection.EnlistTransaction(committableTransaction); - - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_implicit_transaction_is_not_created_when_user_enlists_TransactionScope() - { - using (var ctx = CreateTransactionContext()) - { - ctx.Connection.Open(); - using (var transactionScope = new TransactionScope()) - { - ctx.Connection.EnlistTransaction(Transaction.Current); - - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_implicit_transaction_is_not_created_when_user_creates_ambient_CommittableTransaction() - { - using (var ctx = CreateTransactionContext()) - { - ctx.Connection.Open(); - using (var committableTransaction = new CommittableTransaction(new TimeSpan(1, 0, 0))) - { - ctx.Connection.EnlistTransaction(committableTransaction); - Transaction.Current = committableTransaction; - - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - - Transaction.Current = null; - } - } - - // Transaction not commited. No entities should be saved to the database. - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_implicit_transaction_is_not_created_when_user_starts_DbTransaction_explicitly() - { - using (var ctx = CreateTransactionContext()) - { - ctx.Connection.Open(); - using (var dbTransaction = ctx.Connection.BeginTransaction()) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_DbTransaction_cannot_be_mixed_with_TransactionScope() - { - try - { - using (var ctx = CreateTransactionContext()) - { - ctx.Connection.Open(); - using (var dbTransaction = ctx.Connection.BeginTransaction()) - { - using (var transactionScope = new TransactionScope()) - { - var transactionLogEntry = new TransactionLogEntry(); - ctx.AddObject("Entities.TransactionLog", transactionLogEntry); - - Assert.Equal( - Strings.EntityClient_ProviderSpecificError("EnlistTransaction"), - Assert.Throws(() => ctx.SaveChanges()).Message); - } - } - } - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_DbTransaction_cannot_be_mixed_with_CommittableTransaction() - { - try - { - using (var ctx = CreateTransactionContext()) - { - ctx.Connection.Open(); - using (var dbTransaction = ctx.Connection.BeginTransaction()) - { - using (var committableTransaction = new CommittableTransaction()) - { - Assert.Equal( - Strings.EntityClient_ProviderSpecificError("EnlistTransaction"), - Assert.Throws(() => ctx.Connection.EnlistTransaction(committableTransaction)).Message); - } - } - } - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_using_TransactionScope_with_DbTransaction_results_in_nested_transaction_and_implicit_transaction_not_created() - { - using (var ctx = CreateTransactionContext()) - { - using (new TransactionScope()) - { - ctx.Connection.Open(); - using (ctx.Connection.BeginTransaction()) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(2, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - } - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - } - - // What should be the correct behavior for this? See Issue #777 for details - ////[Fact] - ////public void Verify_using_TransactionScope_with_DbTransaction_results_in_nested_transaction_and_implicit_transaction_not_created_when_using_context_with_already_opened_connection() - ////{ - //// try - //// { - //// var connection = new EntityConnection(connectionString); - //// connection.Open(); - //// using (var ctx = CreateTransactionContext(connection)) - //// { - //// using (var transactionScope = new TransactionScope()) - //// { - //// // need to enlist connection here, otherwise test will fail - //// ctx.Connection.EnlistTransaction(Transaction.Current); - //// using (var dbTransaction = ctx.Connection.BeginTransaction()) - //// { - //// var transactionLogEntry = AddLogEntryToDatabase(ctx); - //// Assert.Equal(2, transactionLogEntry.TransactionCount); - //// Assert.Equal(ConnectionState.Open, ctx.Connection.State); - //// } - //// } - //// } - - //// // "Transaction not commited. No entities should be saved to the database." - //// Assert.Equal(0, LogEntriesCount()); - //// } - //// finally - //// { - //// ResetTables(); - //// } - ////} - - [Fact] - public void Verify_using_CommittableTransaction_with_DbTransaction_results_in_nested_transaction_and_implicit_transaction_not_created() - { - using (var ctx = CreateTransactionContext()) - { - ctx.Connection.Open(); - using (var committableTransaction = new CommittableTransaction()) - { - ctx.Connection.EnlistTransaction(committableTransaction); - - using (ctx.Connection.BeginTransaction()) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(2, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - } - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_TransactionScope_cannot_be_mixed_with_CommitableTransaction() - { - try - { - using (var ctx = CreateTransactionContext()) - { - using (var transactionScope = new TransactionScope()) - { - ctx.Connection.Open(); - using (var committableTransaction = new CommittableTransaction()) - { - Assert.Equal( - Strings.EntityClient_ProviderSpecificError("EnlistTransaction"), - Assert.Throws(() => ctx.Connection.EnlistTransaction(committableTransaction)).Message); - } - } - } - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_CommitableTransaction_cannot_be_mixed_with_TransactionScope() - { - try - { - using (var ctx = CreateTransactionContext()) - { - ctx.Connection.Open(); - using (var committableTransaction = new CommittableTransaction()) - { - ctx.Connection.EnlistTransaction(committableTransaction); - using (var transactionScope = new TransactionScope()) - { - var transactionLogEntry = new TransactionLogEntry(); - ctx.AddObject("Entities.TransactionLog", transactionLogEntry); - - Assert.Equal( - Strings.EntityClient_ProviderSpecificError("EnlistTransaction"), - Assert.Throws(() => ctx.SaveChanges()).Message); - } - } - } - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_implicit_transaction_created_when_transaction_from_previous_operation_disposed_and_connection_opened() - { - try - { - using (var ctx = CreateObjectContext()) - { - ctx.Connection.Open(); - using (var transactionScope = new TransactionScope()) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - - AddLogEntryToDatabase(ctx); - - // "Implicit transaction committed. 1 entity expected." - Assert.Equal(1, LogEntriesCount()); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_no_implicit_transaction_created_when_if_enlisted_in_explicit_transaction_after_transaction_from_previous_operation_disposed() - { - using (var ctx = CreateObjectContext()) - { - ctx.Connection.Open(); - using (new TransactionScope()) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - - using (var committableTransaction = new CommittableTransaction()) - { - ctx.Connection.EnlistTransaction(committableTransaction); - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - } - } - - [Fact] - public void Verify_implicit_transaction_created_when_transaction_from_previous_operation_disposed_and_connection_closed() - { - try - { - using (var ctx = CreateObjectContext()) - { - using (var transactionScope = new TransactionScope()) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Closed, ctx.Connection.State); - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - - var newTransactionLogEntry = AddLogEntryToDatabase(ctx); - - // "Implicit transaction committed. 1 entity expected." - Assert.Equal(1, LogEntriesCount()); - Assert.Equal(ConnectionState.Closed, ctx.Connection.State); - } - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_explicit_transaction_cleared_after_disposing() - { - try - { - using (var ctx = CreateObjectContext()) - { - ctx.Connection.Open(); - - using (var committableTransaction = new CommittableTransaction()) - { - ctx.Connection.EnlistTransaction(committableTransaction); - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, CreateTransactionContext().LogEntries.Count()); - - var newTransactionLogEntry = AddLogEntryToDatabase(ctx); - - // "Implicit transaction committed. 1 entity expected." - Assert.Equal(1, CreateTransactionContext().LogEntries.Count()); - } - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_no_implicit_transaction_created_when_transactions_change_between_requests() - { - using (var ctx = CreateObjectContext()) - { - ctx.Connection.Open(); - - using (var transaction1 = new TransactionScope()) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - - using (var transaction2 = new TransactionScope()) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_no_implicit_transaction_created_when_enlisting_in_transaction_between_requests() - { - using (var ctx = CreateObjectContext()) - { - ctx.Connection.Open(); - - using (var transaction1 = new TransactionScope()) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - - using (var committableTransaction = new CommittableTransaction()) - { - ctx.Connection.EnlistTransaction(committableTransaction); - - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Open, ctx.Connection.State); - } - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_no_implicit_transaction_created_when_transaction_change_and_connection_is_closed_between_requests() - { - using (var ctx = CreateObjectContext()) - { - ctx.Connection.Open(); - - using (var trx = new TransactionScope()) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - ctx.Connection.Close(); - } - - using (var trx = new TransactionScope()) - { - var transactionLogEntry = AddLogEntryToDatabase(ctx); - Assert.Equal(1, transactionLogEntry.TransactionCount); - Assert.Equal(ConnectionState.Closed, ctx.Connection.State); - } - } - - // "Transaction not commited. No entities should be saved to the database." - Assert.Equal(0, LogEntriesCount()); - } - - [Fact] - public void Verify_cannot_enlist_in_more_than_one_active_transaction_on_the_same_opened_connection() - { - try - { - using (var ctx = CreateTransactionContext()) - { - ctx.Connection.Open(); - using (var committableTransaction = new CommittableTransaction()) - { - using (var newCommittableTransaction = new CommittableTransaction()) - { - ctx.Connection.EnlistTransaction(committableTransaction); - - Assert.Equal( - Strings.EntityClient_ProviderSpecificError("EnlistTransaction"), - Assert.Throws(() => ctx.Connection.EnlistTransaction(newCommittableTransaction)).Message); - } - } - } - } - finally - { - ResetTables(); - } - } - - [Fact] - public void Verify_closing_connection_invalidates_explicit_transaction() - { - try - { - using (var ctx = CreateTransactionContext()) - { - ctx.Connection.Open(); - using (var committableTransaction = new CommittableTransaction()) - { - ctx.Connection.EnlistTransaction(committableTransaction); - ctx.Connection.Close(); - - ctx.Connection.Open(); - using (var newCommittableTransaction = new CommittableTransaction()) - { - ctx.Connection.EnlistTransaction(newCommittableTransaction); - } - } - } - } - finally - { - ResetTables(); - } - } - - private TransactionContext CreateTransactionContext() - { - var ctx = new TransactionContext(connectionString); - ctx.MetadataWorkspace.LoadFromAssembly(Assembly.GetExecutingAssembly()); - - return ctx; - } - - private TransactionContext CreateTransactionContext(EntityConnection connection) - { - var ctx = new TransactionContext(connection); - ctx.MetadataWorkspace.LoadFromAssembly(Assembly.GetExecutingAssembly()); - - return ctx; - } - - private ObjectContext CreateObjectContext() - { - var ctx = new ObjectContext(connectionString); - ctx.MetadataWorkspace.LoadFromAssembly(Assembly.GetExecutingAssembly()); - - return ctx; - } - - private ObjectContext CreateObjectContext(EntityConnection connection) - { - var ctx = new ObjectContext(connection); - ctx.MetadataWorkspace.LoadFromAssembly(Assembly.GetExecutingAssembly()); - - return ctx; - } - - private TransactionDbContext CreateTransactionDbContext() - { - var ctx = new TransactionDbContext(connectionString); - - return ctx; - } - - private TransactionDbContext CreateTransactionDbContext(EntityConnection connection, bool contextOwnsConnection) - { - var ctx = new TransactionDbContext(connection, contextOwnsConnection); - - return ctx; - } - - private TransactionDbContext CreateTransactionDbContext(SqlConnection connection, DbCompiledModel compiledModel, bool contextOwnsConnection) - { - var ctx = new TransactionDbContext(connection, compiledModel, contextOwnsConnection); - - return ctx; - } - - private int LogEntriesCount() - { - using (var ctx = CreateTransactionContext()) - { - return ctx.LogEntries.Count(); - } - } - - private int LogEntriesCount(EntityConnection connection) - { - using (var ctx = CreateTransactionContext(connection)) - { - return ctx.LogEntries.Count(); - } - } - - private TransactionLogEntry AddLogEntryToDatabase(ObjectContext ctx) - { - var transactionLogEntry = new TransactionLogEntry(); - ctx.AddObject("Entities.TransactionLog", transactionLogEntry); - ctx.SaveChanges(); - - return transactionLogEntry; - } - - private TransactionLogEntry AddLogEntryToDatabase(TransactionDbContext ctx) - { - var transactionLogEntry = new TransactionLogEntry(); - ctx.LogEntries.Add(transactionLogEntry); - ctx.SaveChanges(); - - return transactionLogEntry; - } - - private void AddLogEntryUsingAdoNet(SqlConnection connection) - { - bool shouldCloseConnection = false; - if (connection.State == ConnectionState.Closed) - { - connection.Open(); - shouldCloseConnection = true; - } - - var command = new SqlCommand(); - command.Connection = connection; - command.CommandText = @"INSERT INTO ##TransactionLog Values(-1)"; - command.ExecuteNonQuery(); - - if (shouldCloseConnection) - { - connection.Close(); - } - } - - /// - /// Removes all entries from the tables used for tests. Must be called from tests that are committing transactions - /// as each test expects that the db will be initially clean. - /// - private void ResetTables() - { - new SqlCommand("DELETE FROM ##TransactionLog", globalConnection).ExecuteNonQuery(); - Assert.Equal(0, CreateTransactionContext().LogEntries.Count()); - } - } - - public class TransactionFixture : FunctionalTestBase, IDisposable - { - public SqlConnection GlobalConnection { get; private set; } - public DbCompiledModel CompiledModel { get; private set; } - - public TransactionFixture() - { - if (GlobalConnection != null) - { - throw new InvalidOperationException("Database is still in use and cannot be initialized."); - } - - // we are using tempdb and SQLExpress instance so we don't want this to be configurable - GlobalConnection = new SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=tempdb;Integrated Security=SSPI;"); - GlobalConnection.Open(); - - try - { - new SqlCommand( - @" - CREATE TABLE [dbo].[##TransactionLog]( - [ID] [int] IDENTITY(1,1) NOT NULL, - [TransactionCount] [int] NOT NULL, - CONSTRAINT [PK_TransactionLog] PRIMARY KEY CLUSTERED - ( - [ID] ASC - )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] - ) ON [PRIMARY]", GlobalConnection).ExecuteNonQuery(); - - new SqlCommand( - @" - CREATE PROCEDURE [dbo].[##CreateTransactionLogEntry] - AS - BEGIN - DECLARE @tranCount AS int = @@TRANCOUNT -- assigning to a variable prevents from counting an implicit transaction created for insert - INSERT INTO ##TransactionLog Values(@tranCount) - SELECT ID, TransactionCount - FROM ##TransactionLog - WHERE ID = SCOPE_IDENTITY() - END", GlobalConnection).ExecuteNonQuery(); - - CompiledModel = BuildCompiledModel(); - } - catch - { - CleanupDatabase(); - - throw; - } - } - - private DbCompiledModel BuildCompiledModel() - { - // hack - we have to create context that uses StoredProcedure to for inserts. DbModelBuilder does not support that. - // Instead, we use reflection to inject MetadataWorkspace created using csdl/ssdl/msl into a DbCompiledModel - var connectionString = string.Format( - @"metadata=res://EntityFramework.FunctionalTests/System.Data.Entity.Objects.TransactionsModel.csdl|res://EntityFramework.FunctionalTests/System.Data.Entity.Objects.TransactionsModel.ssdl|res://EntityFramework.FunctionalTests/System.Data.Entity.Objects.TransactionsModel.msl;provider=System.Data.SqlClient;provider connection string=""{0}""", - ModelHelpers.SimpleConnectionString("tempdb")); - - var ctx = new TransactionDbContext(connectionString); - ctx.LogEntries.Count(); - var objectContext = ((IObjectContextAdapter)ctx).ObjectContext; - - DbModelBuilder builder = new DbModelBuilder(); - builder.Entity(typeof(TransactionLogEntry)).ToTable("##TransactionLog"); - builder.HasDefaultSchema("tempdbModel"); - builder.Conventions.Add(new ModelContainerConvention("Entities")); - - - var model = builder.Build(ctx.Database.Connection); - var compiledModel = model.Compile(); - var cachedMetadataWorkspaceFieldInfo = compiledModel.GetType().GetField("_workspace", BindingFlags.Instance | BindingFlags.NonPublic); - var cachedMetadataWorkspace = cachedMetadataWorkspaceFieldInfo.GetValue(compiledModel); - var metadataWorkspaceFieldInfo = cachedMetadataWorkspace.GetType().GetField("_metadataWorkspace", BindingFlags.Instance | BindingFlags.NonPublic); - metadataWorkspaceFieldInfo.SetValue(cachedMetadataWorkspace, objectContext.MetadataWorkspace); - - return compiledModel; - } - - private void CleanupDatabase() - { - Debug.Assert(GlobalConnection != null); - - GlobalConnection.Close(); - GlobalConnection.Dispose(); - GlobalConnection = null; - } - - public void Dispose() - { - CleanupDatabase(); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Objects +{ + using System.Data.Common; + using System.Data.Entity.Core; + using System.Data.Entity.Core.EntityClient; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.Core.Objects; + using System.Data.Entity.Infrastructure; + using System.Data.Entity.Resources; + using System.Data.SqlClient; + using System.Diagnostics; + using System.Linq; + using System.Reflection; + using System.Transactions; + using Xunit; + + public class TransactionLogEntry + { + public int ID { get; set; } + public int TransactionCount { get; set; } + } + + public class TransactionContext : ObjectContext + { + public TransactionContext(string connectionString) + : base(connectionString) + { + } + + public TransactionContext(EntityConnection connection) + : base(connection) + { + } + + public IQueryable LogEntries + { + get { return CreateObjectSet("Entities.TransactionLog"); } + } + } + + public class TransactionDbContext : DbContext + { + public TransactionDbContext(string connectionString) + : base(connectionString) + { + } + + public TransactionDbContext(EntityConnection connection, bool contextOwnsConnection) + : base(connection, contextOwnsConnection) + { + } + + public TransactionDbContext(SqlConnection connection, DbCompiledModel model, bool contextOwnsConnection) + : base(connection, model, contextOwnsConnection) + { + } + + public DbSet LogEntries { get; set; } + } + + public class TransactionsTests : FunctionalTestBase, IUseFixture + { + private string connectionString; + private string modelDirectory; + + private MetadataWorkspace workspace; + private SqlConnection globalConnection; + private DbCompiledModel compiledModel; + + public void SetFixture(TransactionFixture data) + { + globalConnection = data.GlobalConnection; + compiledModel = data.CompiledModel; + + connectionString = string.Format( + @"metadata=res://EntityFramework.FunctionalTests.Transitional/System.Data.Entity.Objects.TransactionsModel.csdl|res://EntityFramework.FunctionalTests.Transitional/System.Data.Entity.Objects.TransactionsModel.ssdl|res://EntityFramework.FunctionalTests.Transitional/System.Data.Entity.Objects.TransactionsModel.msl;provider=System.Data.SqlClient;provider connection string=""{0}""", + ModelHelpers.SimpleConnectionString("tempdb")); + } + + [Fact] + public void Verify_implicit_transaction_is_created_when_using_DbContext_and_no_transaction_created_by_user_and_connection_is_closed() + { + try + { + using (var ctx = CreateTransactionDbContext()) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + + // Implicit transaction committed. 1 entity expected. + Assert.Equal(1, LogEntriesCount()); + Assert.Equal(ConnectionState.Closed, ctx.Database.Connection.State); + } + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_implicit_transaction_is_created_when_using_DbContext_and_no_transaction_created_by_user_and_EntityConnection_is_opened_and_context_owns_connection() + { + try + { + var entityConnection = new EntityConnection(connectionString); + entityConnection.Open(); + + using (var ctx = CreateTransactionDbContext(entityConnection, contextOwnsConnection: true)) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + + // Implicit transaction committed. 1 entity expected. + Assert.Equal(1, LogEntriesCount()); + Assert.Equal(ConnectionState.Open, ctx.Database.Connection.State); + } + + Assert.Equal(ConnectionState.Closed, entityConnection.State); + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_implicit_transaction_is_created_when_using_DbContext_and_no_transaction_created_by_user_and_EntityConnection_is_opened_and_context_does_not_own_connection() + { + try + { + var entityConnection = new EntityConnection(connectionString); + entityConnection.Open(); + using (var ctx = CreateTransactionDbContext(entityConnection, contextOwnsConnection: false)) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + + // Implicit transaction committed. 1 entity expected. + Assert.Equal(1, LogEntriesCount()); + } + + Assert.Equal(ConnectionState.Open, entityConnection.StoreConnection.State); + Assert.Equal(ConnectionState.Open, entityConnection.State); + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_implicit_transaction_is_created_when_using_DbContext_and_no_transaction_created_by_user_and_SqlConnection_is_opened_and_context_owns_connection() + { + try + { + var sqlConnection = new SqlConnection(globalConnection.ConnectionString); + sqlConnection.Open(); + + using (var ctx = CreateTransactionDbContext(sqlConnection, compiledModel, contextOwnsConnection: true)) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + + // Implicit transaction committed. 1 entity expected. + Assert.Equal(1, LogEntriesCount()); + Assert.Equal(ConnectionState.Open, ctx.Database.Connection.State); + } + + Assert.Equal(ConnectionState.Closed, sqlConnection.State); + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_implicit_transaction_is_created_when_using_DbContext_and_no_transaction_created_by_user_and_SqlConnection_is_opened_and_context_does_not_own_connection() + { + try + { + var sqlConnection = new SqlConnection(globalConnection.ConnectionString); + sqlConnection.Open(); + + using (var ctx = CreateTransactionDbContext(sqlConnection, compiledModel, contextOwnsConnection: false)) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + + // Implicit transaction committed. 1 entity expected. + Assert.Equal(1, LogEntriesCount()); + } + + Assert.Equal(ConnectionState.Open, sqlConnection.State); + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_implicit_transaction_is_not_created_when_using_DbContext_and_user_creates_transaction_using_TransactionScope_and_EntityConnection_is_closed() + { + var entityConnection = new EntityConnection(connectionString); + using (new TransactionScope()) + { + using (var ctx = CreateTransactionDbContext(entityConnection, true)) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + } + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_implicit_transaction_is_not_created_when_using_DbContext_and_user_creates_transaction_using_TransactionScope_and_SqlConnection_is_closed() + { + var connection = new SqlConnection(globalConnection.ConnectionString); + using (new TransactionScope()) + { + using (var ctx = CreateTransactionDbContext(connection, compiledModel, contextOwnsConnection: true)) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + } + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_implicit_transaction_is_not_created_when_using_DbContext_and_user_creates_transaction_using_TransactionScope_and_EntityConnection_is_opened_inside_transaction_scope() + { + var connection = new EntityConnection(connectionString); + using (new TransactionScope()) + { + connection.Open(); + using (var ctx = CreateTransactionDbContext(connection, contextOwnsConnection: true)) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + } + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + } + + // Fails for now - MSDTC on server 'MAUMARDEV\SQLEXPRESS' is unavailable. See Issue #771 for details + ////[Fact] + ////public void Verify_implicit_transaction_is_not_created_when_using_DbContext_and_user_creates_transaction_using_TransactionScope_and_connection_is_opened_inside_transaction_scope() + ////{ + //// try + //// { + //// var connection = new SqlConnection(globalConnection.ConnectionString); + //// using (var transactionScope = new TransactionScope()) + //// { + //// connection.Open(); + //// using (var ctx = CreateTransactionDbContext(connection, compiledModel, contextOwnsConnection: true)) + //// { + //// var transactionLogEntry = AddLogEntryToDatabase(ctx); + //// Assert.Equal(1, transactionLogEntry.TransactionCount); + //// } + //// } + + //// // "Transaction not commited. No entities should be saved to the database." + //// Assert.Equal(0, LogEntriesCount()); + //// } + //// finally + //// { + //// ResetTables(); + //// } + ////} + + // What should be the correct behavior for this? See Issue #777 for details + ////[Fact] + ////public void Verify_implicit_transaction_is_not_created_when_using_DbContext_and_user_creates_transaction_using_TransactionScope_and_EntityConnection_is_opened_outside_transaction_scope() + ////{ + //// try + //// { + //// var entityConnection = new EntityConnection(connectionString); + //// entityConnection.Open(); + //// using (var transactionScope = new TransactionScope()) + //// { + //// using (var ctx = CreateTransactionDbContext(entityConnection, contextOwnsConnection: true)) + //// { + //// var transactionLogEntry = AddLogEntryToDatabase(ctx); + //// Assert.Equal(1, transactionLogEntry.TransactionCount); + //// } + //// } + + //// // "Transaction not commited. No entities should be saved to the database." + //// Assert.Equal(0, LogEntriesCount()); + //// } + //// finally + //// { + //// ResetTables(); + //// } + ////} + + // Fails for now - MSDTC on server 'MAUMARDEV\SQLEXPRESS' is unavailable. See Issue #771 for details + ////[Fact] + ////public void Verify_implicit_transaction_is_not_created_when_using_DbContext_and_user_creates_transaction_using_TransactionScope_and_connection_is_opened_outside_transaction_scope() + ////{ + //// try + //// { + //// var connection = new SqlConnection(globalConnection.ConnectionString); + + //// connection.Open(); + //// using (var transactionScope = new TransactionScope()) + //// { + //// using (var ctx = CreateTransactionDbContext(connection, compiledModel, contextOwnsConnection: true)) + //// { + //// var transactionLogEntry = AddLogEntryToDatabase(ctx); + //// Assert.Equal(1, transactionLogEntry.TransactionCount); + //// } + //// } + + //// // "Transaction not commited. No entities should be saved to the database." + //// Assert.Equal(0, LogEntriesCount()); + //// } + //// finally + //// { + //// ResetTables(); + //// } + ////} + + [Fact] + public void Verify_implicit_transaction_is_created_when_no_transaction_created_by_user_and_connection_is_closed() + { + try + { + using (var ctx = CreateTransactionContext()) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + + // Implicit transaction committed. 1 entity expected. + Assert.Equal(1, LogEntriesCount()); + Assert.Equal(ConnectionState.Closed, ctx.Connection.State); + } + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_implicit_transaction_is_created_when_no_transaction_created_by_user_and_connection_is_created_outside_context_and_is_closed() + { + try + { + var connection = new EntityConnection(connectionString); + using (var ctx = CreateTransactionContext(connection)) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + + // Implicit transaction committed. 1 entity expected. + Assert.Equal(1, LogEntriesCount(connection)); + Assert.Equal(ConnectionState.Closed, ctx.Connection.State); + } + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_implicit_transaction_is_created_when_no_transaction_created_by_user_and_connection_is_open() + { + try + { + using (var ctx = CreateTransactionContext()) + { + ctx.Connection.Open(); + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + + // Implicit transaction committed. 1 entity expected. + Assert.Equal(1, LogEntriesCount()); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_implicit_transaction_is_created_when_no_transaction_created_by_user_and_connection_is_created_outside_context_and_is_open() + { + try + { + var connection = new EntityConnection(connectionString); + connection.Open(); + using (var ctx = CreateTransactionContext(connection)) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + + // Implicit transaction committed. 1 entity expected. + Assert.Equal(1, LogEntriesCount(connection)); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_is_closed() + { + using (new TransactionScope()) + { + using (var ctx = CreateTransactionContext()) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Closed, ctx.Connection.State); + } + } + + // Transaction not commited. No entities should be saved to the database. + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_outside_context_and_is_closed() + { + using (new TransactionScope()) + { + var connection = new EntityConnection(connectionString); + using (var ctx = CreateTransactionContext(connection)) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Closed, ctx.Connection.State); + } + } + + // Transaction not commited. No entities should be saved to the database. + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_outside_context_and_is_closed_plus_AdoNet_calls() + { + using (new TransactionScope()) + { + var connection = new EntityConnection(connectionString); + AddLogEntryUsingAdoNet((SqlConnection)connection.StoreConnection); + + using (var ctx = CreateTransactionContext(connection)) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Closed, ctx.Connection.State); + } + } + + // Transaction not commited. No entities should be saved to the database. + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_outside_transaction_scope_and_is_closed() + { + var connection = new EntityConnection(connectionString); + using (new TransactionScope()) + { + using (var ctx = CreateTransactionContext(connection)) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Closed, ctx.Connection.State); + } + } + + // Transaction not commited. No entities should be saved to the database. + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_outside_transaction_scope_and_is_closed_plus_AdoNet_calls() + { + var connection = new EntityConnection(connectionString); + using (new TransactionScope()) + { + AddLogEntryUsingAdoNet((SqlConnection)connection.StoreConnection); + using (var ctx = CreateTransactionContext(connection)) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Closed, ctx.Connection.State); + } + } + + // Transaction not commited. No entities should be saved to the database. + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_only_one_transaction_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_outside_transaction_scope_and_is_closed_plus_AdoNet_calls_and_transaction_is_completed() + { + try + { + var connection = new EntityConnection(connectionString); + using (var transactionScope = new TransactionScope()) + { + AddLogEntryUsingAdoNet((SqlConnection)connection.StoreConnection); + using (var ctx = CreateTransactionContext(connection)) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + transactionScope.Complete(); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Closed, ctx.Connection.State); + } + } + + // verify that there are two entries (one for AdoNet and one for EF, but only one transaction + using (var ctx = CreateTransactionContext()) + { + var transactionCountEntries = ctx.LogEntries.Select(e => e.TransactionCount).OrderBy(c => c).ToList(); + Assert.Equal(2, transactionCountEntries.Count()); + Assert.Equal(-1, transactionCountEntries[0]); + Assert.Equal(1, transactionCountEntries[1]); + } + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_is_open() + { + using (new TransactionScope()) + { + using (var ctx = CreateTransactionContext()) + { + ctx.Connection.Open(); + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + } + + // Transaction not commited. No entities should be saved to the database. + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_outside_context_and_is_open() + { + using (new TransactionScope()) + { + var connection = new EntityConnection(connectionString); + connection.Open(); + using (var ctx = CreateTransactionContext(connection)) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + } + + // Transaction not commited. No entities should be saved to the database. + Assert.Equal(0, LogEntriesCount()); + } + + // What should be the correct behavior for this? See Issue #777 for details + ////[Fact] + ////public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_and_opened_outside_transaction_scope() + ////{ + //// try + //// { + //// var connection = new EntityConnection(connectionString); + //// connection.Open(); + //// using (var transactionScope = new TransactionScope()) + //// { + //// using (var ctx = CreateTransactionContext(connection)) + //// { + //// var transactionLogEntry = AddLogEntryToDatabase(ctx); + //// Assert.Equal(1, transactionLogEntry.TransactionCount); + //// Assert.Equal(ConnectionState.Open, ctx.Connection.State); + //// } + //// } + + //// // Transaction not commited. No entities should be saved to the database. + //// Assert.Equal(0, CreateTransactionContext().LogEntries.Count()); + //// } + //// finally + //// { + //// ResetTables(); + //// } + ////} + + // What should be the correct behavior for this? See Issue #777 for details + ////[Fact] + ////public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_and_opened_outside_transaction_scope_plus_AdoNet_calls() + ////{ + //// try + //// { + //// var connection = new EntityConnection(connectionString); + //// connection.Open(); + //// using (var transactionScope = new TransactionScope()) + //// { + //// // need to enlist store connection so that AdoNet calls execute inside a transaction + //// connection.StoreConnection.EnlistTransaction(Transaction.Current); + //// AddLogEntryUsingAdoNet((SqlConnection)connection.StoreConnection); + //// using (var ctx = CreateTransactionContext(connection)) + //// { + //// var transactionLogEntry = AddLogEntryToDatabase(ctx); + //// Assert.Equal(1, transactionLogEntry.TransactionCount); + //// Assert.Equal(ConnectionState.Open, ctx.Connection.State); + //// } + //// } + + //// // Transaction not commited. No entities should be saved to the database. + //// Assert.Equal(0, LogEntriesCount()); + //// } + //// finally + //// { + //// ResetTables(); + //// } + ////} + + // What should be the correct behavior for this? See Issue #777 for details + ////[Fact] + ////public void Verify_only_one_transaction_created_when_user_creates_transaction_using_TransactionScope_and_connection_created_outside_transaction_scope_and_is_open_plus_AdoNet_calls_and_transaction_is_completed() + ////{ + //// try + //// { + //// var connection = new EntityConnection(connectionString); + //// connection.Open(); + //// using (var transactionScope = new TransactionScope()) + //// { + //// // need to enlist store connection so that AdoNet calls execute inside a transaction + //// connection.StoreConnection.EnlistTransaction(Transaction.Current); + //// AddLogEntryUsingAdoNet((SqlConnection)connection.StoreConnection); + //// using (var ctx = CreateTransactionContext(connection)) + //// { + //// var transactionLogEntry = AddLogEntryToDatabase(ctx); + //// transactionScope.Complete(); + //// Assert.Equal(1, transactionLogEntry.TransactionCount); + //// Assert.Equal(ConnectionState.Open, ctx.Connection.State); + //// } + //// } + + //// // verify that there are two entries (one for AdoNet and one for EF, but only one transaction + //// using (var ctx = CreateTransactionContext()) + //// { + //// var transactionCountEntries = ctx.LogEntries.Select(e => e.TransactionCount).OrderBy(c => c).ToList(); + //// Assert.Equal(2, transactionCountEntries.Count()); + //// Assert.Equal(-1, transactionCountEntries[0]); + //// Assert.Equal(1, transactionCountEntries[1]); + //// } + //// } + //// finally + //// { + //// ResetTables(); + //// } + ////} + + [Fact] + public void Verify_implicit_transaction_is_not_created_when_executing_multiple_operations_in_the_same_TransactionScope() + { + using (new TransactionScope()) + { + using (var ctx = CreateTransactionContext()) + { + ctx.Connection.Open(); + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + + transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + } + + // What should be the correct behavior for this? See Issue #777 for details + ////[Fact] + ////public void Verify_implicit_transaction_is_not_created_when_executing_multiple_operations_in_the_same_TransactionScope_and_connection_is_opened_outside_transaction_scope() + ////{ + //// try + //// { + //// var connection = new EntityConnection(connectionString); + //// connection.Open(); + //// using (var transactionScope = new TransactionScope()) + //// { + //// using (var ctx = CreateTransactionContext(connection)) + //// { + //// var transactionLogEntry = AddLogEntryToDatabase(ctx); + //// Assert.Equal(1, transactionLogEntry.TransactionCount); + //// Assert.Equal(ConnectionState.Open, ctx.Connection.State); + + //// transactionLogEntry = AddLogEntryToDatabase(ctx); + //// Assert.Equal(1, transactionLogEntry.TransactionCount); + //// Assert.Equal(ConnectionState.Open, ctx.Connection.State); + //// } + //// } + + //// // "Transaction not commited. No entities should be saved to the database." + //// Assert.Equal(0, LogEntriesCount()); + //// } + //// finally + //// { + //// ResetTables(); + //// } + ////} + + [Fact] + public void Verify_implicit_transaction_is_not_created_when_user_creates_transaction_explicitly_using_CommittableTransaction() + { + using (var ctx = CreateTransactionContext()) + { + ctx.Connection.Open(); + using (var committableTransaction = new CommittableTransaction()) + { + ctx.Connection.EnlistTransaction(committableTransaction); + + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_implicit_transaction_is_not_created_when_user_enlists_TransactionScope() + { + using (var ctx = CreateTransactionContext()) + { + ctx.Connection.Open(); + using (var transactionScope = new TransactionScope()) + { + ctx.Connection.EnlistTransaction(Transaction.Current); + + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_implicit_transaction_is_not_created_when_user_creates_ambient_CommittableTransaction() + { + using (var ctx = CreateTransactionContext()) + { + ctx.Connection.Open(); + using (var committableTransaction = new CommittableTransaction(new TimeSpan(1, 0, 0))) + { + ctx.Connection.EnlistTransaction(committableTransaction); + Transaction.Current = committableTransaction; + + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + + Transaction.Current = null; + } + } + + // Transaction not commited. No entities should be saved to the database. + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_implicit_transaction_is_not_created_when_user_starts_DbTransaction_explicitly() + { + using (var ctx = CreateTransactionContext()) + { + ctx.Connection.Open(); + using (var dbTransaction = ctx.Connection.BeginTransaction()) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_DbTransaction_cannot_be_mixed_with_TransactionScope() + { + try + { + using (var ctx = CreateTransactionContext()) + { + ctx.Connection.Open(); + using (var dbTransaction = ctx.Connection.BeginTransaction()) + { + using (var transactionScope = new TransactionScope()) + { + var transactionLogEntry = new TransactionLogEntry(); + ctx.AddObject("Entities.TransactionLog", transactionLogEntry); + + Assert.Equal( + Strings.EntityClient_ProviderSpecificError("EnlistTransaction"), + Assert.Throws(() => ctx.SaveChanges()).Message); + } + } + } + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_DbTransaction_cannot_be_mixed_with_CommittableTransaction() + { + try + { + using (var ctx = CreateTransactionContext()) + { + ctx.Connection.Open(); + using (var dbTransaction = ctx.Connection.BeginTransaction()) + { + using (var committableTransaction = new CommittableTransaction()) + { + Assert.Equal( + Strings.EntityClient_ProviderSpecificError("EnlistTransaction"), + Assert.Throws(() => ctx.Connection.EnlistTransaction(committableTransaction)).Message); + } + } + } + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_using_TransactionScope_with_DbTransaction_results_in_nested_transaction_and_implicit_transaction_not_created() + { + using (var ctx = CreateTransactionContext()) + { + using (new TransactionScope()) + { + ctx.Connection.Open(); + using (ctx.Connection.BeginTransaction()) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(2, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + } + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + } + + // What should be the correct behavior for this? See Issue #777 for details + ////[Fact] + ////public void Verify_using_TransactionScope_with_DbTransaction_results_in_nested_transaction_and_implicit_transaction_not_created_when_using_context_with_already_opened_connection() + ////{ + //// try + //// { + //// var connection = new EntityConnection(connectionString); + //// connection.Open(); + //// using (var ctx = CreateTransactionContext(connection)) + //// { + //// using (var transactionScope = new TransactionScope()) + //// { + //// // need to enlist connection here, otherwise test will fail + //// ctx.Connection.EnlistTransaction(Transaction.Current); + //// using (var dbTransaction = ctx.Connection.BeginTransaction()) + //// { + //// var transactionLogEntry = AddLogEntryToDatabase(ctx); + //// Assert.Equal(2, transactionLogEntry.TransactionCount); + //// Assert.Equal(ConnectionState.Open, ctx.Connection.State); + //// } + //// } + //// } + + //// // "Transaction not commited. No entities should be saved to the database." + //// Assert.Equal(0, LogEntriesCount()); + //// } + //// finally + //// { + //// ResetTables(); + //// } + ////} + + [Fact] + public void Verify_using_CommittableTransaction_with_DbTransaction_results_in_nested_transaction_and_implicit_transaction_not_created() + { + using (var ctx = CreateTransactionContext()) + { + ctx.Connection.Open(); + using (var committableTransaction = new CommittableTransaction()) + { + ctx.Connection.EnlistTransaction(committableTransaction); + + using (ctx.Connection.BeginTransaction()) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(2, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + } + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_TransactionScope_cannot_be_mixed_with_CommitableTransaction() + { + try + { + using (var ctx = CreateTransactionContext()) + { + using (var transactionScope = new TransactionScope()) + { + ctx.Connection.Open(); + using (var committableTransaction = new CommittableTransaction()) + { + Assert.Equal( + Strings.EntityClient_ProviderSpecificError("EnlistTransaction"), + Assert.Throws(() => ctx.Connection.EnlistTransaction(committableTransaction)).Message); + } + } + } + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_CommitableTransaction_cannot_be_mixed_with_TransactionScope() + { + try + { + using (var ctx = CreateTransactionContext()) + { + ctx.Connection.Open(); + using (var committableTransaction = new CommittableTransaction()) + { + ctx.Connection.EnlistTransaction(committableTransaction); + using (var transactionScope = new TransactionScope()) + { + var transactionLogEntry = new TransactionLogEntry(); + ctx.AddObject("Entities.TransactionLog", transactionLogEntry); + + Assert.Equal( + Strings.EntityClient_ProviderSpecificError("EnlistTransaction"), + Assert.Throws(() => ctx.SaveChanges()).Message); + } + } + } + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_implicit_transaction_created_when_transaction_from_previous_operation_disposed_and_connection_opened() + { + try + { + using (var ctx = CreateObjectContext()) + { + ctx.Connection.Open(); + using (var transactionScope = new TransactionScope()) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + + AddLogEntryToDatabase(ctx); + + // "Implicit transaction committed. 1 entity expected." + Assert.Equal(1, LogEntriesCount()); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_no_implicit_transaction_created_when_if_enlisted_in_explicit_transaction_after_transaction_from_previous_operation_disposed() + { + using (var ctx = CreateObjectContext()) + { + ctx.Connection.Open(); + using (new TransactionScope()) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + + using (var committableTransaction = new CommittableTransaction()) + { + ctx.Connection.EnlistTransaction(committableTransaction); + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + } + } + + [Fact] + public void Verify_implicit_transaction_created_when_transaction_from_previous_operation_disposed_and_connection_closed() + { + try + { + using (var ctx = CreateObjectContext()) + { + using (var transactionScope = new TransactionScope()) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Closed, ctx.Connection.State); + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + + var newTransactionLogEntry = AddLogEntryToDatabase(ctx); + + // "Implicit transaction committed. 1 entity expected." + Assert.Equal(1, LogEntriesCount()); + Assert.Equal(ConnectionState.Closed, ctx.Connection.State); + } + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_explicit_transaction_cleared_after_disposing() + { + try + { + using (var ctx = CreateObjectContext()) + { + ctx.Connection.Open(); + + using (var committableTransaction = new CommittableTransaction()) + { + ctx.Connection.EnlistTransaction(committableTransaction); + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, CreateTransactionContext().LogEntries.Count()); + + var newTransactionLogEntry = AddLogEntryToDatabase(ctx); + + // "Implicit transaction committed. 1 entity expected." + Assert.Equal(1, CreateTransactionContext().LogEntries.Count()); + } + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_no_implicit_transaction_created_when_transactions_change_between_requests() + { + using (var ctx = CreateObjectContext()) + { + ctx.Connection.Open(); + + using (var transaction1 = new TransactionScope()) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + + using (var transaction2 = new TransactionScope()) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_no_implicit_transaction_created_when_enlisting_in_transaction_between_requests() + { + using (var ctx = CreateObjectContext()) + { + ctx.Connection.Open(); + + using (var transaction1 = new TransactionScope()) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + + using (var committableTransaction = new CommittableTransaction()) + { + ctx.Connection.EnlistTransaction(committableTransaction); + + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Open, ctx.Connection.State); + } + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_no_implicit_transaction_created_when_transaction_change_and_connection_is_closed_between_requests() + { + using (var ctx = CreateObjectContext()) + { + ctx.Connection.Open(); + + using (var trx = new TransactionScope()) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + ctx.Connection.Close(); + } + + using (var trx = new TransactionScope()) + { + var transactionLogEntry = AddLogEntryToDatabase(ctx); + Assert.Equal(1, transactionLogEntry.TransactionCount); + Assert.Equal(ConnectionState.Closed, ctx.Connection.State); + } + } + + // "Transaction not commited. No entities should be saved to the database." + Assert.Equal(0, LogEntriesCount()); + } + + [Fact] + public void Verify_cannot_enlist_in_more_than_one_active_transaction_on_the_same_opened_connection() + { + try + { + using (var ctx = CreateTransactionContext()) + { + ctx.Connection.Open(); + using (var committableTransaction = new CommittableTransaction()) + { + using (var newCommittableTransaction = new CommittableTransaction()) + { + ctx.Connection.EnlistTransaction(committableTransaction); + + Assert.Equal( + Strings.EntityClient_ProviderSpecificError("EnlistTransaction"), + Assert.Throws(() => ctx.Connection.EnlistTransaction(newCommittableTransaction)).Message); + } + } + } + } + finally + { + ResetTables(); + } + } + + [Fact] + public void Verify_closing_connection_invalidates_explicit_transaction() + { + try + { + using (var ctx = CreateTransactionContext()) + { + ctx.Connection.Open(); + using (var committableTransaction = new CommittableTransaction()) + { + ctx.Connection.EnlistTransaction(committableTransaction); + ctx.Connection.Close(); + + ctx.Connection.Open(); + using (var newCommittableTransaction = new CommittableTransaction()) + { + ctx.Connection.EnlistTransaction(newCommittableTransaction); + } + } + } + } + finally + { + ResetTables(); + } + } + + private TransactionContext CreateTransactionContext() + { + var ctx = new TransactionContext(connectionString); + ctx.MetadataWorkspace.LoadFromAssembly(Assembly.GetExecutingAssembly()); + + return ctx; + } + + private TransactionContext CreateTransactionContext(EntityConnection connection) + { + var ctx = new TransactionContext(connection); + ctx.MetadataWorkspace.LoadFromAssembly(Assembly.GetExecutingAssembly()); + + return ctx; + } + + private ObjectContext CreateObjectContext() + { + var ctx = new ObjectContext(connectionString); + ctx.MetadataWorkspace.LoadFromAssembly(Assembly.GetExecutingAssembly()); + + return ctx; + } + + private ObjectContext CreateObjectContext(EntityConnection connection) + { + var ctx = new ObjectContext(connection); + ctx.MetadataWorkspace.LoadFromAssembly(Assembly.GetExecutingAssembly()); + + return ctx; + } + + private TransactionDbContext CreateTransactionDbContext() + { + var ctx = new TransactionDbContext(connectionString); + + return ctx; + } + + private TransactionDbContext CreateTransactionDbContext(EntityConnection connection, bool contextOwnsConnection) + { + var ctx = new TransactionDbContext(connection, contextOwnsConnection); + + return ctx; + } + + private TransactionDbContext CreateTransactionDbContext(SqlConnection connection, DbCompiledModel compiledModel, bool contextOwnsConnection) + { + var ctx = new TransactionDbContext(connection, compiledModel, contextOwnsConnection); + + return ctx; + } + + private int LogEntriesCount() + { + using (var ctx = CreateTransactionContext()) + { + return ctx.LogEntries.Count(); + } + } + + private int LogEntriesCount(EntityConnection connection) + { + using (var ctx = CreateTransactionContext(connection)) + { + return ctx.LogEntries.Count(); + } + } + + private TransactionLogEntry AddLogEntryToDatabase(ObjectContext ctx) + { + var transactionLogEntry = new TransactionLogEntry(); + ctx.AddObject("Entities.TransactionLog", transactionLogEntry); + ctx.SaveChanges(); + + return transactionLogEntry; + } + + private TransactionLogEntry AddLogEntryToDatabase(TransactionDbContext ctx) + { + var transactionLogEntry = new TransactionLogEntry(); + ctx.LogEntries.Add(transactionLogEntry); + ctx.SaveChanges(); + + return transactionLogEntry; + } + + private void AddLogEntryUsingAdoNet(SqlConnection connection) + { + bool shouldCloseConnection = false; + if (connection.State == ConnectionState.Closed) + { + connection.Open(); + shouldCloseConnection = true; + } + + var command = new SqlCommand(); + command.Connection = connection; + command.CommandText = @"INSERT INTO ##TransactionLog Values(-1)"; + command.ExecuteNonQuery(); + + if (shouldCloseConnection) + { + connection.Close(); + } + } + + /// + /// Removes all entries from the tables used for tests. Must be called from tests that are committing transactions + /// as each test expects that the db will be initially clean. + /// + private void ResetTables() + { + new SqlCommand("DELETE FROM ##TransactionLog", globalConnection).ExecuteNonQuery(); + Assert.Equal(0, CreateTransactionContext().LogEntries.Count()); + } + } + + public class TransactionFixture : FunctionalTestBase, IDisposable + { + public SqlConnection GlobalConnection { get; private set; } + public DbCompiledModel CompiledModel { get; private set; } + + public TransactionFixture() + { + if (GlobalConnection != null) + { + throw new InvalidOperationException("Database is still in use and cannot be initialized."); + } + + // we are using tempdb and SQLExpress instance so we don't want this to be configurable + GlobalConnection = new SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=tempdb;Integrated Security=SSPI;"); + GlobalConnection.Open(); + + try + { + new SqlCommand( + @" + CREATE TABLE [dbo].[##TransactionLog]( + [ID] [int] IDENTITY(1,1) NOT NULL, + [TransactionCount] [int] NOT NULL, + CONSTRAINT [PK_TransactionLog] PRIMARY KEY CLUSTERED + ( + [ID] ASC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + ) ON [PRIMARY]", GlobalConnection).ExecuteNonQuery(); + + new SqlCommand( + @" + CREATE PROCEDURE [dbo].[##CreateTransactionLogEntry] + AS + BEGIN + DECLARE @tranCount AS int = @@TRANCOUNT -- assigning to a variable prevents from counting an implicit transaction created for insert + INSERT INTO ##TransactionLog Values(@tranCount) + SELECT ID, TransactionCount + FROM ##TransactionLog + WHERE ID = SCOPE_IDENTITY() + END", GlobalConnection).ExecuteNonQuery(); + + CompiledModel = BuildCompiledModel(); + } + catch + { + CleanupDatabase(); + + throw; + } + } + + private DbCompiledModel BuildCompiledModel() + { + // hack - we have to create context that uses StoredProcedure to for inserts. DbModelBuilder does not support that. + // Instead, we use reflection to inject MetadataWorkspace created using csdl/ssdl/msl into a DbCompiledModel + var connectionString = string.Format( + @"metadata=res://EntityFramework.FunctionalTests.Transitional/System.Data.Entity.Objects.TransactionsModel.csdl|res://EntityFramework.FunctionalTests.Transitional/System.Data.Entity.Objects.TransactionsModel.ssdl|res://EntityFramework.FunctionalTests.Transitional/System.Data.Entity.Objects.TransactionsModel.msl;provider=System.Data.SqlClient;provider connection string=""{0}""", + ModelHelpers.SimpleConnectionString("tempdb")); + + var ctx = new TransactionDbContext(connectionString); + ctx.LogEntries.Count(); + var objectContext = ((IObjectContextAdapter)ctx).ObjectContext; + + DbModelBuilder builder = new DbModelBuilder(); + builder.Entity(typeof(TransactionLogEntry)).ToTable("##TransactionLog"); + builder.HasDefaultSchema("tempdbModel"); + builder.Conventions.Add(new ModelContainerConvention("Entities")); + + + var model = builder.Build(ctx.Database.Connection); + var compiledModel = model.Compile(); + var cachedMetadataWorkspaceFieldInfo = compiledModel.GetType().GetField("_workspace", BindingFlags.Instance | BindingFlags.NonPublic); + var cachedMetadataWorkspace = cachedMetadataWorkspaceFieldInfo.GetValue(compiledModel); + var metadataWorkspaceFieldInfo = cachedMetadataWorkspace.GetType().GetField("_metadataWorkspace", BindingFlags.Instance | BindingFlags.NonPublic); + metadataWorkspaceFieldInfo.SetValue(cachedMetadataWorkspace, objectContext.MetadataWorkspace); + + return compiledModel; + } + + private void CleanupDatabase() + { + Debug.Assert(GlobalConnection != null); + + GlobalConnection.Close(); + GlobalConnection.Dispose(); + GlobalConnection = null; + } + + public void Dispose() + { + CleanupDatabase(); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/ProductivityApi/DbContextTests.cs b/test/EntityFramework/FunctionalTests.Transitional/ProductivityApi/DbContextTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/ProductivityApi/DbContextTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/ProductivityApi/DbContextTests.cs index c4d49ffc..421c82bb 100644 --- a/test/EntityFramework/FunctionalTests/ProductivityApi/DbContextTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/ProductivityApi/DbContextTests.cs @@ -1,3546 +1,3546 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace ProductivityApiTests -{ - using System; - using System.Collections; - using System.Collections.Generic; - using System.Data; - using System.Data.Common; - using System.Data.Entity; - using System.Data.Entity.Core; - using System.Data.Entity.Core.EntityClient; - using System.Data.Entity.Core.Objects; - using System.Data.Entity.Infrastructure; - using System.Data.Entity.Internal; - using System.Data.Entity.ModelConfiguration; - using System.Data.Entity.Validation; - using System.Globalization; - using System.Linq; - using System.Transactions; - using AdvancedPatternsModel; - using AllTypeKeysModel; - using ConcurrencyModel; - using DaFunc; - using SimpleModel; - using Xunit; - using Xunit.Extensions; - - /// - /// Tests for the primary methods on DbContext. - /// - public class DbContextTests : FunctionalTestBase - { - #region Infrastructure/setup - - public DbContextTests() - { - CreateMetadataFilesForSimpleModel(); - } - - #endregion - - #region Positive constructor tests - - [Fact] - public void Sets_are_initialized_using_empty_constructor_on_DbContext() - { - using (var context = new SimpleModelContext()) - { - Assert.NotNull(context.Products); - Assert.NotNull(context.Categories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - [Fact] - public void Sets_are_initialized_using_name_constructor_on_DbContext() - { - using (var context = new SimpleModelContext(DefaultDbName())) - { - Assert.NotNull(context.Products); - Assert.NotNull(context.Categories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - [Fact] - public void Sets_are_initialized_but_do_not_change_model_using_name_and_model_constructor_on_DbContext() - { - var model = new DbModelBuilder().Build(ProviderRegistry.Sql2008_ProviderInfo).Compile(); - using (var context = new SimpleModelContextWithNoData(DefaultDbName(), model)) - { - Assert.NotNull(context.Products); - Assert.NotNull(context.Categories); - context.Assert().IsNotInModel(); - context.Assert().IsNotInModel(); - } - } - - [Fact] - public void Sets_are_initialized_using_existing_connection_constructor_on_DbContext() - { - using (var connection = SimpleConnection()) - { - using (var context = new SimpleModelContext(connection)) - { - Assert.NotNull(context.Products); - Assert.NotNull(context.Categories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - } - - [Fact] - public void - Sets_are_initialized_but_do_not_change_model_using_existing_connection_and_model_constructor_on_DbContext() - { - var model = new DbModelBuilder().Build(ProviderRegistry.Sql2008_ProviderInfo).Compile(); - using (var connection = SimpleConnection()) - { - using (var context = new SimpleModelContextWithNoData(connection, model)) - { - Assert.NotNull(context.Products); - Assert.NotNull(context.Categories); - context.Assert().IsNotInModel(); - context.Assert().IsNotInModel(); - } - } - } - - [Fact] - public void Sets_are_initialized_using_object_context_constructor_on_DbContext() - { - using (var context = new SimpleModelContext()) - { - using (var context2 = new SimpleModelContext(GetObjectContext(context))) - { - Assert.NotNull(context2.Products); - Assert.NotNull(context2.Categories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - } - - [Fact] - public void Database_Name_is_formed_by_convention_ie_namespace_qualified_class_name_when_using_empty_constructor_on_DbContext() - { - Database_Name_is_formed_by_convention_ie_namespace_qualified_class_name(); - } - - [Fact] - public void Database_Name_is_formed_by_convention_ie_namespace_qualified_class_name_when_using_model_constructor_on_DbContext() - { - // Arrange - var builder = SimpleModelContext.CreateBuilder(); - - // Act- Assert - Database_Name_is_formed_by_convention_ie_namespace_qualified_class_name( - builder.Build(ProviderRegistry.Sql2008_ProviderInfo).Compile()); - } - - private void Database_Name_is_formed_by_convention_ie_namespace_qualified_class_name( - DbCompiledModel model = null) - { - // Act - using (var context = model == null ? new SimpleModelContext() : new SimpleModelContext(model)) - { - // Assert - Assert.Equal("SimpleModel.SimpleModelContext", context.Database.Connection.Database); - } - } - - [Fact] - public void - Database_Name_is_from_App_Config_if_convention_name_matches_named_connection_string_when_using_model_constructor_on_DbContext() - { - var builder = AllTypeKeysContext.CreateBuilder(); - Database_Name_is_from_App_Config_if_convention_name_matches_named_connection_string( - builder.Build(ProviderRegistry.Sql2008_ProviderInfo).Compile()); - } - - [Fact] - public void - Database_Name_is_from_App_config_if_named_connection_string_matches_convention_name_when_using_empty_constructor_on_DbContext() - { - Database_Name_is_from_App_Config_if_convention_name_matches_named_connection_string(); - } - - private void Database_Name_is_from_App_Config_if_convention_name_matches_named_connection_string( - DbCompiledModel model = null) - { - // Act - using (var context = model == null ? new AllTypeKeysContext() : new AllTypeKeysContext(model)) - { - // Assert that name of database is taken from app config rather than the convention way, - // namespace qualified type name - Assert.NotEqual("AllTypeKeysModel.AllTypeKeysContext", context.Database.Connection.Database); - Assert.Equal("AllTypeKeysDb", context.Database.Connection.Database); - } - } - - [Fact] - public void Sets_are_initialized_for_DbContext_constructor_when_using_empty_DbCompiledModel() - { - VerifySetsAreInitialized(DbCompiledModelContents.IsEmpty); - } - - [Fact] - public void Sets_are_initialized_for_DbContext_constructor_when_using_subset_DbCompiledModel() - { - VerifySetsAreInitialized(DbCompiledModelContents.IsSubset); - } - - [Fact] - public void Sets_are_initialized_for_DbContext_constructor_when_using_superset_DbCompiledModel() - { - VerifySetsAreInitialized(DbCompiledModelContents.IsSuperset); - } - - [Fact] - public void Sets_are_initialized_for_DbContext_constructor_when_using_DbCompiledModel_that_matches_the_context() - { - VerifySetsAreInitialized(DbCompiledModelContents.Match); - } - - [Fact] - public void Sets_are_initialized_for_DbContext_constructor_when_using_DbCompiledModel_that_doesnt_match_context_definitions() - { - VerifySetsAreInitialized(DbCompiledModelContents.DontMatch); - } - - [Fact] - public void Model_Tweaking_is_ignored_when_using_model_ctor_on_DbContext() - { - // Arrange - var modelBuilder = new DbModelBuilder(); - // Blog has Id as the key defined in OnModelCreating, here we tweak it to use Title as the Key - modelBuilder.Entity().HasKey(o => o.Title); - - // Act - using ( - var context = new LiveWriterContext(modelBuilder.Build(ProviderRegistry.SqlCe4_ProviderInfo).Compile())) - { - Assert.NotNull(context.Blogs); - context.Assert().IsInModel(); - - // Assert that Blog doesnt have Id as the key but rather has Title as the Key - var type = GetEntityType(context, typeof(Blog)); - Assert.True(type.KeyMembers.Count == 1); - Assert.Equal(type.KeyMembers.First().Name, "Title"); - } - } - - [Fact] - public void Verify_DbContext_construction_using_connection_string_ctor_when_string_is_database_name() - { - Verify_DbContext_construction_using_connection_string_ctor( - nameOrConnectionString: "DefaultDatabaseNameDb", - expectedDatabaseName: "DefaultDatabaseNameDb"); - } - - [Fact] - public void Verify_DbContext_construction_using_connection_string_ctor_when_string_is_provider_connection_string() - { - Verify_DbContext_construction_using_connection_string_ctor( - nameOrConnectionString: SimpleConnectionString()); - } - - [Fact] - public void Verify_DbContext_construction_using_connection_string_ctor_when_string_is_named_connection_string() - { - Verify_DbContext_construction_using_connection_string_ctor( - nameOrConnectionString: "SimpleModelWithNoDataFromAppConfig", - expectedDatabaseName: "SimpleModel.SimpleModelWithNoData"); - } - - [Fact] - public void Verify_DbContext_construction_using_connection_string_ctor_when_string_is_named_connection_string_using_name_keyword() - { - Verify_DbContext_construction_using_connection_string_ctor( - nameOrConnectionString: "Name=SimpleModelWithNoDataFromAppConfig", - expectedDatabaseName: "SimpleModel.SimpleModelWithNoData"); - } - - [Fact] - public void - Verify_DbContext_construction_using_connection_string_ctor_when_string_is_named_connection_string_and_its_last_token_exists_in_config - () - { - Verify_DbContext_construction_using_connection_string_ctor( - nameOrConnectionString: "X.Y.Z.R.SimpleModelWithNoDataFromAppConfig", - expectedDatabaseName: "SimpleModel.SimpleModelWithNoData"); - } - - private void Verify_DbContext_construction_using_connection_string_ctor( - string nameOrConnectionString, - string expectedDatabaseName = - "SimpleModel.SimpleModelContextWithNoData") - { - using (var context = new SimpleModelContextWithNoData(nameOrConnectionString)) - { - Assert.NotNull(context.Products); - Assert.NotNull(context.Categories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - - Assert.Equal(expectedDatabaseName, context.Database.Connection.Database); - } - } - - [Fact] - public void Verify_DbContext_construction_using_db_name_and_model_Ctor_where_model_defines_a_subset_of_entities_on_context() - { - DbContext_construction_using_connection_string_and_model_Ctor( - ConnectionStringFormat.DatabaseName, - DbCompiledModelContents.IsSubset); - } - - [Fact] - public void Verify_DbContext_construction_using_db_name_and_model_Ctor_where_model_defines_a_superset_of_entities_on_context() - { - DbContext_construction_using_connection_string_and_model_Ctor( - ConnectionStringFormat.DatabaseName, - DbCompiledModelContents.IsSuperset); - } - - [Fact] - public void - Verify_DbContext_construction_using_db_name_and_model_Ctor_where_model_matches_the_entities_on_context() - { - DbContext_construction_using_connection_string_and_model_Ctor( - ConnectionStringFormat.DatabaseName, - DbCompiledModelContents.Match); - } - - [Fact] - public void Verify_DbContext_construction_using_db_name_and_model_Ctor_where_model_has_no_entities_matching_those_on_context() - { - DbContext_construction_using_connection_string_and_model_Ctor( - ConnectionStringFormat.DatabaseName, - DbCompiledModelContents.DontMatch); - } - - [Fact] - public void Verify_DbContext_construction_using_valid_connection_string_and_model_Ctor_where_model_is_empty() - { - DbContext_construction_using_connection_string_and_model_Ctor( - ConnectionStringFormat.ProviderConnectionString, DbCompiledModelContents.IsEmpty); - } - - [Fact] - public void - Verify_DbContext_construction_using_valid_connection_string_and_model_Ctor_where_model_defines_a_subset_of_entities_on_context() - { - DbContext_construction_using_connection_string_and_model_Ctor( - ConnectionStringFormat.ProviderConnectionString, DbCompiledModelContents.IsSubset); - } - - [Fact] - public void - Verify_DbContext_construction_using_valid_connection_string_and_model_Ctor_where_model_defines_a_superset_of_entities_on_context - () - { - DbContext_construction_using_connection_string_and_model_Ctor( - ConnectionStringFormat.ProviderConnectionString, DbCompiledModelContents.IsSuperset); - } - - [Fact] - public void Verify_DbContext_construction_using_valid_connection_string_and_model_Ctor_where_model_matches_the_entities_on_context() - { - DbContext_construction_using_connection_string_and_model_Ctor( - ConnectionStringFormat.ProviderConnectionString, DbCompiledModelContents.Match); - } - - [Fact] - public void - Verify_DbContext_construction_using_valid_connection_string_and_model_Ctor_where_model_has_no_entities_matching_those_on_context - () - { - DbContext_construction_using_connection_string_and_model_Ctor( - ConnectionStringFormat.ProviderConnectionString, DbCompiledModelContents.DontMatch); - } - - [Fact] - public void Verify_DbContext_construction_using_named_connection_string_and_model_Ctor_where_model_is_empty() - { - DbContext_construction_using_connection_string_and_model_Ctor( - ConnectionStringFormat.NamedConnectionString, - DbCompiledModelContents.IsEmpty); - } - - [Fact] - public void DbContext_construction_using_named_connection_string_and_model_Ctor_where_model_defines_a_subset_of_entities_on_context( - - ) - { - DbContext_construction_using_connection_string_and_model_Ctor( - ConnectionStringFormat.NamedConnectionString, - DbCompiledModelContents.IsSubset); - } - - [Fact] - public void - DbContext_construction_using_named_connection_string_and_model_Ctor_where_model_defines_a_superset_of_entities_on_context() - { - DbContext_construction_using_connection_string_and_model_Ctor( - ConnectionStringFormat.NamedConnectionString, - DbCompiledModelContents.IsSuperset); - } - - [Fact] - public void DbContext_construction_using_named_connection_string_and_model_Ctor_where_model_matches_the_entities_on_context() - { - DbContext_construction_using_connection_string_and_model_Ctor( - ConnectionStringFormat.NamedConnectionString, - DbCompiledModelContents.Match); - } - - [Fact] - public void - DbContext_construction_using_named_connection_string_and_model_Ctor_where_model_has_no_entities_matching_those_on_context() - { - DbContext_construction_using_connection_string_and_model_Ctor( - ConnectionStringFormat.NamedConnectionString, - DbCompiledModelContents.DontMatch); - } - - private void DbContext_construction_using_connection_string_and_model_Ctor( - ConnectionStringFormat connStringFormat, DbCompiledModelContents modelContents) - { - // Act - // Setup connection string - string connectionString = null; - string dbName = null; - switch (connStringFormat) - { - case ConnectionStringFormat.DatabaseName: - connectionString = dbName = DefaultDbName(); - break; - case ConnectionStringFormat.NamedConnectionString: - connectionString = "SimpleModelWithNoDataFromAppConfig"; - dbName = "SimpleModel.SimpleModelWithNoData"; - break; - case ConnectionStringFormat.ProviderConnectionString: - connectionString = SimpleConnectionString(); - dbName = "SimpleModel.SimpleModelContextWithNoData"; - break; - default: - throw new ArgumentException("Invalid ConnectionStringFormat enum supplied " + connStringFormat); - } - - // Setup DbCompiledModel - var builder = new DbModelBuilder(); - - switch (modelContents) - { - case DbCompiledModelContents.IsEmpty: - // Do nothing as builder has already been initialized - break; - case DbCompiledModelContents.IsSubset: - // Product is not defined here - builder.Entity(); - break; - case DbCompiledModelContents.IsSuperset: - builder.Entity(); - builder.Entity(); - builder.Entity(); - break; - case DbCompiledModelContents.Match: - builder.Entity(); - builder.Entity(); - break; - case DbCompiledModelContents.DontMatch: - builder.Entity(); - builder.Entity(); - break; - default: - throw new ArgumentException("Invalid DbCompiledModelContents Arguments passed in, " + modelContents); - } - - // Act - using ( - var context = new SimpleModelContextWithNoData( - connectionString, - builder.Build(ProviderRegistry.Sql2008_ProviderInfo). - Compile())) - { - // Assert - Assert.Equal(context.Database.Connection.Database, dbName); - switch (modelContents) - { - case DbCompiledModelContents.IsEmpty: - Assert.NotNull(context.Categories); - Assert.NotNull(context.Categories); - context.Assert().IsNotInModel(); - context.Assert().IsNotInModel(); - break; - case DbCompiledModelContents.IsSubset: - Assert.NotNull(context.Categories); - Assert.NotNull(context.Categories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); // reachability - break; - case DbCompiledModelContents.IsSuperset: - Assert.NotNull(context.Categories); - Assert.NotNull(context.Categories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - break; - case DbCompiledModelContents.Match: - Assert.NotNull(context.Categories); - Assert.NotNull(context.Categories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - context.Assert().IsNotInModel(); - break; - case DbCompiledModelContents.DontMatch: - Assert.NotNull(context.Categories); - Assert.NotNull(context.Products); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - break; - default: - throw new ArgumentException( - "Invalid DbCompiledModelContents Arguments passed in, " + - modelContents); - } - } - } - - [Fact] - public void Database_name_generated_from_generic_DbContext_class_name_works() - { - using (var context = new GenericFuncy>()) - { - context.Database.Delete(); - - context.Database.Initialize(force: false); - - Assert.True(context.Database.Exists()); - } - } - - [Fact] - public void Database_name_generated_from_DbContext_class_nested_in_generic_class_name_works() - { - using (var context = new GT.Funcy()) - { - context.Database.Delete(); - - context.Database.Initialize(force: false); - - Assert.True(context.Database.Exists()); - } - } - - [Fact] - public void Database_name_generated_from_generic_DbContext_class_nested_in_generic_class_name_works() - { - using (var context = new GT.GenericFuncy, NT>, NT>()) - { - context.Database.Delete(); - - context.Database.Initialize(force: false); - - Assert.True(context.Database.Exists()); - } - } - - #endregion - - #region Negative constructor tests - - [Fact] - public void DbContext_construction_does_not_throw_but_subsequent_calls_using_connection_throw_for_invalid_sql_connection_string() - { - var context = new SimpleModelContextWithNoData("InvalidKeywordConnectionString"); - Assert.Throws(() => GetObjectContext(context)).ValidateMessage( - typeof(DbConnection).Assembly, "ADP_KeywordNotSupported", null); - } - - [Fact] - public void DbContext_construction_does_not_throw_but_subsequent_calls_using_connection_throw_for_invalid_provider_keyword() - { - var context = new SimpleModelContextWithNoData("InvalidProviderNameConnectionString"); - Assert.Throws(() => GetObjectContext(context)).ValidateMessage("EntityClient_InvalidStoreProvider"); - } - - [Fact] - public void DbContext_construction_does_not_throw_but_subsequent_calls_using_connection_throw_for_nonexistent_connection_string() - { - var context = new SimpleModelContextWithNoData("Name=NonexistentConnectionString"); - Assert.Throws(() => GetObjectContext(context)).ValidateMessage( - "DbContext_ConnectionStringNotFound", "NonexistentConnectionString"); - } - - [Fact] - public void DbContext_caches_models_for_two_providers() - { - // Ensure that the model is in use with a SQL connection - using (var context = new SimpleModelContext()) - { - context.Database.Initialize(force: false); - } - - // Now try to use it with a CE connection; would throw in EF 4.1, will not now throw. - var sqlCeConnectionFactory = new SqlCeConnectionFactory( - "System.Data.SqlServerCe.4.0", - AppDomain.CurrentDomain.BaseDirectory, ""); - using (var connection = sqlCeConnectionFactory.CreateConnection(DefaultDbName())) - { - using (var context = new SimpleModelContext(connection)) - { - context.Database.Initialize(force: false); - } - } - } - - #endregion - - #region Positive SaveChanges tests - - [Fact] - [AutoRollback] - public void SaveChanges_saves_Added_Modified_Deleted_entities() - { - SaveChanges_saves_Added_Modified_Deleted_entities_implementation((c) => c.SaveChanges()); - } - -#if !NET40 - - [Fact] - [AutoRollback] - public void SaveChangesAsync_saves_Added_Modified_Deleted_entities() - { - SaveChanges_saves_Added_Modified_Deleted_entities_implementation((c) => c.SaveChangesAsync().Result); - } - -#endif - - private void SaveChanges_saves_Added_Modified_Deleted_entities_implementation(Func saveChanges) - { - using (var context = new SimpleModelContext()) - { - // Modified - var product1 = context.Products.Find(1); - product1.Name = "Smarties"; - - // Deleted - var product2 = context.Products.Find(2); - context.Products.Remove(product2); - - // Added - var product3 = new Product - { - Name = "Branston Pickle" - }; - context.Products.Add(product3); - - // Validate state before Save - Assert.Equal(3, GetStateEntries(context).Count()); - Assert.Equal(EntityState.Modified, GetStateEntry(context, product1).State); - Assert.Equal(EntityState.Deleted, GetStateEntry(context, product2).State); - Assert.Equal(EntityState.Added, GetStateEntry(context, product3).State); - - // Save - var savedCount = saveChanges(context); - Assert.Equal(3, savedCount); - - // Validate state after Save - Assert.Equal(2, GetStateEntries(context).Count()); - Assert.Equal(EntityState.Unchanged, GetStateEntry(context, product1).State); - Assert.Equal(EntityState.Unchanged, GetStateEntry(context, product3).State); - - using (var context2 = new SimpleModelContext()) - { - var product1s = context2.Products.Find(product1.Id); - var product2s = context2.Products.Find(product2.Id); - var product3s = context2.Products.Find(product3.Id); - - Assert.NotNull(product1s); - Assert.Null(product2s); - Assert.NotNull(product3s); - - Assert.Equal("Smarties", product1s.Name); - Assert.Equal("Branston Pickle", product3s.Name); - - Assert.Equal(2, GetStateEntries(context).Count()); - Assert.Equal(EntityState.Unchanged, GetStateEntry(context2, product1s).State); - Assert.Equal(EntityState.Unchanged, GetStateEntry(context2, product3s).State); - } - } - } - - [Fact] - [AutoRollback] - public void SaveChanges_performs_DetectChanges() - { - SaveChanges_performs_DetectChanges_implementation((c) => c.SaveChanges()); - } - -#if !NET40 - - [Fact] - [AutoRollback] - public void SaveChangesAsync_performs_DetectChanges() - { - SaveChanges_performs_DetectChanges_implementation((c) => c.SaveChangesAsync().Result); - } - -#endif - - private void SaveChanges_performs_DetectChanges_implementation(Func saveChanges) - { - // NOTE: This is split out into a seperate test from the above test because - // it is important no other APIs are called between the modification - // and calling SaveChanges due to other APIs calling DetectChanges implicitly - - using (var context = new SimpleModelContext()) - { - var prod = context.Products.Find(1); - prod.Name = "Cascade Draught"; - var savedCount = saveChanges(context); - Assert.Equal(1, savedCount); - } - } - - [Fact] - public void SaveChanges_on_uninitialized_context_does_not_throw() - { - using (var context = new SimpleModelContext()) - { - Assert.Equal(0, context.SaveChanges()); - } - } - -#if !NET40 - - [Fact] - public void SaveChangesAsync_on_uninitialized_context_does_not_throw() - { - using (var context = new SimpleModelContext()) - { - Assert.Equal(0, context.SaveChangesAsync().Result); - } - } - -#endif - - public class SaveChangesDoesntInitializeContext : DbContext - { - public SaveChangesDoesntInitializeContext() - { - Database.SetInitializer(null); - } - - public bool InitializationHappened { get; set; } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - InitializationHappened = true; - } - } - - [Fact] - public void SaveChanges_on_uninitialized_context_does_not_cause_context_to_be_initialized() - { - using (var context = new SaveChangesDoesntInitializeContext()) - { - context.SaveChanges(); - - Assert.False(context.InitializationHappened); - - var _ = ((IObjectContextAdapter)context).ObjectContext; - - Assert.True(context.InitializationHappened); - } - } - -#if !NET40 - - public class SaveChangesAsyncDoesntInitializeContext : DbContext - { - public SaveChangesAsyncDoesntInitializeContext() - { - Database.SetInitializer(null); - } - - public bool InitializationHappened { get; set; } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - InitializationHappened = true; - } - } - - [Fact] - public void SaveChangesAsync_on_uninitialized_context_does_not_cause_context_to_be_initialized() - { - using (var context = new SaveChangesAsyncDoesntInitializeContext()) - { - context.SaveChangesAsync().Wait(); - - Assert.False(context.InitializationHappened); - - var _ = ((IObjectContextAdapter)context).ObjectContext; - - Assert.True(context.InitializationHappened); - } - } - -#endif - - [Fact] - public void SaveChanges_is_virtual() - { - using (DbContext context = new SimpleModelContextWithNoData()) - { - Assert.Equal(0, context.SaveChanges()); - Assert.True(((SimpleModelContextWithNoData)context).SaveChangesCalled); - } - } - -#if !NET40 - - [Fact] - public void SaveChangesAsync_is_virtual() - { - using (DbContext context = new SimpleModelContextWithNoData()) - { - Assert.Equal(0, context.SaveChangesAsync().Result); - Assert.True(((SimpleModelContextWithNoData)context).SaveChangesCalled); - } - } - -#endif - - #endregion - - #region Negative SaveChanges tests - - [Fact] - public void SaveChanges_bubbles_presave_exception() - { - SaveChanges_bubbles_presave_exception_implementation((c) => c.SaveChanges()); - } - -#if !NET40 - - [Fact] - public void SaveChangesAsync_bubbles_presave_exception() - { - SaveChanges_bubbles_presave_exception_implementation( - (c) => ExceptionHelpers.UnwrapAggregateExceptions(() => c.SaveChangesAsync().Result)); - } - -#endif - - private void SaveChanges_bubbles_presave_exception_implementation(Func saveChanges) - { - EnsureDatabaseInitialized(() => new AdvancedPatternsMasterContext()); - - using (new TransactionScope()) - { - using (var context = new AdvancedPatternsMasterContext()) - { - var emp = new CurrentEmployee - { - EmployeeId = 4 - }; - var ord = new WorkOrder - { - WorkOrderId = 2, - EmployeeId = 4 - }; - context.Employees.Attach(emp); - context.WorkOrders.Attach(ord); - - // Create a conceptual null - GetObjectContext(context).ObjectStateManager.ChangeObjectState(emp, EntityState.Deleted); - - Assert.Throws(() => context.SaveChanges()).ValidateMessage( - "ObjectContext_CommitWithConceptualNull"); - } - } - } - - [Fact] - [AutoRollback] - public void SaveChanges_bubbles_UpdateException() - { - SaveChanges_bubbles_UpdateException_implementation((c) => c.SaveChanges()); - } - -#if !NET40 - - [Fact] - [AutoRollback] - public void SaveChangesAsync_bubbles_UpdateException() - { - SaveChanges_bubbles_UpdateException_implementation( - (c) => ExceptionHelpers.UnwrapAggregateExceptions(() => c.SaveChangesAsync().Result)); - } - -#endif - - private void SaveChanges_bubbles_UpdateException_implementation(Func saveChanges) - { - using (var context = new SimpleModelContext()) - { - var prod = new Product - { - Name = "Wallaby Sausages", - CategoryId = "AUSSIE FOODS" - }; - context.Products.Add(prod); - - Assert.Throws(() => saveChanges(context)).ValidateMessage( - "Update_GeneralExecutionException"); - } - } - - [Fact] - [AutoRollback] - public void SaveChanges_bubbles_exception_during_AcceptChanges() - { - SaveChanges_bubbles_exception_during_AcceptChanges_implementation((c) => c.SaveChanges()); - } - -#if !NET40 - - [Fact] - [AutoRollback] - public void SaveChangesAsync_bubbles_exception_during_AcceptChanges() - { - SaveChanges_bubbles_exception_during_AcceptChanges_implementation( - (c) => ExceptionHelpers.UnwrapAggregateExceptions(() => c.SaveChangesAsync().Result)); - } - -#endif - - private void SaveChanges_bubbles_exception_during_AcceptChanges_implementation(Func saveChanges) - { - using (var context = new SimpleModelContext()) - { - var cat1 = new Category - { - Id = "AUSSIE FOODS" - }; - var cat2 = new Category - { - Id = "AUSSIE FOODS" - }; - - context.Categories.Attach(cat1); - context.Categories.Add(cat2); - - // Accept will fail because of PK violation - // (cat1 doesn't actually exist in the store so update pipeline will succeed) - Assert.Throws(() => saveChanges(context)).ValidateMessage( - "ObjectContext_AcceptAllChangesFailure"); - } - } - - [Fact] - public void SaveChanges_throws_on_validation_errors() - { - SaveChanges_throws_on_validation_errors_implementation((c) => c.SaveChanges()); - } - -#if !NET40 - - [Fact] - public void SaveChangesAsync_throws_on_validation_errors() - { - SaveChanges_throws_on_validation_errors_implementation( - (c) => ExceptionHelpers.UnwrapAggregateExceptions(() => c.SaveChangesAsync().Result)); - } - -#endif - - public void SaveChanges_throws_on_validation_errors_implementation(Func saveChanges) - { - using (var context = new ValidationTestContext()) - { - context.Database.Initialize(force: false); - - using (new TransactionScope()) - { - context.ValidateEntityFunc = - (entry) => { return new DbEntityValidationResult(entry, new[] { new DbValidationError("Id", "error") }); }; - context.Categories.Add(new Category("FOOD")); - Assert.Throws(() => context.SaveChanges()).ValidateMessage( - "DbEntityValidationException_ValidationFailed"); - } - } - } - - #endregion - - #region Positive ObjectContext tests - - [Fact] - public void ObjectContext_property_returns_EF_context() - { - using (var context = new SimpleModelContext()) - { - var product = context.Products.Find(1); - - Assert.NotNull(GetObjectContext(context)); - Assert.NotNull(GetObjectContext(context).ObjectStateManager.GetObjectStateEntry(product)); - } - } - - [Fact] - public void ObjectContext_property_returns_EF_context_even_before_DbContext_is_initialized() - { - using (var context = new SimpleModelContext()) - { - Assert.NotNull(GetObjectContext(context)); - var product = GetObjectContext(context).CreateObjectSet().Where(p => p.Id == 1).Single(); - Assert.Equal(1, product.Id); - } - } - - #endregion - - #region Positive Connection property tests - - [Fact] - public void Connection_property_returns_connection() - { - using (var context = new SimpleModelContext()) - { - var product = context.Products.Find(1); - - Assert.NotNull(context.Database.Connection); - Assert.Equal(DefaultDbName(), context.Database.Connection.Database); - } - } - - [Fact] - public void Connection_property_returns_connection_even_before_DbContext_is_initialized() - { - using (var context = new SimpleModelContext()) - { - Assert.NotNull(context.Database.Connection); - Assert.Equal(DefaultDbName(), context.Database.Connection.Database); - } - } - - #endregion - - #region Positive set detection and initialization tests - - public class DbSetVariant : EmptyContext - { - public DbSetVariant() - : base("CommonProductCategoryDatabase") - { - } - - public DbSet UnicornProducts { get; set; } - public DbSet UnicornCategories { get; set; } - } - - [Fact] - public void DbSet_properties_are_detected_and_initialized() - { - using (var context = new DbSetVariant()) - { - Assert.NotNull(context.UnicornProducts); - Assert.NotNull(context.UnicornCategories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - [Fact] - public void Entity_set_names_are_taken_from_DbSet_property_names() - { - using (var context = new DbSetVariant()) - { - Assert.Equal("UnicornProducts", GetEntitySetName(context, typeof(Product))); - Assert.Equal("UnicornCategories", GetEntitySetName(context, typeof(Category))); - } - } - - public class IDbSetVariant : EmptyContext - { - public IDbSetVariant() - : base("CommonProductCategoryDatabase") - { - } - - public IDbSet UnicornProducts { get; set; } - public IDbSet UnicornCategories { get; set; } - } - - [Fact] - public void IDbSet_properties_are_detected_and_initialized() - { - using (var context = new IDbSetVariant()) - { - Assert.NotNull(context.UnicornProducts); - Assert.NotNull(context.UnicornCategories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - [Fact] - public void Entity_set_names_are_taken_from_DbSet_property_names_when_using_IDbSet_properties() - { - using (var context = new IDbSetVariant()) - { - Assert.Equal("UnicornProducts", GetEntitySetName(context, typeof(Product))); - Assert.Equal("UnicornCategories", GetEntitySetName(context, typeof(Category))); - } - } - - public class IQueryableVariant : EmptyContext - { - public IQueryableVariant() - : base(DefaultDbName()) - { - } - - public IQueryable Products { get; set; } - public IQueryable Categories { get; set; } - } - - [Fact] - public void IQueryable_properties_are_not_detected_or_initialized() - { - using (var context = new IQueryableVariant()) - { - Assert.Null(context.Products); - Assert.Null(context.Categories); - context.Assert().IsNotInModel(); - context.Assert().IsNotInModel(); - } - } - - public class DbQueryVariant : EmptyContext - { - public DbQueryVariant() - : base(DefaultDbName()) - { - } - - public DbQuery Products { get; set; } - public DbQuery Categories { get; set; } - } - - [Fact] - public void DbQuery_properties_are_not_initialized() - { - using (var context = new DbQueryVariant()) - { - Assert.Null(context.Products); - Assert.Null(context.Categories); - context.Assert().IsNotInModel(); - context.Assert().IsNotInModel(); - } - } - - public class SetOfDerivedTypeVariant : EmptyContext - { - public SetOfDerivedTypeVariant() - : base("CommonProductCategoryDatabase") - { - } - - public DbSet UnicornProducts { get; set; } - public DbSet FeaturedProducts { get; set; } - public DbSet UnicornCategories { get; set; } - } - - [Fact] - public void Set_of_derived_type_initialized() - { - using (var context = new SetOfDerivedTypeVariant()) - { - Assert.NotNull(context.UnicornProducts); - Assert.NotNull(context.FeaturedProducts); - Assert.NotNull(context.UnicornCategories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - [Fact] - public void Entity_set_names_for_a_derived_type_come_from_the_base_type_DbSet_property_names() - { - using (var context = new SetOfDerivedTypeVariant()) - { - Assert.Equal("UnicornProducts", GetEntitySetName(context, typeof(Product))); - Assert.Equal("UnicornProducts", GetEntitySetName(context, typeof(FeaturedProduct))); - Assert.Equal("UnicornCategories", GetEntitySetName(context, typeof(Category))); - } - } - - public class PrivateSettersVariant : EmptyContext - { - public PrivateSettersVariant() - : base("CommonProductCategoryDatabase") - { - } - - public DbSet Products { get; private set; } - public IDbSet Categories { get; private set; } - } - - [Fact] - public void Set_properties_with_private_setters_are_detected_but_not_initialized() - { - using (var context = new PrivateSettersVariant()) - { - Assert.Null(context.Products); - Assert.Null(context.Categories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - public class InternalSettersVariant : EmptyContext - { - public InternalSettersVariant() - : base("CommonProductCategoryDatabase") - { - } - - public DbSet Products { get; internal set; } - public IDbSet Categories { get; internal set; } - } - - [Fact] - public void Set_properties_with_internal_setters_are_detected_but_not_initialized() - { - using (var context = new InternalSettersVariant()) - { - Assert.Null(context.Products); - Assert.Null(context.Categories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - public class ProtectedSettersVariant : EmptyContext - { - public ProtectedSettersVariant() - : base("CommonProductCategoryDatabase") - { - } - - public DbSet Products { get; protected set; } - public IDbSet Categories { get; protected set; } - } - - [Fact] - public void Set_properties_with_protected_setters_are_detected_but_not_initialized() - { - using (var context = new ProtectedSettersVariant()) - { - Assert.Null(context.Products); - Assert.Null(context.Categories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - public class NoSettersVariant : EmptyContext - { - public NoSettersVariant() - : base("CommonProductCategoryDatabase") - { - } - - public DbSet Products - { - get { return null; } - } - - public IDbSet Categories - { - get { return null; } - } - } - - [Fact] - public void Set_properties_with_no_setters_are_detected_but_not_initialized() - { - using (var context = new NoSettersVariant()) - { - Assert.Null(context.Products); - Assert.Null(context.Categories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - public class FullyPrivateVariant : EmptyContext - { - public FullyPrivateVariant() - : base("CommonProductCategoryDatabase") - { - } - - private DbSet Products { get; set; } - private IDbSet Categories { get; set; } - - public IQueryable GetProducts() - { - return Products; - } - - public IQueryable GetCategories() - { - return Categories; - } - } - - [Fact] - public void Fully_private_properties_are_detected_but_not_initialized() - { - using (var context = new FullyPrivateVariant()) - { - Assert.Null(context.GetProducts()); - Assert.Null(context.GetCategories()); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - public class MethodsAndFieldsVariant : EmptyContext - { - public MethodsAndFieldsVariant() - : base(DefaultDbName()) - { - } - - public IQueryable Products; - public IDbSet Categories; - public DbSet Logins; - - public IQueryable GetProducts() - { - return Products; - } - - public IDbSet GetCategories() - { - return Categories; - } - - public DbSet GetLogins() - { - return Logins; - } - } - - [Fact] - public void IQueryable_and_DbSet_methods_and_fields_are_ignored() - { - using (var context = new MethodsAndFieldsVariant()) - { - Assert.Null(context.GetProducts()); - Assert.Null(context.GetCategories()); - Assert.Null(context.GetLogins()); - context.Assert().IsNotInModel(); - context.Assert().IsNotInModel(); - context.Assert().IsNotInModel(); - } - } - - [Fact] - public void Derived_context_with_no_sets_is_okay() - { - using (var context = new EmptyContext()) - { - // Asking for the ObjectContext causes the DbContext to be initialized even with no types. - Assert.NotNull(GetObjectContext(context)); - } - } - - public class NonGenericIQueryableVariant : EmptyContext - { - public NonGenericIQueryableVariant() - : base(DefaultDbName()) - { - } - - public IQueryable Stuff { get; set; } - } - - [Fact] - public void Set_properties_of_non_generic_IQueryable_are_ignored() - { - using (var context = new NonGenericIQueryableVariant()) - { - Assert.Null(context.Stuff); - - // Asking for the ObjectContext causes the DbContext to be initialized even with no types. - Assert.NotNull(GetObjectContext(context)); - } - } - - public class IEnumerableVariant : EmptyContext - { - public IEnumerableVariant() - : base(DefaultDbName()) - { - } - - public IEnumerable Categories { get; set; } - } - - [Fact] - public void Set_properties_defined_as_IEnumerable_are_ignored() - { - using (var context = new IEnumerableVariant()) - { - Assert.Null(context.Categories); - context.Assert().IsNotInModel(); - } - } - - public class SetsDerivedFromValidSetTypeVariant : EmptyContext - { - public SetsDerivedFromValidSetTypeVariant() - : base(DefaultDbName()) - { - } - - public ObjectSet Products { get; set; } - public HashSetBasedDbSet Categories { get; set; } - } - - [Fact] - public void Set_properties_derived_from_valid_set_type_are_ignored() - { - using (var ctx = new SetsDerivedFromValidSetTypeVariant()) - { - Assert.Null(ctx.Products); - Assert.Null(ctx.Categories); - ctx.Assert().IsNotInModel(); - ctx.Assert().IsNotInModel(); - } - } - - public class DerivedDerivedContextNoExtraSetsVariant : SimpleModelContext - { - } - - [Fact] - public void Derived_derived_context_with_no_extra_sets() - { - using (var context = new DerivedDerivedContextNoExtraSetsVariant()) - { - Assert.NotNull(context.Categories); - Assert.NotNull(context.Products); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - public class DerivedDerivedContextExtraSetsVariant : SimpleModelContext - { - public DbSet ExtraSet { get; set; } - } - - [Fact] - public void Derived_derived_context_with_extra_sets() - { - using (var context = new DerivedDerivedContextExtraSetsVariant()) - { - Assert.NotNull(context.Categories); - Assert.NotNull(context.Products); - Assert.NotNull(context.ExtraSet); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - #endregion - - #region Negative set detection and initialization tests - - public class InterfaceVariant : EmptyContext - { - public InterfaceVariant() - : base(DefaultDbName()) - { - } - - public DbSet Collections { get; set; } - } - - [Fact] - public void Set_properties_for_interface_types_throw() - { - try - { - new InterfaceVariant(); - Assert.True(false); - } - catch (InvalidOperationException ex) - { - var resourceLookup = new AssemblyResourceLookup( - EntityFrameworkAssembly, - "System.Data.Entity.Properties.Resources"); - var messageTemplate = resourceLookup.LookupString("InvalidEntityType"); - - var message = String.Format(CultureInfo.InvariantCulture, messageTemplate, typeof(ICollection)); - - Assert.Equal(message, ex.Message); - } - } - - public class GenericVariant : EmptyContext - { - public GenericVariant() - : base(DefaultDbName()) - { - } - - public IDbSet> ProductCollections { get; set; } - } - - [Fact] - public void Set_properties_for_generic_types_throw() - { - try - { - new GenericVariant(); - Assert.True(false); - } - catch (InvalidOperationException ex) - { - var resourceLookup = new AssemblyResourceLookup( - EntityFrameworkAssembly, - "System.Data.Entity.Properties.Resources"); - var messageTemplate = resourceLookup.LookupString("InvalidEntityType"); - - var message = String.Format(CultureInfo.InvariantCulture, messageTemplate, typeof(List)); - - Assert.Equal(message, ex.Message); - } - } - - public class NonEntityVariant : EmptyContext - { - public NonEntityVariant() - : base(DefaultDbName()) - { - } - - public DbSet ObsoleteAttributes { get; set; } - } - - [Fact] - public void Set_properties_for_non_entity_types_throw() - { - using (var context = new NonEntityVariant()) - { - Assert.NotNull(context.ObsoleteAttributes); - Assert.Throws(() => GetObjectContext(context)); - } - } - - public class DuplicateDbSetVariant : DbContext - { - public DbSet Products { get; set; } - public DbSet Categories { get; set; } - public DbSet CategoriesAgain { get; set; } - } - - [Fact] - public void Duplicate_DbSet_content_types_throw_Anti_MEST() - { - using (var context = new DuplicateDbSetVariant()) - { - Assert.Throws(() => context.Categories.FirstOrDefault()).ValidateMessage( - "Mapping_MESTNotSupported", "Categories", "CategoriesAgain", "SimpleModel.Category"); - } - } - - public class DuplicateIQueryableSetVariant : EmptyContext - { - public DuplicateIQueryableSetVariant() - : base(DefaultDbName()) - { - } - - public IQueryable Products1 { get; set; } - public IQueryable Products2 { get; set; } - } - - [Fact] - public void Duplicate_IQueryable_content_types_do_not_throw_Anti_MEST() - { - using (var context = new DuplicateIQueryableSetVariant()) - { - Assert.Null(context.Products1); - Assert.Null(context.Products2); - context.Assert().IsNotInModel(); - } - } - - public class DuplicateSetWithDifferentSetTypesVariant : EmptyContext - { - public DuplicateSetWithDifferentSetTypesVariant() - : base("CommonProductCategoryDatabase") - { - } - - public DbSet Products { get; set; } - public DbSet Categories { get; set; } - public IQueryable CategoriesAgain { get; set; } - } - - [Fact] - public void Duplicate_set_content_types_where_one_type_is_IQueryable_does_not_throw_Anti_MEST() - { - using (var context = new DuplicateSetWithDifferentSetTypesVariant()) - { - Assert.NotNull(context.Products); - Assert.NotNull(context.Categories); - Assert.Null(context.CategoriesAgain); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - public class ExceptionFromSetSetterVariant : EmptyContext - { - public ExceptionFromSetSetterVariant() - : base("CommonProductCategoryDatabase") - { - } - - public DbSet Categories { get; set; } - - public DbSet Products - { - get { return null; } - set { throw new Exception("SETTER"); } - } - } - - [Fact] - public void Exception_from_set_setter() - { - try - { - var ctx = new ExceptionFromSetSetterVariant(); - Assert.True(false, "Exception in set setter was swallowed."); - } - catch (Exception ex) - { - Assert.Equal("SETTER", ex.Message); - } - } - - #endregion - - #region Positive tests for tweaking set discovery using attributes at class level - - [SuppressDbSetInitialization] - private class ClassLevelSetDiscoverOnlyVariant : EmptyContext - { - public ClassLevelSetDiscoverOnlyVariant() - : base("CommonProductCategoryDatabase") - { - } - - public DbSet Products { get; set; } - public DbSet Categories { get; set; } - } - - [Fact] - public void - SuppressDbSetInitializationAttribute_on_context_class_results_in_entities_in_model_but_sets_not_initialized() - { - using (var context = new ClassLevelSetDiscoverOnlyVariant()) - { - Assert.Null(context.Products); - Assert.Null(context.Categories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - #endregion - - #region Positive tests for tweaking set discovery using attributes at property level - - private class PropertyLevelSetDiscoverOnlyVariant : EmptyContext - { - public PropertyLevelSetDiscoverOnlyVariant() - : base("CommonProductCategoryDatabase") - { - } - - public DbSet Products { get; set; } - - [SuppressDbSetInitialization] - public DbSet Categories { get; set; } - } - - [Fact] - public void SuppressDbSetInitializationAttribute_on_property_results_in_that_entity_in_model_but_its_set_not_initialized() - { - using (var context = new PropertyLevelSetDiscoverOnlyVariant()) - { - Assert.NotNull(context.Products); - Assert.Null(context.Categories); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - #endregion - - #region Positive Set tests - - [Fact] - public void Can_create_DbSet() - { - using (var context = new SimpleModelContext()) - { - var set = context.Set(); - Assert.IsType>(set); - - var entity = set.FirstOrDefault(); - Assert.IsType(entity); - Assert.Equal(EntityState.Unchanged, GetStateEntry(context, entity).State); - } - } - - [Fact] - public void Can_create_non_generic_DbSet() - { - using (var context = new SimpleModelContext()) - { - var set = context.Set(typeof(Category)); - Assert.Equal(typeof(Category), set.ElementType); - - var entity = set.Cast().FirstOrDefault(); - Assert.IsType(entity); - Assert.Equal(EntityState.Unchanged, GetStateEntry(context, entity).State); - } - } - - [Fact] - public void Can_create_DbSet_for_base_type() - { - using (var context = new SimpleModelContext()) - { - var set = context.Set(); - Assert.IsType>(set); - - var entity = set.FirstOrDefault(); - Assert.IsType(entity); - } - } - - [Fact] - public void Can_create_non_generic_DbSet_for_base_type() - { - using (var context = new SimpleModelContext()) - { - var set = context.Set(typeof(Product)); - Assert.Equal(typeof(Product), set.ElementType); - - var entity = set.Cast().FirstOrDefault(); - Assert.IsType(entity); - } - } - - [Fact] - public void Can_create_DbSet_for_abstract_base_type() - { - using (var context = new AdvancedPatternsMasterContext()) - { - var set = context.Set(); - Assert.IsType>(set); - - var entity = set.FirstOrDefault(); - Assert.IsAssignableFrom(entity); - } - } - - [Fact] - public void Can_create_non_generic_DbSet_for_abstract_base_type() - { - using (var context = new AdvancedPatternsMasterContext()) - { - var set = context.Set(typeof(Employee)); - Assert.Equal(typeof(Employee), set.ElementType); - - var entity = set.Cast().FirstOrDefault(); - Assert.IsAssignableFrom(entity); - } - } - - [Fact] - public void Can_create_DbSet_for_derived_type() - { - using (var context = new SimpleModelContext()) - { - var set = context.Set(); - Assert.IsType>(set); - - var entity = set.FirstOrDefault(); - Assert.IsType(entity); - Assert.Equal(EntityState.Unchanged, GetStateEntry(context, entity).State); - } - } - - [Fact] - public void Can_create_non_generic_DbSet_for_derived_type() - { - using (var context = new SimpleModelContext()) - { - var set = context.Set(typeof(FeaturedProduct)); - Assert.Equal(typeof(FeaturedProduct), set.ElementType); - - var entity = set.Cast().FirstOrDefault(); - Assert.IsType(entity); - Assert.Equal(EntityState.Unchanged, GetStateEntry(context, entity).State); - } - } - - [Fact] - public void Set_method_returns_the_same_instance_each_invocation() - { - using (var context = new SimpleModelContext()) - { - var set1 = context.Set(); - var set2 = context.Set(); - - Assert.Same(set1, set2); - Assert.Same(set1, context.Products); - } - } - - [Fact] - public void Non_generic_Set_method_returns_the_same_instance_each_invocation() - { - using (var context = new SimpleModelContext()) - { - var set1 = context.Set(typeof(Product)); - var set2 = context.Set(typeof(Product)); - - Assert.Same(set1, set2); - } - } - - #endregion - - #region Positive OnModelCreating tests - - public class TweakingModelVariant : EmptyContext - { - public DbSet Products { get; set; } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - modelBuilder.Entity().HasKey(c => c.Id); - modelBuilder.Entity().HasMany(c => c.Products).WithOptional(p => p.Category).HasForeignKey( - p => p.CategoryId); - base.OnModelCreating(modelBuilder); - } - } - - [Fact] - public void Model_can_be_tweaked_in_OnModelCreating() - { - using (var context = new TweakingModelVariant()) - { - Assert.NotNull(context.Products); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - } - } - - public class OnModelCreatingVariant : DbContext - { - public DbSet Products { get; set; } - - public static int OnModelCreatingCount { get; set; } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - OnModelCreatingCount++; - } - } - - [Fact] - public void OnModelCreating_is_only_called_once_by_default() - { - using (var context = new OnModelCreatingVariant()) - { - context.Assert().IsInModel(); - } - Assert.Equal(1, OnModelCreatingVariant.OnModelCreatingCount); - - using (var context = new OnModelCreatingVariant()) - { - context.Assert().IsInModel(); - } - Assert.Equal(1, OnModelCreatingVariant.OnModelCreatingCount); - - using (var context = new OnModelCreatingVariant()) - { - context.Assert().IsInModel(); - } - Assert.Equal(1, OnModelCreatingVariant.OnModelCreatingCount); - } - - public class SillyCallToOnModelCreatingVariant : EmptyContext - { - public SillyCallToOnModelCreatingVariant() - : base(DefaultDbName()) - { - OnModelCreating(new DbModelBuilder()); - } - } - - [Fact] - public void Calling_OnModelCreating_explicitly_is_noop() - { - using (var context = new SillyCallToOnModelCreatingVariant()) - { - } - } - - [Fact] - public void Can_use_context_during_construction_with_tweaking() - { - using (var context = new UseContextInCtorModelTweakingVariant()) - { - Assert.NotNull(context.Products); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - - Assert.False(GetObjectContext(context).ContextOptions.LazyLoadingEnabled); - Assert.False(context.Configuration.LazyLoadingEnabled); - } - } - - public class UseContextInCtorModelTweakingVariant : EmptyContext - { - public UseContextInCtorModelTweakingVariant() - { - ((IObjectContextAdapter)this).ObjectContext.ContextOptions.LazyLoadingEnabled = false; - } - - public DbSet Products { get; set; } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - modelBuilder.Entity().HasKey(c => c.Id); - modelBuilder.Entity().HasMany(c => c.Products).WithOptional(p => p.Category).HasForeignKey( - p => p.CategoryId); - base.OnModelCreating(modelBuilder); - } - } - - #endregion - - #region Negative OnModelCreating tests - - public class UseModeWhileCreatingVariant : EmptyContext - { - public UseModeWhileCreatingVariant() - : base("CommonProductCategoryDatabase") - { - } - - public DbSet Products { get; set; } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - Products.FirstOrDefault(); - base.OnModelCreating(modelBuilder); - } - } - - [Fact] - public void Using_context_during_OnModelCreating_throws() - { - using (var context = new UseModeWhileCreatingVariant()) - { - Assert.Throws(() => context.Products.FirstOrDefault()).ValidateMessage( - "DbContext_ContextUsedInModelCreating"); - } - } - - #endregion - - #region Positive non-derived context tests using an existing model - - [Fact] - public void Model_passed_to_DbContext_string_constructor_is_used_to_back_the_context() - { - Model_passed_to_DbContext_constructor_is_used_to_back_the_context( - model => new DbContext(DefaultDbName(), model)); - } - - [Fact] - public void Model_passed_to_DbContext_DbConnection_constructor_is_used_to_back_the_context() - { - using (var connection = SimpleConnection()) - { - Model_passed_to_DbContext_constructor_is_used_to_back_the_context( - model => new DbContext(connection, model, contextOwnsConnection: false)); - } - } - - private void Model_passed_to_DbContext_constructor_is_used_to_back_the_context( - Func factory) - { - using (var context = factory(CreateSimpleModel())) - { - context.Assert().IsInModel(); - context.Assert().IsInModel(); - context.Assert().IsNotInModel(); - - // Verify that we can use sets and we are connected to the correct database - Assert.Equal("Marmite", context.Set().Find(1).Name); - Assert.Equal("Foods", context.Set().Find("Foods").Id); - } - } - - private static DbCompiledModel CreateSimpleModel() - { - return SimpleModelContext.CreateBuilder().Build(ProviderRegistry.Sql2008_ProviderInfo).Compile(); - } - - #endregion - - #region Positive derived context tests using existing model - - private class DerivedContextWithMismatchedModel : DbContext - { - public DerivedContextWithMismatchedModel(DbCompiledModel model) - : base(model) - { - } - - public DerivedContextWithMismatchedModel(string nameOrConnectionString, DbCompiledModel model) - : base(nameOrConnectionString, model) - { - } - - public DerivedContextWithMismatchedModel(DbConnection existingConnection, DbCompiledModel model) - : base(existingConnection, model, contextOwnsConnection: false) - { - } - - public DbSet Logins { get; set; } - } - - [Fact] - public void Model_passed_to_derived_DbContext_constructor_is_used_and_the_sets_on_context_are_not_used() - { - // In this case we can't control the name of the database, so it won't be the normal SimpleModel database - using (var context = new DerivedContextWithMismatchedModel(CreateSimpleModel())) - { - context.Assert().IsInModel(); - context.Assert().IsInModel(); - context.Assert().IsNotInModel(); - - Assert.Throws(() => context.Logins.ToList()).ValidateMessage( - "DbSet_EntityTypeNotInModel", "Login"); - } - } - - [Fact] - public void Model_passed_to_derived_DbContext_string_constructor_is_used_and_the_sets_on_context_are_not_used() - { - Model_passed_to_DbContext_constructor_is_used_to_back_the_context( - model => new DerivedContextWithMismatchedModel(DefaultDbName(), model)); - } - - [Fact] - public void - Model_passed_to_derived_DbContext_DbConnection_constructor_is_used_and_the_sets_on_context_are_not_used() - { - using (var connection = SimpleConnection()) - { - Model_passed_to_DbContext_constructor_is_used_to_back_the_context( - model => new DerivedContextWithMismatchedModel(connection, model)); - } - } - - #endregion - - #region Lazy loading tests - - private void ValidateLazyLoading(F1Context context, bool lazyLoadingEnabled) - { - Assert.Equal(lazyLoadingEnabled, context.Configuration.LazyLoadingEnabled); - Assert.Equal(lazyLoadingEnabled, GetObjectContext(context).ContextOptions.LazyLoadingEnabled); - - context.ChangeTracker.Entries().ToList().ForEach(e => e.State = EntityState.Detached); - - var team = context.Drivers.First().Team; - if (lazyLoadingEnabled) - { - Assert.NotNull(team); - } - else - { - Assert.Null(team); - } - } - - private static DbCompiledModel CreateF1Model() - { - var builder = new DbModelBuilder(); - - F1Context.AdditionalModelConfiguration(builder); - - return builder.Build(ProviderRegistry.Sql2008_ProviderInfo).Compile(); - } - - [Fact] - public void Lazy_loading_is_on_by_default_when_using_empty_constructor() - { - using (var context = new F1Context()) - { - ValidateLazyLoading(context, lazyLoadingEnabled: true); - } - } - - [Fact] - public void Lazy_loading_is_on_by_default_when_using_String_constructor() - { - using (var context = new F1Context(DefaultDbName())) - { - ValidateLazyLoading(context, lazyLoadingEnabled: true); - } - } - - [Fact] - public void Lazy_loading_is_on_by_default_when_using_DbCompiledModel_constructor() - { - using (var context = new F1Context(CreateF1Model())) - { - ValidateLazyLoading(context, lazyLoadingEnabled: true); - } - } - - [Fact] - public void Lazy_loading_is_on_by_default_when_using_String_and_DbCompiledModel_constructor() - { - using (var context = new F1Context(DefaultDbName(), CreateF1Model())) - { - ValidateLazyLoading(context, lazyLoadingEnabled: true); - } - } - - [Fact] - public void Lazy_loading_is_on_by_default_when_using_DbConnection_constructor() - { - using (var context = new F1Context(SimpleConnection(), contextOwnsConnection: true)) - { - ValidateLazyLoading(context, lazyLoadingEnabled: true); - } - } - - [Fact] - public void Lazy_loading_is_on_by_default_when_using_DbConnection_and_DbCompiledModel_constructor() - { - using ( - var context = new F1Context(SimpleConnection(), CreateF1Model(), contextOwnsConnection: true) - ) - { - ValidateLazyLoading(context, lazyLoadingEnabled: true); - } - } - - [Fact] - public void Lazy_loading_is_on_by_default_when_using_entity_connection_string_in_constructor() - { - using (var context = new DbContext(SimpleModelEntityConnectionString)) - { - Assert.True(context.Configuration.LazyLoadingEnabled); - var objectContext = GetObjectContext(context); - Assert.True(objectContext.ContextOptions.LazyLoadingEnabled); - } - } - - [Fact] - public void Lazy_loading_is_on_by_default_when_using_EntityConnection_object_in_constructor() - { - using ( - var context = new DbContext( - new EntityConnection(SimpleModelEntityConnectionString), - contextOwnsConnection: true)) - { - Assert.True(context.Configuration.LazyLoadingEnabled); - var objectContext = GetObjectContext(context); - Assert.True(objectContext.ContextOptions.LazyLoadingEnabled); - } - } - - [Fact] - public void Lazy_loading_flag_can_be_inherited_from_ObjectContext_as_true_when_using_ObjectContext_constructor() - { - Lazy_loading_flag_is_inherited_from_ObjectContext_when_using_ObjectContext_constructor( - lazyLoadingEnabled: true); - } - - [Fact] - public void Lazy_loading_flag_can_be_inherited_from_ObjectContext_as_false_when_using_ObjectContext_constructor() - { - Lazy_loading_flag_is_inherited_from_ObjectContext_when_using_ObjectContext_constructor( - lazyLoadingEnabled: false); - } - - private void Lazy_loading_flag_is_inherited_from_ObjectContext_when_using_ObjectContext_constructor( - bool lazyLoadingEnabled) - { - var objectContext = GetObjectContext(new F1Context()); - objectContext.ContextOptions.LazyLoadingEnabled = lazyLoadingEnabled; - - using (var context = new F1Context(objectContext, dbContextOwnsObjectContext: true)) - { - ValidateLazyLoading(context, lazyLoadingEnabled); - } - } - - [Fact] - public void Lazy_loading_can_be_switched_off_in_constructor_which_calls_to_base_empty_constructor() - { - using (var context = new F1Context(lazyLoadingEnabled: false)) - { - ValidateLazyLoading(context, lazyLoadingEnabled: false); - } - } - - [Fact] - public void Lazy_loading_can_be_switched_off_in_constructor_which_calls_to_base_String_constructor() - { - using (var context = new F1Context(DefaultDbName(), lazyLoadingEnabled: false)) - { - ValidateLazyLoading(context, lazyLoadingEnabled: false); - } - } - - [Fact] - public void Lazy_loading_can_be_switched_off_in_constructor_which_calls_to_base_DbCompiledModel_constructor() - { - using (var context = new F1Context(CreateF1Model(), lazyLoadingEnabled: false)) - { - ValidateLazyLoading(context, lazyLoadingEnabled: false); - } - } - - [Fact] - public void - Lazy_loading_can_be_switched_off_in_constructor_which_calls_to_base_String_and_DbCompiledModel_constructor() - { - using (var context = new F1Context(DefaultDbName(), CreateF1Model(), lazyLoadingEnabled: false)) - { - ValidateLazyLoading(context, lazyLoadingEnabled: false); - } - } - - [Fact] - public void Lazy_loading_can_be_switched_off_in_constructor_which_calls_to_base_DbConnection_constructor() - { - using ( - var context = new F1Context( - SimpleConnection(), contextOwnsConnection: true, - lazyLoadingEnabled: false)) - { - ValidateLazyLoading(context, lazyLoadingEnabled: false); - } - } - - [Fact] - public void Lazy_loading_can_be_switched_off_in_constructor_which_calls_to_base_DbConnection_and_DbCompiledModel_constructor() - { - using ( - var context = new F1Context( - SimpleConnection(), CreateF1Model(), contextOwnsConnection: true, - lazyLoadingEnabled: false)) - { - ValidateLazyLoading(context, lazyLoadingEnabled: false); - } - } - - [Fact] - public void Lazy_loading_can_be_switched_off_in_constructor_which_calls_to_base_ObjectContext_constructor() - { - var objectContext = GetObjectContext(new F1Context()); - objectContext.ContextOptions.LazyLoadingEnabled = true; - - using ( - var context = new F1Context(objectContext, dbContextOwnsObjectContext: true, lazyLoadingEnabled: false)) - { - ValidateLazyLoading(context, false); - } - } - - public class LazyLoadingFlagTestContext : EmptyContext - { - public LazyLoadingFlagTestContext() - : base(DefaultDbName()) - { - } - - public LazyLoadingFlagTestContext(string connectionString) - : base(connectionString) - { - } - - public LazyLoadingFlagTestContext(DbConnection connection) - : base(connection, contextOwnsConnection: true) - { - } - - public bool ModelCreated { get; set; } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - ModelCreated = true; - base.OnModelCreating(modelBuilder); - } - } - - [Fact] - public void Lazy_loading_can_be_changed_after_DbContext_is_created_but_before_initialization_when_using_entity_connection_string() - { - Lazy_loading_can_be_changed_after_DbContext_is_created_but_before_initialization( - () => new LazyLoadingFlagTestContext(SimpleModelEntityConnectionString), expectOnModelCreation: false); - } - - [Fact] - public void Lazy_loading_can_be_changed_after_DbContext_is_created_but_before_initialization_when_using_EntityConnection() - { - Lazy_loading_can_be_changed_after_DbContext_is_created_but_before_initialization( - () => new LazyLoadingFlagTestContext(new EntityConnection(SimpleModelEntityConnectionString)), - expectOnModelCreation: false); - } - - [Fact] - public void - Lazy_loading_can_be_changed_after_DbContext_is_created_without_causing_ObjectContext_initialization_when_using_code_first() - { - Lazy_loading_can_be_changed_after_DbContext_is_created_but_before_initialization( - () => new LazyLoadingFlagTestContext(), expectOnModelCreation: true); - } - - private void Lazy_loading_can_be_changed_after_DbContext_is_created_but_before_initialization( - Func createContext, bool expectOnModelCreation) - { - using (var context = createContext()) - { - Assert.True(context.Configuration.LazyLoadingEnabled); - - context.Configuration.LazyLoadingEnabled = false; - Assert.False(context.Configuration.LazyLoadingEnabled); - - context.Configuration.LazyLoadingEnabled = true; - Assert.True(context.Configuration.LazyLoadingEnabled); - - context.Configuration.LazyLoadingEnabled = false; - Assert.False(context.ModelCreated); - - Assert.Equal(false, GetObjectContext(context).ContextOptions.LazyLoadingEnabled); - Assert.Equal(expectOnModelCreation, context.ModelCreated); - } - } - - [Fact] - public void - Changing_lazy_loading_flag_after_ObjectContext_is_initialized_causes_lazy_loading_flag_in_DbContext_and_ObjectContext_to_change( - - ) - { - using (var context = new F1Context()) - { - ValidateLazyLoading(context, lazyLoadingEnabled: true); - - context.Configuration.LazyLoadingEnabled = false; - ValidateLazyLoading(context, lazyLoadingEnabled: false); - - context.Configuration.LazyLoadingEnabled = true; - ValidateLazyLoading(context, lazyLoadingEnabled: true); - } - } - - [Fact] - public void Changing_lazy_loading_flag_in_ObjectContext_causes_lazy_loading_flag_in_DbContext_and_ObjectContext_to_change() - { - using (var context = new F1Context()) - { - ValidateLazyLoading(context, lazyLoadingEnabled: true); - - GetObjectContext(context).ContextOptions.LazyLoadingEnabled = false; - ValidateLazyLoading(context, lazyLoadingEnabled: false); - - GetObjectContext(context).ContextOptions.LazyLoadingEnabled = true; - ValidateLazyLoading(context, lazyLoadingEnabled: true); - } - } - - [Fact] - public void Entity_reference_does_not_get_lazily_loaded_if_LazyLoadingEnabled_is_set_to_false() - { - using (var context = new F1Context()) - { - context.Configuration.LazyLoadingEnabled = false; - var driver = context.Drivers.FirstOrDefault(); - - Assert.Null(driver.Team); - } - } - - [Fact] - public void Entity_collection_does_not_get_lazily_loaded_if_LazyLoadingEnabled_is_set_to_false() - { - using (var context = new F1Context()) - { - context.Configuration.LazyLoadingEnabled = false; - var team = context.Teams.FirstOrDefault(); - - Assert.Equal(0, team.Drivers.Count); - } - } - - [Fact] - public void Lazy_loading_throws_when_done_outside_context_scope() - { - Team team; - using (var context = new F1Context()) - { - team = context.Teams.FirstOrDefault(); - } - - Assert.Throws(() => team.Engine); - Assert.Throws(() => team.Drivers); - } - - [Fact] - public void Lazy_loading_wires_up_references_navigations_correctly() - { - using (var context = new F1Context()) - { - // get driver and engine supplier that would navigate to the same engine - var query = context.Drivers.Select(d => new { DriverId = d.Id, EngineSupplierId = d.Team.Engine.EngineSupplier.Id }).AsNoTracking(); - var tuple = query.FirstOrDefault(); - var driverId = tuple.DriverId; - var engineSupplierId = tuple.EngineSupplierId; - - var driver = context.Drivers.Where(d => d.Id == driverId).Single(); - var team = driver.Team; - - var engineSupplier = context.EngineSuppliers.Where(es => es.Id == engineSupplierId).Single(); - var engine = engineSupplier.Engines; - - context.Configuration.LazyLoadingEnabled = false; - - Assert.NotNull(team.Engine); - } - } - - [Fact] - public void Lazy_loading_wires_up_collection_navigations_correctly() - { - using (var context = new F1Context()) - { - var query = context.Sponsors.SelectMany(s => s.Teams, (s, t) => new { SponsorId = s.Id, EngineId = t.Engine.Id }).AsNoTracking(); - var tuple = query.FirstOrDefault(); - var sponsor = context.Sponsors.Where(s => s.Id == tuple.SponsorId).Single(); - var sponsorTeams = sponsor.Teams; - - var engine = context.Engines.Where(e => e.Id == tuple.EngineId).Single(); - - context.Configuration.LazyLoadingEnabled = false; - - Assert.True(engine.Teams.Count > 0); - bool engineTeamsContainSponsorTeam = false; - foreach (var sponsorTeam in sponsorTeams) - { - if (engine.Teams.Contains(sponsorTeam)) - { - engineTeamsContainSponsorTeam = true; - } - } - - Assert.True(engineTeamsContainSponsorTeam); - - foreach (var engineTeam in engine.Teams) - { - Assert.True(sponsorTeams.Contains(engineTeam)); - } - } - } - - [Fact] - public void Lazy_loading_many_to_many_navigation_works_properly() - { - using (var context = new F1Context()) - { - var teamId = context.Teams.OrderBy(t => t.Id).AsNoTracking().FirstOrDefault().Id; - var sponsorsId = context.Teams.Where(t => t.Id == teamId).SelectMany(t => t.Sponsors).AsNoTracking().Select(s => s.Id).ToList(); - - var team = context.Teams.Where(t => t.Id == teamId).Single(); - var sponsors = team.Sponsors; - - context.Configuration.LazyLoadingEnabled = false; - - foreach (var sponsor in sponsors) - { - Assert.True(sponsorsId.Contains(sponsor.Id)); - } - } - } - - #endregion - - #region Proxy creation tests - - private void ValidateProxyCreation(F1Context context, bool proxyCreationEnabled) - { - Assert.Equal(proxyCreationEnabled, context.Configuration.ProxyCreationEnabled); - Assert.Equal(proxyCreationEnabled, GetObjectContext(context).ContextOptions.ProxyCreationEnabled); - - context.ChangeTracker.Entries().ToList().ForEach(e => e.State = EntityState.Detached); - - var driver = context.Drivers.First(); - if (proxyCreationEnabled) - { - Assert.NotEqual(typeof(Driver), driver.GetType()); - } - else - { - Assert.Equal(typeof(Driver), driver.GetType()); - } - } - - [Fact] - public void Proxy_creation_is_on_by_default_when_using_empty_constructor() - { - using (var context = new F1Context()) - { - ValidateProxyCreation(context, proxyCreationEnabled: true); - } - } - - [Fact] - public void Proxy_creation_is_on_by_default_when_using_String_constructor() - { - using (var context = new F1Context(DefaultDbName())) - { - ValidateProxyCreation(context, proxyCreationEnabled: true); - } - } - - [Fact] - public void Proxy_creation_is_on_by_default_when_using_DbCompiledModel_constructor() - { - using (var context = new F1Context(CreateF1Model())) - { - ValidateProxyCreation(context, proxyCreationEnabled: true); - } - } - - [Fact] - public void Proxy_creation_is_on_by_default_when_using_String_and_DbCompiledModel_constructor() - { - using (var context = new F1Context(DefaultDbName(), CreateF1Model())) - { - ValidateProxyCreation(context, proxyCreationEnabled: true); - } - } - - [Fact] - public void Proxy_creation_is_on_by_default_when_using_DbConnection_constructor() - { - using (var context = new F1Context(SimpleConnection(), contextOwnsConnection: true)) - { - ValidateProxyCreation(context, proxyCreationEnabled: true); - } - } - - [Fact] - public void Proxy_creation_is_on_by_default_when_using_DbConnection_and_DbCompiledModel_constructor() - { - using ( - var context = new F1Context(SimpleConnection(), CreateF1Model(), contextOwnsConnection: true) - ) - { - ValidateProxyCreation(context, proxyCreationEnabled: true); - } - } - - [Fact] - public void Proxy_creation_is_on_by_default_when_using_entity_connection_string_in_constructor() - { - using (var context = new DbContext(SimpleModelEntityConnectionString)) - { - Assert.True(context.Configuration.ProxyCreationEnabled); - var objectContext = GetObjectContext(context); - Assert.True(objectContext.ContextOptions.ProxyCreationEnabled); - } - } - - [Fact] - public void Proxy_creation_is_on_by_default_when_using_EntityConnection_object_in_constructor() - { - using ( - var context = new DbContext( - new EntityConnection(SimpleModelEntityConnectionString), - contextOwnsConnection: true)) - { - Assert.True(context.Configuration.ProxyCreationEnabled); - var objectContext = GetObjectContext(context); - Assert.True(objectContext.ContextOptions.ProxyCreationEnabled); - } - } - - [Fact] - public void Proxy_creation_flag_can_be_inherited_from_ObjectContext_as_true_when_using_ObjectContext_constructor() - { - Proxy_creation_flag_is_inherited_from_ObjectContext_when_using_ObjectContext_constructor( - proxyCreationEnabled: true); - } - - [Fact] - public void - Proxy_creation_flag_can_be_inherited_from_ObjectContext_as_false_when_using_ObjectContext_constructor() - { - Proxy_creation_flag_is_inherited_from_ObjectContext_when_using_ObjectContext_constructor( - proxyCreationEnabled: false); - } - - private void Proxy_creation_flag_is_inherited_from_ObjectContext_when_using_ObjectContext_constructor( - bool proxyCreationEnabled) - { - var objectContext = GetObjectContext(new F1Context()); - objectContext.ContextOptions.ProxyCreationEnabled = proxyCreationEnabled; - - using (var context = new F1Context(objectContext, dbContextOwnsObjectContext: true)) - { - ValidateProxyCreation(context, proxyCreationEnabled); - } - } - - [Fact] - public void Proxy_creation_can_be_switched_off_in_constructor_which_calls_to_base_empty_constructor() - { - using (var context = new F1Context(proxyCreationEnabled: false)) - { - ValidateProxyCreation(context, proxyCreationEnabled: false); - } - } - - [Fact] - public void Proxy_creation_can_be_switched_off_in_constructor_which_calls_to_base_String_constructor() - { - using (var context = new F1Context(DefaultDbName(), proxyCreationEnabled: false)) - { - ValidateProxyCreation(context, proxyCreationEnabled: false); - } - } - - [Fact] - public void Proxy_creation_can_be_switched_off_in_constructor_which_calls_to_base_DbCompiledModel_constructor() - { - using (var context = new F1Context(CreateF1Model(), proxyCreationEnabled: false)) - { - ValidateProxyCreation(context, proxyCreationEnabled: false); - } - } - - [Fact] - public void Proxy_creation_can_be_switched_off_in_constructor_which_calls_to_base_String_and_DbCompiledModel_constructor() - { - using (var context = new F1Context(DefaultDbName(), CreateF1Model(), proxyCreationEnabled: false) - ) - { - ValidateProxyCreation(context, proxyCreationEnabled: false); - } - } - - [Fact] - public void Proxy_creation_can_be_switched_off_in_constructor_which_calls_to_base_DbConnection_constructor() - { - using ( - var context = new F1Context( - SimpleConnection(), contextOwnsConnection: true, - proxyCreationEnabled: false)) - { - ValidateProxyCreation(context, proxyCreationEnabled: false); - } - } - - [Fact] - public void Proxy_creation_can_be_switched_off_in_constructor_which_calls_to_base_DbConnection_and_DbCompiledModel_constructor() - { - using ( - var context = new F1Context( - SimpleConnection(), CreateF1Model(), contextOwnsConnection: true, - proxyCreationEnabled: false)) - { - ValidateProxyCreation(context, proxyCreationEnabled: false); - } - } - - [Fact] - public void Proxy_creation_can_be_switched_off_in_constructor_which_calls_to_base_ObjectContext_constructor() - { - var objectContext = GetObjectContext(new F1Context()); - objectContext.ContextOptions.ProxyCreationEnabled = true; - - using ( - var context = new F1Context(objectContext, dbContextOwnsObjectContext: true, proxyCreationEnabled: false) - ) - { - ValidateProxyCreation(context, false); - } - } - - public class ProxyCreationFlagTestContext : EmptyContext - { - public ProxyCreationFlagTestContext() - : base(DefaultDbName()) - { - } - - public ProxyCreationFlagTestContext(string connectionString) - : base(connectionString) - { - } - - public ProxyCreationFlagTestContext(DbConnection connection) - : base(connection, contextOwnsConnection: true) - { - } - - public bool ModelCreated { get; set; } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - ModelCreated = true; - base.OnModelCreating(modelBuilder); - } - } - - [Fact] - public void Proxy_creation_can_be_changed_after_DbContext_is_created_but_before_initialization_when_using_entity_connection_string() - { - Proxy_creation_can_be_changed_after_DbContext_is_created_but_before_initialization( - () => new ProxyCreationFlagTestContext(SimpleModelEntityConnectionString), expectOnModelCreation: false); - } - - [Fact] - public void Proxy_creation_can_be_changed_after_DbContext_is_created_but_before_initialization_when_using_EntityConnection() - { - Proxy_creation_can_be_changed_after_DbContext_is_created_but_before_initialization( - () => new ProxyCreationFlagTestContext(new EntityConnection(SimpleModelEntityConnectionString)), - expectOnModelCreation: false); - } - - [Fact] - public void - Proxy_creation_can_be_changed_after_DbContext_is_created_without_causing_ObjectContext_initialization_when_using_code_first() - { - Proxy_creation_can_be_changed_after_DbContext_is_created_but_before_initialization( - () => new ProxyCreationFlagTestContext(), expectOnModelCreation: true); - } - - private void Proxy_creation_can_be_changed_after_DbContext_is_created_but_before_initialization( - Func createContext, bool expectOnModelCreation) - { - using (var context = createContext()) - { - Assert.True(context.Configuration.ProxyCreationEnabled); - - context.Configuration.ProxyCreationEnabled = false; - Assert.False(context.Configuration.ProxyCreationEnabled); - - context.Configuration.ProxyCreationEnabled = true; - Assert.True(context.Configuration.ProxyCreationEnabled); - - context.Configuration.ProxyCreationEnabled = false; - Assert.False(context.ModelCreated); - - Assert.Equal(false, GetObjectContext(context).ContextOptions.ProxyCreationEnabled); - Assert.Equal(expectOnModelCreation, context.ModelCreated); - } - } - - [Fact] - public void - Changing_proxy_creation_flag_after_ObjectContext_is_initialized_causes_proxy_creation_flag_in_DbContext_and_ObjectContext_to_change - () - { - using (var context = new F1Context()) - { - ValidateProxyCreation(context, proxyCreationEnabled: true); - - context.Configuration.ProxyCreationEnabled = false; - ValidateProxyCreation(context, proxyCreationEnabled: false); - - context.Configuration.ProxyCreationEnabled = true; - ValidateProxyCreation(context, proxyCreationEnabled: true); - } - } - - [Fact] - public void Changing_proxy_creation_flag_in_ObjectContext_causes_proxy_creation_flag_in_DbContext_and_ObjectContext_to_change() - { - using (var context = new F1Context()) - { - ValidateProxyCreation(context, proxyCreationEnabled: true); - - GetObjectContext(context).ContextOptions.ProxyCreationEnabled = false; - ValidateProxyCreation(context, proxyCreationEnabled: false); - - GetObjectContext(context).ContextOptions.ProxyCreationEnabled = true; - ValidateProxyCreation(context, proxyCreationEnabled: true); - } - } - - #endregion - - #region DetectChanges tests - - [Fact] - public void AutoDetectChangesEnabled_is_on_by_default_and_can_be_changed() - { - using (var context = new F1Context()) - { - Assert.True(context.Configuration.AutoDetectChangesEnabled); - - context.Configuration.AutoDetectChangesEnabled = false; - - Assert.False(context.Configuration.AutoDetectChangesEnabled); - } - } - - [Fact] - public void Explicitly_calling_DetectChanges_results_in_change_detection() - { - TestDetectChanges(c => c.ChangeTracker.DetectChanges(), autoDetectChanges: true); - } - - [Fact] - public void - Explicitly_calling_DetectChanges_results_in_change_detection_even_when_AutoDetectChangesEnabled_is_off() - { - TestDetectChanges(c => c.ChangeTracker.DetectChanges(), autoDetectChanges: false, expectDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_called_by_Find_on_generic_DbSet_when_AutoDetectChangesEnabled_is_on() - { - TestDetectChanges(c => c.Teams.Find(Team.Williams), autoDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_called_by_Add_on_generic_DbSet_when_AutoDetectChangesEnabled_is_on() - { - TestDetectChanges(c => c.Drivers.Add(new Driver()), autoDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_called_by_Attach_on_generic_DbSet_when_AutoDetectChangesEnabled_is_on() - { - TestDetectChanges(c => c.Drivers.Attach(new Driver()), autoDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_called_by_Remove_on_generic_DbSet_when_AutoDetectChangesEnabled_is_on() - { - Driver driver = null; - TestDetectChanges( - c => { driver = c.Drivers.Add(new Driver()); }, c => c.Drivers.Remove(driver), - autoDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_called_by_Local_on_generic_DbSet_when_AutoDetectChangesEnabled_is_on() - { - TestDetectChanges(c => { var _ = c.Drivers.Local; }, autoDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_called_by_Find_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_on() - { - TestDetectChanges(c => c.Set(typeof(Team)).Find(Team.Williams), autoDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_called_by_Add_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_on() - { - TestDetectChanges(c => c.Set(typeof(Driver)).Add(new Driver()), autoDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_called_by_Attach_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_on() - { - TestDetectChanges(c => c.Set(typeof(Driver)).Attach(new Driver()), autoDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_called_by_Remove_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_on() - { - Driver driver = null; - TestDetectChanges( - c => { driver = c.Drivers.Add(new Driver()); }, c => c.Set(typeof(Driver)).Remove(driver), - autoDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_called_by_Local_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_on() - { - TestDetectChanges(c => { var _ = c.Set(typeof(Driver)).Local; }, autoDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_called_by_non_generic_Entry_when_AutoDetectChangesEnabled_is_on() - { - TestDetectChanges(c => c.Entry((object)new Driver()), autoDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_called_by_generic_Entry_when_AutoDetectChangesEnabled_is_on() - { - TestDetectChanges(c => c.Entry(new Driver()), autoDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_called_by_non_generic_Entries_when_AutoDetectChangesEnabled_is_on() - { - TestDetectChanges(c => c.ChangeTracker.Entries(), autoDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_called_by_generic_Entries_when_AutoDetectChangesEnabled_is_on() - { - TestDetectChanges(c => c.ChangeTracker.Entries(), autoDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_not_called_by_Find_on_generic_DbSet_when_AutoDetectChangesEnabled_is_off() - { - TestDetectChanges(c => c.Teams.Find(Team.Williams), autoDetectChanges: false); - } - - [Fact] - public void DetectChanges_is_not_called_by_Add_on_generic_DbSet_when_AutoDetectChangesEnabled_is_off() - { - TestDetectChanges(c => c.Drivers.Add(new Driver()), autoDetectChanges: false); - } - - [Fact] - public void DetectChanges_is_not_called_by_Attach_on_generic_DbSet_when_AutoDetectChangesEnabled_is_off() - { - TestDetectChanges(c => c.Drivers.Attach(new Driver()), autoDetectChanges: false); - } - - [Fact] - public void DetectChanges_is_not_called_by_Remove_on_generic_DbSet_when_AutoDetectChangesEnabled_is_off() - { - Driver driver = null; - TestDetectChanges( - c => { driver = c.Drivers.Add(new Driver()); }, c => c.Drivers.Remove(driver), - autoDetectChanges: false); - } - - [Fact] - public void DetectChanges_is_not_called_by_Local_on_generic_DbSet_when_AutoDetectChangesEnabled_is_off() - { - TestDetectChanges(c => { var _ = c.Drivers.Local; }, autoDetectChanges: false); - } - - [Fact] - public void DetectChanges_is_not_called_by_Find_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_off() - { - TestDetectChanges(c => c.Set(typeof(Team)).Find(Team.Williams), autoDetectChanges: false); - } - - [Fact] - public void DetectChanges_is_not_called_by_Add_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_off() - { - TestDetectChanges(c => c.Set(typeof(Driver)).Add(new Driver()), autoDetectChanges: false); - } - - [Fact] - public void DetectChanges_is_not_called_by_Attach_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_off() - { - TestDetectChanges(c => c.Set(typeof(Driver)).Attach(new Driver()), autoDetectChanges: false); - } - - [Fact] - public void DetectChanges_is_not_called_by_Remove_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_off() - { - Driver driver = null; - TestDetectChanges( - c => { driver = c.Drivers.Add(new Driver()); }, c => c.Set(typeof(Driver)).Remove(driver), - autoDetectChanges: false); - } - - [Fact] - public void DetectChanges_is_not_called_by_Local_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_off() - { - TestDetectChanges(c => { var _ = c.Set(typeof(Driver)).Local; }, autoDetectChanges: false); - } - - [Fact] - public void DetectChanges_is_not_called_by_non_generic_Entry_when_AutoDetectChangesEnabled_is_off() - { - TestDetectChanges(c => c.Entry((object)new Driver()), autoDetectChanges: false); - } - - [Fact] - public void DetectChanges_is_not_called_by_generic_Entry_when_AutoDetectChangesEnabled_is_off() - { - TestDetectChanges(c => c.Entry(new Driver()), autoDetectChanges: false); - } - - [Fact] - public void DetectChanges_is_not_called_by_non_generic_Entries_when_AutoDetectChangesEnabled_is_off() - { - TestDetectChanges(c => c.ChangeTracker.Entries(), autoDetectChanges: false); - } - - [Fact] - public void DetectChanges_is_not_called_by_generic_Entries_when_AutoDetectChangesEnabled_is_off() - { - TestDetectChanges(c => c.ChangeTracker.Entries(), autoDetectChanges: false); - } - - private void TestDetectChanges( - Action actOnContext, bool autoDetectChanges, - bool? expectDetectChanges = null) - { - TestDetectChanges(c => { }, actOnContext, autoDetectChanges, expectDetectChanges); - } - - private void TestDetectChanges( - Action setupContext, Action actOnContext, - bool autoDetectChanges, bool? expectDetectChanges = null) - { - using (var context = new F1Context()) - { - context.Configuration.AutoDetectChangesEnabled = autoDetectChanges; - - setupContext(context); - - var mclaren = context.Teams.Find(Team.McLaren); - var larryEntry = context.Entry( - new Driver - { - Name = "Larry David" - }); - mclaren.Drivers.Add(larryEntry.Entity); - - actOnContext(context); - - Assert.Equal( - expectDetectChanges ?? autoDetectChanges ? EntityState.Added : EntityState.Detached, - larryEntry.State); - } - } - - [Fact] - public void DetectChanges_is_called_by_SaveChanges_when_AutoDetectChangesEnabled_is_on() - { - TestDetectChangesWithSaveChanges(autoDetectChanges: true); - } - - [Fact] - public void DetectChanges_is_not_called_by_SaveChanges_when_AutoDetectChangesEnabled_is_off() - { - TestDetectChangesWithSaveChanges(autoDetectChanges: false); - } - - private void TestDetectChangesWithSaveChanges(bool autoDetectChanges) - { - using (var context = new F1Context()) - { - context.Database.Initialize(force: false); - - using (new TransactionScope()) - { - context.Configuration.AutoDetectChangesEnabled = autoDetectChanges; - - var mclaren = context.Teams.Find(Team.McLaren); - var larryEntry = context.Entry( - new Driver - { - Name = "Larry David" - }); - mclaren.Drivers.Add(larryEntry.Entity); - - Assert.Equal(autoDetectChanges ? EntityState.Added : EntityState.Detached, larryEntry.State); - - context.SaveChanges(); - - Assert.Equal(autoDetectChanges ? EntityState.Unchanged : EntityState.Detached, larryEntry.State); - } - } - } - - #endregion - - #region ValidateOnSaveEnabled tests - - [Fact] - public void ValidateOnSaveEnabled_is_on_by_default_when_using_empty_constructor() - { - using (var context = new F1Context()) - { - Assert.True(context.Configuration.ValidateOnSaveEnabled); - } - } - - [Fact] - public void ValidateOnSaveEnabled_is_on_by_default_when_using_String_constructor() - { - using (var context = new F1Context(DefaultDbName())) - { - Assert.True(context.Configuration.ValidateOnSaveEnabled); - } - } - - [Fact] - public void ValidateOnSaveEnabled_is_on_by_default_when_using_DbCompiledModel_constructor() - { - using (var context = new F1Context(CreateF1Model())) - { - Assert.True(context.Configuration.ValidateOnSaveEnabled); - } - } - - [Fact] - public void ValidateOnSaveEnabled_is_on_by_default_when_using_String_and_DbCompiledModel_constructor() - { - using (var context = new F1Context(DefaultDbName(), CreateF1Model())) - { - Assert.True(context.Configuration.ValidateOnSaveEnabled); - } - } - - [Fact] - public void ValidateOnSaveEnabled_is_on_by_default_when_using_DbConnection_constructor() - { - using (var context = new F1Context(SimpleConnection(), contextOwnsConnection: true)) - { - Assert.True(context.Configuration.ValidateOnSaveEnabled); - } - } - - [Fact] - public void ValidateOnSaveEnabled_is_on_by_default_when_using_DbConnection_and_DbCompiledModel_constructor() - { - using ( - var context = new F1Context(SimpleConnection(), CreateF1Model(), contextOwnsConnection: true) - ) - { - Assert.True(context.Configuration.ValidateOnSaveEnabled); - } - } - - [Fact] - public void ValidateOnSaveEnabled_is_on_by_default_when_using_entity_connection_string_in_constructor() - { - using (var context = new DbContext(SimpleModelEntityConnectionString)) - { - Assert.True(context.Configuration.ValidateOnSaveEnabled); - } - } - - [Fact] - public void ValidateOnSaveEnabled_is_on_by_default_when_using_EntityConnection_object_in_constructor() - { - using ( - var context = new DbContext( - new EntityConnection(SimpleModelEntityConnectionString), - contextOwnsConnection: true)) - { - Assert.True(context.Configuration.ValidateOnSaveEnabled); - } - } - - [Fact] - public void ValidateOnSaveEnabled_flag_is_on_by_default_when_using_ObjectContext_constructor() - { - var objectContext = GetObjectContext(new F1Context()); - using (var context = new F1Context(objectContext, dbContextOwnsObjectContext: true)) - { - Assert.True(context.Configuration.ValidateOnSaveEnabled); - } - } - - [Fact] - public void ValidateOnSaveEnabled_can_be_changed() - { - using (var context = new F1Context()) - { - Assert.True(context.Configuration.ValidateOnSaveEnabled); - context.Configuration.ValidateOnSaveEnabled = false; - Assert.False(context.Configuration.ValidateOnSaveEnabled); - context.Configuration.ValidateOnSaveEnabled = true; - Assert.True(context.Configuration.ValidateOnSaveEnabled); - } - } - - public class ValidationTestContext : DbContext - { - public DbSet Categories { get; set; } - - public Func ValidateEntityFunc { get; set; } - - protected override bool ShouldValidateEntity(DbEntityEntry entityEntry) - { - return true; - } - - protected override DbEntityValidationResult ValidateEntity( - DbEntityEntry entityEntry, - IDictionary items) - { - if (ValidateEntityFunc != null) - { - return ValidateEntityFunc(entityEntry); - } - return new DbEntityValidationResult(entityEntry, Enumerable.Empty()); - } - } - - [Fact] - public void ValidateEntity_is_called_by_SaveChanges_when_ValidateOnSaveEnabled_is_on() - { - TestValidateEntityWithSaveChanges(validateOnSaveEnabled: true); - } - - [Fact] - public void ValidateEntity_is_not_called_by_SaveChanges_when_ValidateOnSaveEnabled_is_off() - { - TestValidateEntityWithSaveChanges(validateOnSaveEnabled: false); - } - - private void TestValidateEntityWithSaveChanges(bool validateOnSaveEnabled) - { - using (var context = new ValidationTestContext()) - { - context.Database.Initialize(force: false); - - using (new TransactionScope()) - { - context.Configuration.ValidateOnSaveEnabled = validateOnSaveEnabled; - var validateCalled = false; - - context.ValidateEntityFunc = (entry) => - { - validateCalled = true; - return new DbEntityValidationResult( - entry, - Enumerable.Empty - ()); - }; - context.Categories.Add(new Category("FOOD")); - context.SaveChanges(); - - Assert.True(validateOnSaveEnabled == validateCalled); - } - } - } - - [Fact] - public void DetectChanges_is_called_by_SaveChanges_once_when_ValidateOnSaveEnabled_is_on() - { - TestDetectChangesWithSaveChangesAndValidation(validateOnSaveEnabled: true); - } - - [Fact] - public void DetectChanges_is_called_by_SaveChanges_once_when_ValidateOnSaveEnabled_is_off() - { - TestDetectChangesWithSaveChangesAndValidation(validateOnSaveEnabled: false); - } - - private void TestDetectChangesWithSaveChangesAndValidation(bool validateOnSaveEnabled) - { - using (var context = new ValidationTestContext()) - { - context.Database.Initialize(force: false); - - using (new TransactionScope()) - { - context.Configuration.ValidateOnSaveEnabled = validateOnSaveEnabled; - - var food = context.Entry(new Category("FOOD")); - context.Categories.Add(food.Entity); - context.SaveChanges(); - - Assert.Equal(null, food.Entity.DetailedDescription); - Assert.Equal(EntityState.Unchanged, food.State); - - food.Entity.DetailedDescription = "foo"; - Assert.Equal(EntityState.Unchanged, food.State); - - context.ValidateEntityFunc = (entry) => - { - Assert.Equal( - validateOnSaveEnabled - ? EntityState.Modified - : EntityState.Unchanged, entry.State); - entry.State = EntityState.Unchanged; - - food.Entity.DetailedDescription = "bar"; - Assert.Equal(EntityState.Unchanged, entry.State); - - return new DbEntityValidationResult( - entry, - Enumerable.Empty - ()); - }; - - context.SaveChanges(); - Assert.Equal(validateOnSaveEnabled ? "bar" : "foo", food.Entity.DetailedDescription); - - food.Reload(); - Assert.Equal(validateOnSaveEnabled ? null : "foo", food.Entity.DetailedDescription); - } - } - } - - #endregion - - #region Replace connection tests - - [Fact] - public void Can_replace_connection() - { - using (var context = new ReplaceConnectionContext()) - { - using (var newConnection = new LazyInternalConnection( - new DbConnectionInfo( - SimpleConnectionString("NewReplaceConnectionContextDatabase"), - "System.Data.SqlClient"))) - { - Can_replace_connection_implementation(context, newConnection); - } - } - } - - [Fact] - public void Can_replace_connection_with_different_provider() - { - using (var context = new ReplaceConnectionContext()) - { - using (var newConnection = new LazyInternalConnection( - new DbConnectionInfo( - "Data Source=NewReplaceConnectionContextDatabase.sdf", - "System.Data.SqlServerCe.4.0"))) - { - Can_replace_connection_implementation(context, newConnection); - } - } - } - - private void Can_replace_connection_implementation( - ReplaceConnectionContext context, - LazyInternalConnection newConnection) - { - Database.Delete(newConnection.Connection); - Database.Delete(typeof(ReplaceConnectionContext).DatabaseName()); - - context.InternalContext.OverrideConnection(newConnection); - - context.Entities.Add( - new PersistEntity - { - Name = "Testing" - }); - context.SaveChanges(); - - Assert.Same(newConnection.Connection, context.Database.Connection); - Assert.True(Database.Exists(newConnection.Connection)); - Assert.False(Database.Exists(typeof(ReplaceConnectionContext).DatabaseName())); - - // By pass EF just to make sure everything targetted the correct database - var cmd = newConnection.Connection.CreateCommand(); - cmd.CommandText = "SELECT Count(*) FROM PersistEntities"; - cmd.Connection.Open(); - Assert.Equal(1, cmd.ExecuteScalar()); - cmd.Connection.Close(); - } - - #endregion - - #region Test EntityConnection-Store Connection state correlation when opening EntityConnection implicitly through context - - [Fact] - public void Implicit_EntityConnection_throws_if_close_underlying_StoreConnection() - { - using (var context = new SimpleModelContext()) - { - EntityConnection entityConnection = (EntityConnection)((IObjectContextAdapter)context).ObjectContext.Connection; - - Assert.True(context.Products.Count() >= 2, "Need at least 2 product entries for test to work below"); - - ConnectionEventsTracker dbConnectionTracker = new ConnectionEventsTracker(entityConnection.StoreConnection); - ConnectionEventsTracker entityConnectionTracker = new ConnectionEventsTracker(entityConnection); - - var query = from p in context.Products - select p.Name; - - query = query.AsStreaming(); - - Assert.Equal(ConnectionState.Closed, entityConnection.State); // entityConnection state - Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); // underlying storeConnection state - - IEnumerator enumerator = query.GetEnumerator(); - enumerator.MoveNext(); - - // close the underlying store connection without explicitly closing entityConnection - // (but entityConnection state is updated automatically) - entityConnection.StoreConnection.Close(); - Assert.Equal(ConnectionState.Closed, entityConnection.State); - Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); - - // verify that the open and close events have been fired once and only once on both EntityConnection and underlying DbConnection - dbConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); - entityConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); - - // check that we throw when we attempt to use the implicitly-opened entityConnection with closed underlying store connection - Assert.Throws(() => enumerator.MoveNext()).ValidateMessage("ADP_DataReaderClosed", "Read"); - - enumerator.Dispose(); - Assert.Equal(ConnectionState.Closed, entityConnection.State); - Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); - - // verify that the open and close events are not fired again by the second MoveNext() above - dbConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); - entityConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); - - // prove that can still re-use the connection even after the above - Assert.True(context.Products.Count() > 0); // this will check that the query will still execute - - // and show that the entity connection and the store connection are once again closed - Assert.Equal(ConnectionState.Closed, entityConnection.State); - Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); - } - } - - [Fact] - public void Implicit_EntityConnection_throws_if_close_EntityConnection_during_query() - { - using (var context = new SimpleModelContext()) - { - EntityConnection entityConnection = (EntityConnection)((IObjectContextAdapter)context).ObjectContext.Connection; - - Assert.True(context.Products.Count() >= 2, "Need at least 2 product entries for test to work below"); - - ConnectionEventsTracker dbConnectionTracker = new ConnectionEventsTracker(entityConnection.StoreConnection); - ConnectionEventsTracker entityConnectionTracker = new ConnectionEventsTracker(entityConnection); - - var query = from p in context.Products - select p.Name; - - query = query.AsStreaming(); - - Assert.Equal(ConnectionState.Closed, entityConnection.State); // entityConnection state - Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); // underlying storeConnection state - - IEnumerator enumerator = query.GetEnumerator(); - enumerator.MoveNext(); - - // close the entity connection explicitly (i.e. not through context) in middle of query - entityConnection.Close(); - Assert.Equal(ConnectionState.Closed, entityConnection.State); - Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); - - // verify that the open and close events have been fired once and only once on both EntityConnection and underlying DbConnection - dbConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); - entityConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); - - // check that we throw when we attempt to use the implicitly-opened entityConnection - Assert.Throws(() => enumerator.MoveNext()).ValidateMessage("ADP_DataReaderClosed", "Read"); - - enumerator.Dispose(); - Assert.Equal(ConnectionState.Closed, entityConnection.State); - Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); - - // verify that the open and close events are not fired again by the second MoveNext() above - dbConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); - entityConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); - - // prove that can still re-use the connection even after the above - Assert.True(context.Products.Count() > 0); // this will check that the query will still execute - - // and show that the entity connection and the store connection are once again closed - Assert.Equal(ConnectionState.Closed, entityConnection.State); - Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); - } - } - - [Fact] - public void EntityConnection_StateChangeEvents_are_fired_when_state_changes() - { - using (var context = new SimpleModelContext()) - { - EntityConnection entityConnection = (EntityConnection)((IObjectContextAdapter)context).ObjectContext.Connection; - - var dbConnectionTracker = new ConnectionEventsTracker(entityConnection.StoreConnection); - var entityConnectionTracker = new ConnectionEventsTracker(entityConnection); - - // verify that the open and close events have not been fired yet - dbConnectionTracker.VerifyNoConnectionEventsWereFired(); - entityConnectionTracker.VerifyNoConnectionEventsWereFired(); - - var storeConnection = entityConnection.StoreConnection; - storeConnection.Open(); - - // verify the open event has been fired on the store connection and the EntityConnection - // was subscribed so it updated too - dbConnectionTracker.VerifyConnectionOpenedEventWasFired(); - entityConnectionTracker.VerifyConnectionOpenedEventWasFired(); - - storeConnection.Close(); - - // verify the close event has been fired on the store connection and the EntityConnection - // was subscribed so it updated too - dbConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); - entityConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); - } - } - #endregion - } - - #region Fake contexts - - public class ReplaceConnectionContext : DbContext - { - public DbSet Entities { get; set; } - } - - public class PersistEntity - { - public int Id { get; set; } - public string Name { get; set; } - } - - #endregion -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace ProductivityApiTests +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Data; + using System.Data.Common; + using System.Data.Entity; + using System.Data.Entity.Core; + using System.Data.Entity.Core.EntityClient; + using System.Data.Entity.Core.Objects; + using System.Data.Entity.Infrastructure; + using System.Data.Entity.Internal; + using System.Data.Entity.ModelConfiguration; + using System.Data.Entity.Validation; + using System.Globalization; + using System.Linq; + using System.Transactions; + using AdvancedPatternsModel; + using AllTypeKeysModel; + using ConcurrencyModel; + using DaFunc; + using SimpleModel; + using Xunit; + using Xunit.Extensions; + + /// + /// Tests for the primary methods on DbContext. + /// + public class DbContextTests : FunctionalTestBase + { + #region Infrastructure/setup + + public DbContextTests() + { + CreateMetadataFilesForSimpleModel(); + } + + #endregion + + #region Positive constructor tests + + [Fact] + public void Sets_are_initialized_using_empty_constructor_on_DbContext() + { + using (var context = new SimpleModelContext()) + { + Assert.NotNull(context.Products); + Assert.NotNull(context.Categories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + [Fact] + public void Sets_are_initialized_using_name_constructor_on_DbContext() + { + using (var context = new SimpleModelContext(DefaultDbName())) + { + Assert.NotNull(context.Products); + Assert.NotNull(context.Categories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + [Fact] + public void Sets_are_initialized_but_do_not_change_model_using_name_and_model_constructor_on_DbContext() + { + var model = new DbModelBuilder().Build(ProviderRegistry.Sql2008_ProviderInfo).Compile(); + using (var context = new SimpleModelContextWithNoData(DefaultDbName(), model)) + { + Assert.NotNull(context.Products); + Assert.NotNull(context.Categories); + context.Assert().IsNotInModel(); + context.Assert().IsNotInModel(); + } + } + + [Fact] + public void Sets_are_initialized_using_existing_connection_constructor_on_DbContext() + { + using (var connection = SimpleConnection()) + { + using (var context = new SimpleModelContext(connection)) + { + Assert.NotNull(context.Products); + Assert.NotNull(context.Categories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + } + + [Fact] + public void + Sets_are_initialized_but_do_not_change_model_using_existing_connection_and_model_constructor_on_DbContext() + { + var model = new DbModelBuilder().Build(ProviderRegistry.Sql2008_ProviderInfo).Compile(); + using (var connection = SimpleConnection()) + { + using (var context = new SimpleModelContextWithNoData(connection, model)) + { + Assert.NotNull(context.Products); + Assert.NotNull(context.Categories); + context.Assert().IsNotInModel(); + context.Assert().IsNotInModel(); + } + } + } + + [Fact] + public void Sets_are_initialized_using_object_context_constructor_on_DbContext() + { + using (var context = new SimpleModelContext()) + { + using (var context2 = new SimpleModelContext(GetObjectContext(context))) + { + Assert.NotNull(context2.Products); + Assert.NotNull(context2.Categories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + } + + [Fact] + public void Database_Name_is_formed_by_convention_ie_namespace_qualified_class_name_when_using_empty_constructor_on_DbContext() + { + Database_Name_is_formed_by_convention_ie_namespace_qualified_class_name(); + } + + [Fact] + public void Database_Name_is_formed_by_convention_ie_namespace_qualified_class_name_when_using_model_constructor_on_DbContext() + { + // Arrange + var builder = SimpleModelContext.CreateBuilder(); + + // Act- Assert + Database_Name_is_formed_by_convention_ie_namespace_qualified_class_name( + builder.Build(ProviderRegistry.Sql2008_ProviderInfo).Compile()); + } + + private void Database_Name_is_formed_by_convention_ie_namespace_qualified_class_name( + DbCompiledModel model = null) + { + // Act + using (var context = model == null ? new SimpleModelContext() : new SimpleModelContext(model)) + { + // Assert + Assert.Equal("SimpleModel.SimpleModelContext", context.Database.Connection.Database); + } + } + + [Fact] + public void + Database_Name_is_from_App_Config_if_convention_name_matches_named_connection_string_when_using_model_constructor_on_DbContext() + { + var builder = AllTypeKeysContext.CreateBuilder(); + Database_Name_is_from_App_Config_if_convention_name_matches_named_connection_string( + builder.Build(ProviderRegistry.Sql2008_ProviderInfo).Compile()); + } + + [Fact] + public void + Database_Name_is_from_App_config_if_named_connection_string_matches_convention_name_when_using_empty_constructor_on_DbContext() + { + Database_Name_is_from_App_Config_if_convention_name_matches_named_connection_string(); + } + + private void Database_Name_is_from_App_Config_if_convention_name_matches_named_connection_string( + DbCompiledModel model = null) + { + // Act + using (var context = model == null ? new AllTypeKeysContext() : new AllTypeKeysContext(model)) + { + // Assert that name of database is taken from app config rather than the convention way, + // namespace qualified type name + Assert.NotEqual("AllTypeKeysModel.AllTypeKeysContext", context.Database.Connection.Database); + Assert.Equal("AllTypeKeysDb", context.Database.Connection.Database); + } + } + + [Fact] + public void Sets_are_initialized_for_DbContext_constructor_when_using_empty_DbCompiledModel() + { + VerifySetsAreInitialized(DbCompiledModelContents.IsEmpty); + } + + [Fact] + public void Sets_are_initialized_for_DbContext_constructor_when_using_subset_DbCompiledModel() + { + VerifySetsAreInitialized(DbCompiledModelContents.IsSubset); + } + + [Fact] + public void Sets_are_initialized_for_DbContext_constructor_when_using_superset_DbCompiledModel() + { + VerifySetsAreInitialized(DbCompiledModelContents.IsSuperset); + } + + [Fact] + public void Sets_are_initialized_for_DbContext_constructor_when_using_DbCompiledModel_that_matches_the_context() + { + VerifySetsAreInitialized(DbCompiledModelContents.Match); + } + + [Fact] + public void Sets_are_initialized_for_DbContext_constructor_when_using_DbCompiledModel_that_doesnt_match_context_definitions() + { + VerifySetsAreInitialized(DbCompiledModelContents.DontMatch); + } + + [Fact] + public void Model_Tweaking_is_ignored_when_using_model_ctor_on_DbContext() + { + // Arrange + var modelBuilder = new DbModelBuilder(); + // Blog has Id as the key defined in OnModelCreating, here we tweak it to use Title as the Key + modelBuilder.Entity().HasKey(o => o.Title); + + // Act + using ( + var context = new LiveWriterContext(modelBuilder.Build(ProviderRegistry.SqlCe4_ProviderInfo).Compile())) + { + Assert.NotNull(context.Blogs); + context.Assert().IsInModel(); + + // Assert that Blog doesnt have Id as the key but rather has Title as the Key + var type = GetEntityType(context, typeof(Blog)); + Assert.True(type.KeyMembers.Count == 1); + Assert.Equal(type.KeyMembers.First().Name, "Title"); + } + } + + [Fact] + public void Verify_DbContext_construction_using_connection_string_ctor_when_string_is_database_name() + { + Verify_DbContext_construction_using_connection_string_ctor( + nameOrConnectionString: "DefaultDatabaseNameDb", + expectedDatabaseName: "DefaultDatabaseNameDb"); + } + + [Fact] + public void Verify_DbContext_construction_using_connection_string_ctor_when_string_is_provider_connection_string() + { + Verify_DbContext_construction_using_connection_string_ctor( + nameOrConnectionString: SimpleConnectionString()); + } + + [Fact] + public void Verify_DbContext_construction_using_connection_string_ctor_when_string_is_named_connection_string() + { + Verify_DbContext_construction_using_connection_string_ctor( + nameOrConnectionString: "SimpleModelWithNoDataFromAppConfig", + expectedDatabaseName: "SimpleModel.SimpleModelWithNoData"); + } + + [Fact] + public void Verify_DbContext_construction_using_connection_string_ctor_when_string_is_named_connection_string_using_name_keyword() + { + Verify_DbContext_construction_using_connection_string_ctor( + nameOrConnectionString: "Name=SimpleModelWithNoDataFromAppConfig", + expectedDatabaseName: "SimpleModel.SimpleModelWithNoData"); + } + + [Fact] + public void + Verify_DbContext_construction_using_connection_string_ctor_when_string_is_named_connection_string_and_its_last_token_exists_in_config + () + { + Verify_DbContext_construction_using_connection_string_ctor( + nameOrConnectionString: "X.Y.Z.R.SimpleModelWithNoDataFromAppConfig", + expectedDatabaseName: "SimpleModel.SimpleModelWithNoData"); + } + + private void Verify_DbContext_construction_using_connection_string_ctor( + string nameOrConnectionString, + string expectedDatabaseName = + "SimpleModel.SimpleModelContextWithNoData") + { + using (var context = new SimpleModelContextWithNoData(nameOrConnectionString)) + { + Assert.NotNull(context.Products); + Assert.NotNull(context.Categories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + + Assert.Equal(expectedDatabaseName, context.Database.Connection.Database); + } + } + + [Fact] + public void Verify_DbContext_construction_using_db_name_and_model_Ctor_where_model_defines_a_subset_of_entities_on_context() + { + DbContext_construction_using_connection_string_and_model_Ctor( + ConnectionStringFormat.DatabaseName, + DbCompiledModelContents.IsSubset); + } + + [Fact] + public void Verify_DbContext_construction_using_db_name_and_model_Ctor_where_model_defines_a_superset_of_entities_on_context() + { + DbContext_construction_using_connection_string_and_model_Ctor( + ConnectionStringFormat.DatabaseName, + DbCompiledModelContents.IsSuperset); + } + + [Fact] + public void + Verify_DbContext_construction_using_db_name_and_model_Ctor_where_model_matches_the_entities_on_context() + { + DbContext_construction_using_connection_string_and_model_Ctor( + ConnectionStringFormat.DatabaseName, + DbCompiledModelContents.Match); + } + + [Fact] + public void Verify_DbContext_construction_using_db_name_and_model_Ctor_where_model_has_no_entities_matching_those_on_context() + { + DbContext_construction_using_connection_string_and_model_Ctor( + ConnectionStringFormat.DatabaseName, + DbCompiledModelContents.DontMatch); + } + + [Fact] + public void Verify_DbContext_construction_using_valid_connection_string_and_model_Ctor_where_model_is_empty() + { + DbContext_construction_using_connection_string_and_model_Ctor( + ConnectionStringFormat.ProviderConnectionString, DbCompiledModelContents.IsEmpty); + } + + [Fact] + public void + Verify_DbContext_construction_using_valid_connection_string_and_model_Ctor_where_model_defines_a_subset_of_entities_on_context() + { + DbContext_construction_using_connection_string_and_model_Ctor( + ConnectionStringFormat.ProviderConnectionString, DbCompiledModelContents.IsSubset); + } + + [Fact] + public void + Verify_DbContext_construction_using_valid_connection_string_and_model_Ctor_where_model_defines_a_superset_of_entities_on_context + () + { + DbContext_construction_using_connection_string_and_model_Ctor( + ConnectionStringFormat.ProviderConnectionString, DbCompiledModelContents.IsSuperset); + } + + [Fact] + public void Verify_DbContext_construction_using_valid_connection_string_and_model_Ctor_where_model_matches_the_entities_on_context() + { + DbContext_construction_using_connection_string_and_model_Ctor( + ConnectionStringFormat.ProviderConnectionString, DbCompiledModelContents.Match); + } + + [Fact] + public void + Verify_DbContext_construction_using_valid_connection_string_and_model_Ctor_where_model_has_no_entities_matching_those_on_context + () + { + DbContext_construction_using_connection_string_and_model_Ctor( + ConnectionStringFormat.ProviderConnectionString, DbCompiledModelContents.DontMatch); + } + + [Fact] + public void Verify_DbContext_construction_using_named_connection_string_and_model_Ctor_where_model_is_empty() + { + DbContext_construction_using_connection_string_and_model_Ctor( + ConnectionStringFormat.NamedConnectionString, + DbCompiledModelContents.IsEmpty); + } + + [Fact] + public void DbContext_construction_using_named_connection_string_and_model_Ctor_where_model_defines_a_subset_of_entities_on_context( + + ) + { + DbContext_construction_using_connection_string_and_model_Ctor( + ConnectionStringFormat.NamedConnectionString, + DbCompiledModelContents.IsSubset); + } + + [Fact] + public void + DbContext_construction_using_named_connection_string_and_model_Ctor_where_model_defines_a_superset_of_entities_on_context() + { + DbContext_construction_using_connection_string_and_model_Ctor( + ConnectionStringFormat.NamedConnectionString, + DbCompiledModelContents.IsSuperset); + } + + [Fact] + public void DbContext_construction_using_named_connection_string_and_model_Ctor_where_model_matches_the_entities_on_context() + { + DbContext_construction_using_connection_string_and_model_Ctor( + ConnectionStringFormat.NamedConnectionString, + DbCompiledModelContents.Match); + } + + [Fact] + public void + DbContext_construction_using_named_connection_string_and_model_Ctor_where_model_has_no_entities_matching_those_on_context() + { + DbContext_construction_using_connection_string_and_model_Ctor( + ConnectionStringFormat.NamedConnectionString, + DbCompiledModelContents.DontMatch); + } + + private void DbContext_construction_using_connection_string_and_model_Ctor( + ConnectionStringFormat connStringFormat, DbCompiledModelContents modelContents) + { + // Act + // Setup connection string + string connectionString = null; + string dbName = null; + switch (connStringFormat) + { + case ConnectionStringFormat.DatabaseName: + connectionString = dbName = DefaultDbName(); + break; + case ConnectionStringFormat.NamedConnectionString: + connectionString = "SimpleModelWithNoDataFromAppConfig"; + dbName = "SimpleModel.SimpleModelWithNoData"; + break; + case ConnectionStringFormat.ProviderConnectionString: + connectionString = SimpleConnectionString(); + dbName = "SimpleModel.SimpleModelContextWithNoData"; + break; + default: + throw new ArgumentException("Invalid ConnectionStringFormat enum supplied " + connStringFormat); + } + + // Setup DbCompiledModel + var builder = new DbModelBuilder(); + + switch (modelContents) + { + case DbCompiledModelContents.IsEmpty: + // Do nothing as builder has already been initialized + break; + case DbCompiledModelContents.IsSubset: + // Product is not defined here + builder.Entity(); + break; + case DbCompiledModelContents.IsSuperset: + builder.Entity(); + builder.Entity(); + builder.Entity(); + break; + case DbCompiledModelContents.Match: + builder.Entity(); + builder.Entity(); + break; + case DbCompiledModelContents.DontMatch: + builder.Entity(); + builder.Entity(); + break; + default: + throw new ArgumentException("Invalid DbCompiledModelContents Arguments passed in, " + modelContents); + } + + // Act + using ( + var context = new SimpleModelContextWithNoData( + connectionString, + builder.Build(ProviderRegistry.Sql2008_ProviderInfo). + Compile())) + { + // Assert + Assert.Equal(context.Database.Connection.Database, dbName); + switch (modelContents) + { + case DbCompiledModelContents.IsEmpty: + Assert.NotNull(context.Categories); + Assert.NotNull(context.Categories); + context.Assert().IsNotInModel(); + context.Assert().IsNotInModel(); + break; + case DbCompiledModelContents.IsSubset: + Assert.NotNull(context.Categories); + Assert.NotNull(context.Categories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); // reachability + break; + case DbCompiledModelContents.IsSuperset: + Assert.NotNull(context.Categories); + Assert.NotNull(context.Categories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + break; + case DbCompiledModelContents.Match: + Assert.NotNull(context.Categories); + Assert.NotNull(context.Categories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + context.Assert().IsNotInModel(); + break; + case DbCompiledModelContents.DontMatch: + Assert.NotNull(context.Categories); + Assert.NotNull(context.Products); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + break; + default: + throw new ArgumentException( + "Invalid DbCompiledModelContents Arguments passed in, " + + modelContents); + } + } + } + + [Fact] + public void Database_name_generated_from_generic_DbContext_class_name_works() + { + using (var context = new GenericFuncy>()) + { + context.Database.Delete(); + + context.Database.Initialize(force: false); + + Assert.True(context.Database.Exists()); + } + } + + [Fact] + public void Database_name_generated_from_DbContext_class_nested_in_generic_class_name_works() + { + using (var context = new GT.Funcy()) + { + context.Database.Delete(); + + context.Database.Initialize(force: false); + + Assert.True(context.Database.Exists()); + } + } + + [Fact] + public void Database_name_generated_from_generic_DbContext_class_nested_in_generic_class_name_works() + { + using (var context = new GT.GenericFuncy, NT>, NT>()) + { + context.Database.Delete(); + + context.Database.Initialize(force: false); + + Assert.True(context.Database.Exists()); + } + } + + #endregion + + #region Negative constructor tests + + [Fact] + public void DbContext_construction_does_not_throw_but_subsequent_calls_using_connection_throw_for_invalid_sql_connection_string() + { + var context = new SimpleModelContextWithNoData("InvalidKeywordConnectionString"); + Assert.Throws(() => GetObjectContext(context)).ValidateMessage( + typeof(DbConnection).Assembly, "ADP_KeywordNotSupported", null); + } + + [Fact] + public void DbContext_construction_does_not_throw_but_subsequent_calls_using_connection_throw_for_invalid_provider_keyword() + { + var context = new SimpleModelContextWithNoData("InvalidProviderNameConnectionString"); + Assert.Throws(() => GetObjectContext(context)).ValidateMessage("EntityClient_InvalidStoreProvider"); + } + + [Fact] + public void DbContext_construction_does_not_throw_but_subsequent_calls_using_connection_throw_for_nonexistent_connection_string() + { + var context = new SimpleModelContextWithNoData("Name=NonexistentConnectionString"); + Assert.Throws(() => GetObjectContext(context)).ValidateMessage( + "DbContext_ConnectionStringNotFound", "NonexistentConnectionString"); + } + + [Fact] + public void DbContext_caches_models_for_two_providers() + { + // Ensure that the model is in use with a SQL connection + using (var context = new SimpleModelContext()) + { + context.Database.Initialize(force: false); + } + + // Now try to use it with a CE connection; would throw in EF 4.1, will not now throw. + var sqlCeConnectionFactory = new SqlCeConnectionFactory( + "System.Data.SqlServerCe.4.0", + AppDomain.CurrentDomain.BaseDirectory, ""); + using (var connection = sqlCeConnectionFactory.CreateConnection(DefaultDbName())) + { + using (var context = new SimpleModelContext(connection)) + { + context.Database.Initialize(force: false); + } + } + } + + #endregion + + #region Positive SaveChanges tests + + [Fact] + [AutoRollback] + public void SaveChanges_saves_Added_Modified_Deleted_entities() + { + SaveChanges_saves_Added_Modified_Deleted_entities_implementation((c) => c.SaveChanges()); + } + +#if !NET40 + + [Fact] + [AutoRollback] + public void SaveChangesAsync_saves_Added_Modified_Deleted_entities() + { + SaveChanges_saves_Added_Modified_Deleted_entities_implementation((c) => c.SaveChangesAsync().Result); + } + +#endif + + private void SaveChanges_saves_Added_Modified_Deleted_entities_implementation(Func saveChanges) + { + using (var context = new SimpleModelContext()) + { + // Modified + var product1 = context.Products.Find(1); + product1.Name = "Smarties"; + + // Deleted + var product2 = context.Products.Find(2); + context.Products.Remove(product2); + + // Added + var product3 = new Product + { + Name = "Branston Pickle" + }; + context.Products.Add(product3); + + // Validate state before Save + Assert.Equal(3, GetStateEntries(context).Count()); + Assert.Equal(EntityState.Modified, GetStateEntry(context, product1).State); + Assert.Equal(EntityState.Deleted, GetStateEntry(context, product2).State); + Assert.Equal(EntityState.Added, GetStateEntry(context, product3).State); + + // Save + var savedCount = saveChanges(context); + Assert.Equal(3, savedCount); + + // Validate state after Save + Assert.Equal(2, GetStateEntries(context).Count()); + Assert.Equal(EntityState.Unchanged, GetStateEntry(context, product1).State); + Assert.Equal(EntityState.Unchanged, GetStateEntry(context, product3).State); + + using (var context2 = new SimpleModelContext()) + { + var product1s = context2.Products.Find(product1.Id); + var product2s = context2.Products.Find(product2.Id); + var product3s = context2.Products.Find(product3.Id); + + Assert.NotNull(product1s); + Assert.Null(product2s); + Assert.NotNull(product3s); + + Assert.Equal("Smarties", product1s.Name); + Assert.Equal("Branston Pickle", product3s.Name); + + Assert.Equal(2, GetStateEntries(context).Count()); + Assert.Equal(EntityState.Unchanged, GetStateEntry(context2, product1s).State); + Assert.Equal(EntityState.Unchanged, GetStateEntry(context2, product3s).State); + } + } + } + + [Fact] + [AutoRollback] + public void SaveChanges_performs_DetectChanges() + { + SaveChanges_performs_DetectChanges_implementation((c) => c.SaveChanges()); + } + +#if !NET40 + + [Fact] + [AutoRollback] + public void SaveChangesAsync_performs_DetectChanges() + { + SaveChanges_performs_DetectChanges_implementation((c) => c.SaveChangesAsync().Result); + } + +#endif + + private void SaveChanges_performs_DetectChanges_implementation(Func saveChanges) + { + // NOTE: This is split out into a seperate test from the above test because + // it is important no other APIs are called between the modification + // and calling SaveChanges due to other APIs calling DetectChanges implicitly + + using (var context = new SimpleModelContext()) + { + var prod = context.Products.Find(1); + prod.Name = "Cascade Draught"; + var savedCount = saveChanges(context); + Assert.Equal(1, savedCount); + } + } + + [Fact] + public void SaveChanges_on_uninitialized_context_does_not_throw() + { + using (var context = new SimpleModelContext()) + { + Assert.Equal(0, context.SaveChanges()); + } + } + +#if !NET40 + + [Fact] + public void SaveChangesAsync_on_uninitialized_context_does_not_throw() + { + using (var context = new SimpleModelContext()) + { + Assert.Equal(0, context.SaveChangesAsync().Result); + } + } + +#endif + + public class SaveChangesDoesntInitializeContext : DbContext + { + public SaveChangesDoesntInitializeContext() + { + Database.SetInitializer(null); + } + + public bool InitializationHappened { get; set; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + InitializationHappened = true; + } + } + + [Fact] + public void SaveChanges_on_uninitialized_context_does_not_cause_context_to_be_initialized() + { + using (var context = new SaveChangesDoesntInitializeContext()) + { + context.SaveChanges(); + + Assert.False(context.InitializationHappened); + + var _ = ((IObjectContextAdapter)context).ObjectContext; + + Assert.True(context.InitializationHappened); + } + } + +#if !NET40 + + public class SaveChangesAsyncDoesntInitializeContext : DbContext + { + public SaveChangesAsyncDoesntInitializeContext() + { + Database.SetInitializer(null); + } + + public bool InitializationHappened { get; set; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + InitializationHappened = true; + } + } + + [Fact] + public void SaveChangesAsync_on_uninitialized_context_does_not_cause_context_to_be_initialized() + { + using (var context = new SaveChangesAsyncDoesntInitializeContext()) + { + context.SaveChangesAsync().Wait(); + + Assert.False(context.InitializationHappened); + + var _ = ((IObjectContextAdapter)context).ObjectContext; + + Assert.True(context.InitializationHappened); + } + } + +#endif + + [Fact] + public void SaveChanges_is_virtual() + { + using (DbContext context = new SimpleModelContextWithNoData()) + { + Assert.Equal(0, context.SaveChanges()); + Assert.True(((SimpleModelContextWithNoData)context).SaveChangesCalled); + } + } + +#if !NET40 + + [Fact] + public void SaveChangesAsync_is_virtual() + { + using (DbContext context = new SimpleModelContextWithNoData()) + { + Assert.Equal(0, context.SaveChangesAsync().Result); + Assert.True(((SimpleModelContextWithNoData)context).SaveChangesCalled); + } + } + +#endif + + #endregion + + #region Negative SaveChanges tests + + [Fact] + public void SaveChanges_bubbles_presave_exception() + { + SaveChanges_bubbles_presave_exception_implementation((c) => c.SaveChanges()); + } + +#if !NET40 + + [Fact] + public void SaveChangesAsync_bubbles_presave_exception() + { + SaveChanges_bubbles_presave_exception_implementation( + (c) => ExceptionHelpers.UnwrapAggregateExceptions(() => c.SaveChangesAsync().Result)); + } + +#endif + + private void SaveChanges_bubbles_presave_exception_implementation(Func saveChanges) + { + EnsureDatabaseInitialized(() => new AdvancedPatternsMasterContext()); + + using (new TransactionScope()) + { + using (var context = new AdvancedPatternsMasterContext()) + { + var emp = new CurrentEmployee + { + EmployeeId = 4 + }; + var ord = new WorkOrder + { + WorkOrderId = 2, + EmployeeId = 4 + }; + context.Employees.Attach(emp); + context.WorkOrders.Attach(ord); + + // Create a conceptual null + GetObjectContext(context).ObjectStateManager.ChangeObjectState(emp, EntityState.Deleted); + + Assert.Throws(() => context.SaveChanges()).ValidateMessage( + "ObjectContext_CommitWithConceptualNull"); + } + } + } + + [Fact] + [AutoRollback] + public void SaveChanges_bubbles_UpdateException() + { + SaveChanges_bubbles_UpdateException_implementation((c) => c.SaveChanges()); + } + +#if !NET40 + + [Fact] + [AutoRollback] + public void SaveChangesAsync_bubbles_UpdateException() + { + SaveChanges_bubbles_UpdateException_implementation( + (c) => ExceptionHelpers.UnwrapAggregateExceptions(() => c.SaveChangesAsync().Result)); + } + +#endif + + private void SaveChanges_bubbles_UpdateException_implementation(Func saveChanges) + { + using (var context = new SimpleModelContext()) + { + var prod = new Product + { + Name = "Wallaby Sausages", + CategoryId = "AUSSIE FOODS" + }; + context.Products.Add(prod); + + Assert.Throws(() => saveChanges(context)).ValidateMessage( + "Update_GeneralExecutionException"); + } + } + + [Fact] + [AutoRollback] + public void SaveChanges_bubbles_exception_during_AcceptChanges() + { + SaveChanges_bubbles_exception_during_AcceptChanges_implementation((c) => c.SaveChanges()); + } + +#if !NET40 + + [Fact] + [AutoRollback] + public void SaveChangesAsync_bubbles_exception_during_AcceptChanges() + { + SaveChanges_bubbles_exception_during_AcceptChanges_implementation( + (c) => ExceptionHelpers.UnwrapAggregateExceptions(() => c.SaveChangesAsync().Result)); + } + +#endif + + private void SaveChanges_bubbles_exception_during_AcceptChanges_implementation(Func saveChanges) + { + using (var context = new SimpleModelContext()) + { + var cat1 = new Category + { + Id = "AUSSIE FOODS" + }; + var cat2 = new Category + { + Id = "AUSSIE FOODS" + }; + + context.Categories.Attach(cat1); + context.Categories.Add(cat2); + + // Accept will fail because of PK violation + // (cat1 doesn't actually exist in the store so update pipeline will succeed) + Assert.Throws(() => saveChanges(context)).ValidateMessage( + "ObjectContext_AcceptAllChangesFailure"); + } + } + + [Fact] + public void SaveChanges_throws_on_validation_errors() + { + SaveChanges_throws_on_validation_errors_implementation((c) => c.SaveChanges()); + } + +#if !NET40 + + [Fact] + public void SaveChangesAsync_throws_on_validation_errors() + { + SaveChanges_throws_on_validation_errors_implementation( + (c) => ExceptionHelpers.UnwrapAggregateExceptions(() => c.SaveChangesAsync().Result)); + } + +#endif + + public void SaveChanges_throws_on_validation_errors_implementation(Func saveChanges) + { + using (var context = new ValidationTestContext()) + { + context.Database.Initialize(force: false); + + using (new TransactionScope()) + { + context.ValidateEntityFunc = + (entry) => { return new DbEntityValidationResult(entry, new[] { new DbValidationError("Id", "error") }); }; + context.Categories.Add(new Category("FOOD")); + Assert.Throws(() => context.SaveChanges()).ValidateMessage( + "DbEntityValidationException_ValidationFailed"); + } + } + } + + #endregion + + #region Positive ObjectContext tests + + [Fact] + public void ObjectContext_property_returns_EF_context() + { + using (var context = new SimpleModelContext()) + { + var product = context.Products.Find(1); + + Assert.NotNull(GetObjectContext(context)); + Assert.NotNull(GetObjectContext(context).ObjectStateManager.GetObjectStateEntry(product)); + } + } + + [Fact] + public void ObjectContext_property_returns_EF_context_even_before_DbContext_is_initialized() + { + using (var context = new SimpleModelContext()) + { + Assert.NotNull(GetObjectContext(context)); + var product = GetObjectContext(context).CreateObjectSet().Where(p => p.Id == 1).Single(); + Assert.Equal(1, product.Id); + } + } + + #endregion + + #region Positive Connection property tests + + [Fact] + public void Connection_property_returns_connection() + { + using (var context = new SimpleModelContext()) + { + var product = context.Products.Find(1); + + Assert.NotNull(context.Database.Connection); + Assert.Equal(DefaultDbName(), context.Database.Connection.Database); + } + } + + [Fact] + public void Connection_property_returns_connection_even_before_DbContext_is_initialized() + { + using (var context = new SimpleModelContext()) + { + Assert.NotNull(context.Database.Connection); + Assert.Equal(DefaultDbName(), context.Database.Connection.Database); + } + } + + #endregion + + #region Positive set detection and initialization tests + + public class DbSetVariant : EmptyContext + { + public DbSetVariant() + : base("CommonProductCategoryDatabase") + { + } + + public DbSet UnicornProducts { get; set; } + public DbSet UnicornCategories { get; set; } + } + + [Fact] + public void DbSet_properties_are_detected_and_initialized() + { + using (var context = new DbSetVariant()) + { + Assert.NotNull(context.UnicornProducts); + Assert.NotNull(context.UnicornCategories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + [Fact] + public void Entity_set_names_are_taken_from_DbSet_property_names() + { + using (var context = new DbSetVariant()) + { + Assert.Equal("UnicornProducts", GetEntitySetName(context, typeof(Product))); + Assert.Equal("UnicornCategories", GetEntitySetName(context, typeof(Category))); + } + } + + public class IDbSetVariant : EmptyContext + { + public IDbSetVariant() + : base("CommonProductCategoryDatabase") + { + } + + public IDbSet UnicornProducts { get; set; } + public IDbSet UnicornCategories { get; set; } + } + + [Fact] + public void IDbSet_properties_are_detected_and_initialized() + { + using (var context = new IDbSetVariant()) + { + Assert.NotNull(context.UnicornProducts); + Assert.NotNull(context.UnicornCategories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + [Fact] + public void Entity_set_names_are_taken_from_DbSet_property_names_when_using_IDbSet_properties() + { + using (var context = new IDbSetVariant()) + { + Assert.Equal("UnicornProducts", GetEntitySetName(context, typeof(Product))); + Assert.Equal("UnicornCategories", GetEntitySetName(context, typeof(Category))); + } + } + + public class IQueryableVariant : EmptyContext + { + public IQueryableVariant() + : base(DefaultDbName()) + { + } + + public IQueryable Products { get; set; } + public IQueryable Categories { get; set; } + } + + [Fact] + public void IQueryable_properties_are_not_detected_or_initialized() + { + using (var context = new IQueryableVariant()) + { + Assert.Null(context.Products); + Assert.Null(context.Categories); + context.Assert().IsNotInModel(); + context.Assert().IsNotInModel(); + } + } + + public class DbQueryVariant : EmptyContext + { + public DbQueryVariant() + : base(DefaultDbName()) + { + } + + public DbQuery Products { get; set; } + public DbQuery Categories { get; set; } + } + + [Fact] + public void DbQuery_properties_are_not_initialized() + { + using (var context = new DbQueryVariant()) + { + Assert.Null(context.Products); + Assert.Null(context.Categories); + context.Assert().IsNotInModel(); + context.Assert().IsNotInModel(); + } + } + + public class SetOfDerivedTypeVariant : EmptyContext + { + public SetOfDerivedTypeVariant() + : base("CommonProductCategoryDatabase") + { + } + + public DbSet UnicornProducts { get; set; } + public DbSet FeaturedProducts { get; set; } + public DbSet UnicornCategories { get; set; } + } + + [Fact] + public void Set_of_derived_type_initialized() + { + using (var context = new SetOfDerivedTypeVariant()) + { + Assert.NotNull(context.UnicornProducts); + Assert.NotNull(context.FeaturedProducts); + Assert.NotNull(context.UnicornCategories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + [Fact] + public void Entity_set_names_for_a_derived_type_come_from_the_base_type_DbSet_property_names() + { + using (var context = new SetOfDerivedTypeVariant()) + { + Assert.Equal("UnicornProducts", GetEntitySetName(context, typeof(Product))); + Assert.Equal("UnicornProducts", GetEntitySetName(context, typeof(FeaturedProduct))); + Assert.Equal("UnicornCategories", GetEntitySetName(context, typeof(Category))); + } + } + + public class PrivateSettersVariant : EmptyContext + { + public PrivateSettersVariant() + : base("CommonProductCategoryDatabase") + { + } + + public DbSet Products { get; private set; } + public IDbSet Categories { get; private set; } + } + + [Fact] + public void Set_properties_with_private_setters_are_detected_but_not_initialized() + { + using (var context = new PrivateSettersVariant()) + { + Assert.Null(context.Products); + Assert.Null(context.Categories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + public class InternalSettersVariant : EmptyContext + { + public InternalSettersVariant() + : base("CommonProductCategoryDatabase") + { + } + + public DbSet Products { get; internal set; } + public IDbSet Categories { get; internal set; } + } + + [Fact] + public void Set_properties_with_internal_setters_are_detected_but_not_initialized() + { + using (var context = new InternalSettersVariant()) + { + Assert.Null(context.Products); + Assert.Null(context.Categories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + public class ProtectedSettersVariant : EmptyContext + { + public ProtectedSettersVariant() + : base("CommonProductCategoryDatabase") + { + } + + public DbSet Products { get; protected set; } + public IDbSet Categories { get; protected set; } + } + + [Fact] + public void Set_properties_with_protected_setters_are_detected_but_not_initialized() + { + using (var context = new ProtectedSettersVariant()) + { + Assert.Null(context.Products); + Assert.Null(context.Categories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + public class NoSettersVariant : EmptyContext + { + public NoSettersVariant() + : base("CommonProductCategoryDatabase") + { + } + + public DbSet Products + { + get { return null; } + } + + public IDbSet Categories + { + get { return null; } + } + } + + [Fact] + public void Set_properties_with_no_setters_are_detected_but_not_initialized() + { + using (var context = new NoSettersVariant()) + { + Assert.Null(context.Products); + Assert.Null(context.Categories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + public class FullyPrivateVariant : EmptyContext + { + public FullyPrivateVariant() + : base("CommonProductCategoryDatabase") + { + } + + private DbSet Products { get; set; } + private IDbSet Categories { get; set; } + + public IQueryable GetProducts() + { + return Products; + } + + public IQueryable GetCategories() + { + return Categories; + } + } + + [Fact] + public void Fully_private_properties_are_detected_but_not_initialized() + { + using (var context = new FullyPrivateVariant()) + { + Assert.Null(context.GetProducts()); + Assert.Null(context.GetCategories()); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + public class MethodsAndFieldsVariant : EmptyContext + { + public MethodsAndFieldsVariant() + : base(DefaultDbName()) + { + } + + public IQueryable Products; + public IDbSet Categories; + public DbSet Logins; + + public IQueryable GetProducts() + { + return Products; + } + + public IDbSet GetCategories() + { + return Categories; + } + + public DbSet GetLogins() + { + return Logins; + } + } + + [Fact] + public void IQueryable_and_DbSet_methods_and_fields_are_ignored() + { + using (var context = new MethodsAndFieldsVariant()) + { + Assert.Null(context.GetProducts()); + Assert.Null(context.GetCategories()); + Assert.Null(context.GetLogins()); + context.Assert().IsNotInModel(); + context.Assert().IsNotInModel(); + context.Assert().IsNotInModel(); + } + } + + [Fact] + public void Derived_context_with_no_sets_is_okay() + { + using (var context = new EmptyContext()) + { + // Asking for the ObjectContext causes the DbContext to be initialized even with no types. + Assert.NotNull(GetObjectContext(context)); + } + } + + public class NonGenericIQueryableVariant : EmptyContext + { + public NonGenericIQueryableVariant() + : base(DefaultDbName()) + { + } + + public IQueryable Stuff { get; set; } + } + + [Fact] + public void Set_properties_of_non_generic_IQueryable_are_ignored() + { + using (var context = new NonGenericIQueryableVariant()) + { + Assert.Null(context.Stuff); + + // Asking for the ObjectContext causes the DbContext to be initialized even with no types. + Assert.NotNull(GetObjectContext(context)); + } + } + + public class IEnumerableVariant : EmptyContext + { + public IEnumerableVariant() + : base(DefaultDbName()) + { + } + + public IEnumerable Categories { get; set; } + } + + [Fact] + public void Set_properties_defined_as_IEnumerable_are_ignored() + { + using (var context = new IEnumerableVariant()) + { + Assert.Null(context.Categories); + context.Assert().IsNotInModel(); + } + } + + public class SetsDerivedFromValidSetTypeVariant : EmptyContext + { + public SetsDerivedFromValidSetTypeVariant() + : base(DefaultDbName()) + { + } + + public ObjectSet Products { get; set; } + public HashSetBasedDbSet Categories { get; set; } + } + + [Fact] + public void Set_properties_derived_from_valid_set_type_are_ignored() + { + using (var ctx = new SetsDerivedFromValidSetTypeVariant()) + { + Assert.Null(ctx.Products); + Assert.Null(ctx.Categories); + ctx.Assert().IsNotInModel(); + ctx.Assert().IsNotInModel(); + } + } + + public class DerivedDerivedContextNoExtraSetsVariant : SimpleModelContext + { + } + + [Fact] + public void Derived_derived_context_with_no_extra_sets() + { + using (var context = new DerivedDerivedContextNoExtraSetsVariant()) + { + Assert.NotNull(context.Categories); + Assert.NotNull(context.Products); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + public class DerivedDerivedContextExtraSetsVariant : SimpleModelContext + { + public DbSet ExtraSet { get; set; } + } + + [Fact] + public void Derived_derived_context_with_extra_sets() + { + using (var context = new DerivedDerivedContextExtraSetsVariant()) + { + Assert.NotNull(context.Categories); + Assert.NotNull(context.Products); + Assert.NotNull(context.ExtraSet); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + #endregion + + #region Negative set detection and initialization tests + + public class InterfaceVariant : EmptyContext + { + public InterfaceVariant() + : base(DefaultDbName()) + { + } + + public DbSet Collections { get; set; } + } + + [Fact] + public void Set_properties_for_interface_types_throw() + { + try + { + new InterfaceVariant(); + Assert.True(false); + } + catch (InvalidOperationException ex) + { + var resourceLookup = new AssemblyResourceLookup( + EntityFrameworkAssembly, + "System.Data.Entity.Properties.Resources"); + var messageTemplate = resourceLookup.LookupString("InvalidEntityType"); + + var message = String.Format(CultureInfo.InvariantCulture, messageTemplate, typeof(ICollection)); + + Assert.Equal(message, ex.Message); + } + } + + public class GenericVariant : EmptyContext + { + public GenericVariant() + : base(DefaultDbName()) + { + } + + public IDbSet> ProductCollections { get; set; } + } + + [Fact] + public void Set_properties_for_generic_types_throw() + { + try + { + new GenericVariant(); + Assert.True(false); + } + catch (InvalidOperationException ex) + { + var resourceLookup = new AssemblyResourceLookup( + EntityFrameworkAssembly, + "System.Data.Entity.Properties.Resources"); + var messageTemplate = resourceLookup.LookupString("InvalidEntityType"); + + var message = String.Format(CultureInfo.InvariantCulture, messageTemplate, typeof(List)); + + Assert.Equal(message, ex.Message); + } + } + + public class NonEntityVariant : EmptyContext + { + public NonEntityVariant() + : base(DefaultDbName()) + { + } + + public DbSet ObsoleteAttributes { get; set; } + } + + [Fact] + public void Set_properties_for_non_entity_types_throw() + { + using (var context = new NonEntityVariant()) + { + Assert.NotNull(context.ObsoleteAttributes); + Assert.Throws(() => GetObjectContext(context)); + } + } + + public class DuplicateDbSetVariant : DbContext + { + public DbSet Products { get; set; } + public DbSet Categories { get; set; } + public DbSet CategoriesAgain { get; set; } + } + + [Fact] + public void Duplicate_DbSet_content_types_throw_Anti_MEST() + { + using (var context = new DuplicateDbSetVariant()) + { + Assert.Throws(() => context.Categories.FirstOrDefault()).ValidateMessage( + "Mapping_MESTNotSupported", "Categories", "CategoriesAgain", "SimpleModel.Category"); + } + } + + public class DuplicateIQueryableSetVariant : EmptyContext + { + public DuplicateIQueryableSetVariant() + : base(DefaultDbName()) + { + } + + public IQueryable Products1 { get; set; } + public IQueryable Products2 { get; set; } + } + + [Fact] + public void Duplicate_IQueryable_content_types_do_not_throw_Anti_MEST() + { + using (var context = new DuplicateIQueryableSetVariant()) + { + Assert.Null(context.Products1); + Assert.Null(context.Products2); + context.Assert().IsNotInModel(); + } + } + + public class DuplicateSetWithDifferentSetTypesVariant : EmptyContext + { + public DuplicateSetWithDifferentSetTypesVariant() + : base("CommonProductCategoryDatabase") + { + } + + public DbSet Products { get; set; } + public DbSet Categories { get; set; } + public IQueryable CategoriesAgain { get; set; } + } + + [Fact] + public void Duplicate_set_content_types_where_one_type_is_IQueryable_does_not_throw_Anti_MEST() + { + using (var context = new DuplicateSetWithDifferentSetTypesVariant()) + { + Assert.NotNull(context.Products); + Assert.NotNull(context.Categories); + Assert.Null(context.CategoriesAgain); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + public class ExceptionFromSetSetterVariant : EmptyContext + { + public ExceptionFromSetSetterVariant() + : base("CommonProductCategoryDatabase") + { + } + + public DbSet Categories { get; set; } + + public DbSet Products + { + get { return null; } + set { throw new Exception("SETTER"); } + } + } + + [Fact] + public void Exception_from_set_setter() + { + try + { + var ctx = new ExceptionFromSetSetterVariant(); + Assert.True(false, "Exception in set setter was swallowed."); + } + catch (Exception ex) + { + Assert.Equal("SETTER", ex.Message); + } + } + + #endregion + + #region Positive tests for tweaking set discovery using attributes at class level + + [SuppressDbSetInitialization] + private class ClassLevelSetDiscoverOnlyVariant : EmptyContext + { + public ClassLevelSetDiscoverOnlyVariant() + : base("CommonProductCategoryDatabase") + { + } + + public DbSet Products { get; set; } + public DbSet Categories { get; set; } + } + + [Fact] + public void + SuppressDbSetInitializationAttribute_on_context_class_results_in_entities_in_model_but_sets_not_initialized() + { + using (var context = new ClassLevelSetDiscoverOnlyVariant()) + { + Assert.Null(context.Products); + Assert.Null(context.Categories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + #endregion + + #region Positive tests for tweaking set discovery using attributes at property level + + private class PropertyLevelSetDiscoverOnlyVariant : EmptyContext + { + public PropertyLevelSetDiscoverOnlyVariant() + : base("CommonProductCategoryDatabase") + { + } + + public DbSet Products { get; set; } + + [SuppressDbSetInitialization] + public DbSet Categories { get; set; } + } + + [Fact] + public void SuppressDbSetInitializationAttribute_on_property_results_in_that_entity_in_model_but_its_set_not_initialized() + { + using (var context = new PropertyLevelSetDiscoverOnlyVariant()) + { + Assert.NotNull(context.Products); + Assert.Null(context.Categories); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + #endregion + + #region Positive Set tests + + [Fact] + public void Can_create_DbSet() + { + using (var context = new SimpleModelContext()) + { + var set = context.Set(); + Assert.IsType>(set); + + var entity = set.FirstOrDefault(); + Assert.IsType(entity); + Assert.Equal(EntityState.Unchanged, GetStateEntry(context, entity).State); + } + } + + [Fact] + public void Can_create_non_generic_DbSet() + { + using (var context = new SimpleModelContext()) + { + var set = context.Set(typeof(Category)); + Assert.Equal(typeof(Category), set.ElementType); + + var entity = set.Cast().FirstOrDefault(); + Assert.IsType(entity); + Assert.Equal(EntityState.Unchanged, GetStateEntry(context, entity).State); + } + } + + [Fact] + public void Can_create_DbSet_for_base_type() + { + using (var context = new SimpleModelContext()) + { + var set = context.Set(); + Assert.IsType>(set); + + var entity = set.FirstOrDefault(); + Assert.IsType(entity); + } + } + + [Fact] + public void Can_create_non_generic_DbSet_for_base_type() + { + using (var context = new SimpleModelContext()) + { + var set = context.Set(typeof(Product)); + Assert.Equal(typeof(Product), set.ElementType); + + var entity = set.Cast().FirstOrDefault(); + Assert.IsType(entity); + } + } + + [Fact] + public void Can_create_DbSet_for_abstract_base_type() + { + using (var context = new AdvancedPatternsMasterContext()) + { + var set = context.Set(); + Assert.IsType>(set); + + var entity = set.FirstOrDefault(); + Assert.IsAssignableFrom(entity); + } + } + + [Fact] + public void Can_create_non_generic_DbSet_for_abstract_base_type() + { + using (var context = new AdvancedPatternsMasterContext()) + { + var set = context.Set(typeof(Employee)); + Assert.Equal(typeof(Employee), set.ElementType); + + var entity = set.Cast().FirstOrDefault(); + Assert.IsAssignableFrom(entity); + } + } + + [Fact] + public void Can_create_DbSet_for_derived_type() + { + using (var context = new SimpleModelContext()) + { + var set = context.Set(); + Assert.IsType>(set); + + var entity = set.FirstOrDefault(); + Assert.IsType(entity); + Assert.Equal(EntityState.Unchanged, GetStateEntry(context, entity).State); + } + } + + [Fact] + public void Can_create_non_generic_DbSet_for_derived_type() + { + using (var context = new SimpleModelContext()) + { + var set = context.Set(typeof(FeaturedProduct)); + Assert.Equal(typeof(FeaturedProduct), set.ElementType); + + var entity = set.Cast().FirstOrDefault(); + Assert.IsType(entity); + Assert.Equal(EntityState.Unchanged, GetStateEntry(context, entity).State); + } + } + + [Fact] + public void Set_method_returns_the_same_instance_each_invocation() + { + using (var context = new SimpleModelContext()) + { + var set1 = context.Set(); + var set2 = context.Set(); + + Assert.Same(set1, set2); + Assert.Same(set1, context.Products); + } + } + + [Fact] + public void Non_generic_Set_method_returns_the_same_instance_each_invocation() + { + using (var context = new SimpleModelContext()) + { + var set1 = context.Set(typeof(Product)); + var set2 = context.Set(typeof(Product)); + + Assert.Same(set1, set2); + } + } + + #endregion + + #region Positive OnModelCreating tests + + public class TweakingModelVariant : EmptyContext + { + public DbSet Products { get; set; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + modelBuilder.Entity().HasKey(c => c.Id); + modelBuilder.Entity().HasMany(c => c.Products).WithOptional(p => p.Category).HasForeignKey( + p => p.CategoryId); + base.OnModelCreating(modelBuilder); + } + } + + [Fact] + public void Model_can_be_tweaked_in_OnModelCreating() + { + using (var context = new TweakingModelVariant()) + { + Assert.NotNull(context.Products); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + } + } + + public class OnModelCreatingVariant : DbContext + { + public DbSet Products { get; set; } + + public static int OnModelCreatingCount { get; set; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + OnModelCreatingCount++; + } + } + + [Fact] + public void OnModelCreating_is_only_called_once_by_default() + { + using (var context = new OnModelCreatingVariant()) + { + context.Assert().IsInModel(); + } + Assert.Equal(1, OnModelCreatingVariant.OnModelCreatingCount); + + using (var context = new OnModelCreatingVariant()) + { + context.Assert().IsInModel(); + } + Assert.Equal(1, OnModelCreatingVariant.OnModelCreatingCount); + + using (var context = new OnModelCreatingVariant()) + { + context.Assert().IsInModel(); + } + Assert.Equal(1, OnModelCreatingVariant.OnModelCreatingCount); + } + + public class SillyCallToOnModelCreatingVariant : EmptyContext + { + public SillyCallToOnModelCreatingVariant() + : base(DefaultDbName()) + { + OnModelCreating(new DbModelBuilder()); + } + } + + [Fact] + public void Calling_OnModelCreating_explicitly_is_noop() + { + using (var context = new SillyCallToOnModelCreatingVariant()) + { + } + } + + [Fact] + public void Can_use_context_during_construction_with_tweaking() + { + using (var context = new UseContextInCtorModelTweakingVariant()) + { + Assert.NotNull(context.Products); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + + Assert.False(GetObjectContext(context).ContextOptions.LazyLoadingEnabled); + Assert.False(context.Configuration.LazyLoadingEnabled); + } + } + + public class UseContextInCtorModelTweakingVariant : EmptyContext + { + public UseContextInCtorModelTweakingVariant() + { + ((IObjectContextAdapter)this).ObjectContext.ContextOptions.LazyLoadingEnabled = false; + } + + public DbSet Products { get; set; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + modelBuilder.Entity().HasKey(c => c.Id); + modelBuilder.Entity().HasMany(c => c.Products).WithOptional(p => p.Category).HasForeignKey( + p => p.CategoryId); + base.OnModelCreating(modelBuilder); + } + } + + #endregion + + #region Negative OnModelCreating tests + + public class UseModeWhileCreatingVariant : EmptyContext + { + public UseModeWhileCreatingVariant() + : base("CommonProductCategoryDatabase") + { + } + + public DbSet Products { get; set; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + Products.FirstOrDefault(); + base.OnModelCreating(modelBuilder); + } + } + + [Fact] + public void Using_context_during_OnModelCreating_throws() + { + using (var context = new UseModeWhileCreatingVariant()) + { + Assert.Throws(() => context.Products.FirstOrDefault()).ValidateMessage( + "DbContext_ContextUsedInModelCreating"); + } + } + + #endregion + + #region Positive non-derived context tests using an existing model + + [Fact] + public void Model_passed_to_DbContext_string_constructor_is_used_to_back_the_context() + { + Model_passed_to_DbContext_constructor_is_used_to_back_the_context( + model => new DbContext(DefaultDbName(), model)); + } + + [Fact] + public void Model_passed_to_DbContext_DbConnection_constructor_is_used_to_back_the_context() + { + using (var connection = SimpleConnection()) + { + Model_passed_to_DbContext_constructor_is_used_to_back_the_context( + model => new DbContext(connection, model, contextOwnsConnection: false)); + } + } + + private void Model_passed_to_DbContext_constructor_is_used_to_back_the_context( + Func factory) + { + using (var context = factory(CreateSimpleModel())) + { + context.Assert().IsInModel(); + context.Assert().IsInModel(); + context.Assert().IsNotInModel(); + + // Verify that we can use sets and we are connected to the correct database + Assert.Equal("Marmite", context.Set().Find(1).Name); + Assert.Equal("Foods", context.Set().Find("Foods").Id); + } + } + + private static DbCompiledModel CreateSimpleModel() + { + return SimpleModelContext.CreateBuilder().Build(ProviderRegistry.Sql2008_ProviderInfo).Compile(); + } + + #endregion + + #region Positive derived context tests using existing model + + private class DerivedContextWithMismatchedModel : DbContext + { + public DerivedContextWithMismatchedModel(DbCompiledModel model) + : base(model) + { + } + + public DerivedContextWithMismatchedModel(string nameOrConnectionString, DbCompiledModel model) + : base(nameOrConnectionString, model) + { + } + + public DerivedContextWithMismatchedModel(DbConnection existingConnection, DbCompiledModel model) + : base(existingConnection, model, contextOwnsConnection: false) + { + } + + public DbSet Logins { get; set; } + } + + [Fact] + public void Model_passed_to_derived_DbContext_constructor_is_used_and_the_sets_on_context_are_not_used() + { + // In this case we can't control the name of the database, so it won't be the normal SimpleModel database + using (var context = new DerivedContextWithMismatchedModel(CreateSimpleModel())) + { + context.Assert().IsInModel(); + context.Assert().IsInModel(); + context.Assert().IsNotInModel(); + + Assert.Throws(() => context.Logins.ToList()).ValidateMessage( + "DbSet_EntityTypeNotInModel", "Login"); + } + } + + [Fact] + public void Model_passed_to_derived_DbContext_string_constructor_is_used_and_the_sets_on_context_are_not_used() + { + Model_passed_to_DbContext_constructor_is_used_to_back_the_context( + model => new DerivedContextWithMismatchedModel(DefaultDbName(), model)); + } + + [Fact] + public void + Model_passed_to_derived_DbContext_DbConnection_constructor_is_used_and_the_sets_on_context_are_not_used() + { + using (var connection = SimpleConnection()) + { + Model_passed_to_DbContext_constructor_is_used_to_back_the_context( + model => new DerivedContextWithMismatchedModel(connection, model)); + } + } + + #endregion + + #region Lazy loading tests + + private void ValidateLazyLoading(F1Context context, bool lazyLoadingEnabled) + { + Assert.Equal(lazyLoadingEnabled, context.Configuration.LazyLoadingEnabled); + Assert.Equal(lazyLoadingEnabled, GetObjectContext(context).ContextOptions.LazyLoadingEnabled); + + context.ChangeTracker.Entries().ToList().ForEach(e => e.State = EntityState.Detached); + + var team = context.Drivers.First().Team; + if (lazyLoadingEnabled) + { + Assert.NotNull(team); + } + else + { + Assert.Null(team); + } + } + + private static DbCompiledModel CreateF1Model() + { + var builder = new DbModelBuilder(); + + F1Context.AdditionalModelConfiguration(builder); + + return builder.Build(ProviderRegistry.Sql2008_ProviderInfo).Compile(); + } + + [Fact] + public void Lazy_loading_is_on_by_default_when_using_empty_constructor() + { + using (var context = new F1Context()) + { + ValidateLazyLoading(context, lazyLoadingEnabled: true); + } + } + + [Fact] + public void Lazy_loading_is_on_by_default_when_using_String_constructor() + { + using (var context = new F1Context(DefaultDbName())) + { + ValidateLazyLoading(context, lazyLoadingEnabled: true); + } + } + + [Fact] + public void Lazy_loading_is_on_by_default_when_using_DbCompiledModel_constructor() + { + using (var context = new F1Context(CreateF1Model())) + { + ValidateLazyLoading(context, lazyLoadingEnabled: true); + } + } + + [Fact] + public void Lazy_loading_is_on_by_default_when_using_String_and_DbCompiledModel_constructor() + { + using (var context = new F1Context(DefaultDbName(), CreateF1Model())) + { + ValidateLazyLoading(context, lazyLoadingEnabled: true); + } + } + + [Fact] + public void Lazy_loading_is_on_by_default_when_using_DbConnection_constructor() + { + using (var context = new F1Context(SimpleConnection(), contextOwnsConnection: true)) + { + ValidateLazyLoading(context, lazyLoadingEnabled: true); + } + } + + [Fact] + public void Lazy_loading_is_on_by_default_when_using_DbConnection_and_DbCompiledModel_constructor() + { + using ( + var context = new F1Context(SimpleConnection(), CreateF1Model(), contextOwnsConnection: true) + ) + { + ValidateLazyLoading(context, lazyLoadingEnabled: true); + } + } + + [Fact] + public void Lazy_loading_is_on_by_default_when_using_entity_connection_string_in_constructor() + { + using (var context = new DbContext(SimpleModelEntityConnectionString)) + { + Assert.True(context.Configuration.LazyLoadingEnabled); + var objectContext = GetObjectContext(context); + Assert.True(objectContext.ContextOptions.LazyLoadingEnabled); + } + } + + [Fact] + public void Lazy_loading_is_on_by_default_when_using_EntityConnection_object_in_constructor() + { + using ( + var context = new DbContext( + new EntityConnection(SimpleModelEntityConnectionString), + contextOwnsConnection: true)) + { + Assert.True(context.Configuration.LazyLoadingEnabled); + var objectContext = GetObjectContext(context); + Assert.True(objectContext.ContextOptions.LazyLoadingEnabled); + } + } + + [Fact] + public void Lazy_loading_flag_can_be_inherited_from_ObjectContext_as_true_when_using_ObjectContext_constructor() + { + Lazy_loading_flag_is_inherited_from_ObjectContext_when_using_ObjectContext_constructor( + lazyLoadingEnabled: true); + } + + [Fact] + public void Lazy_loading_flag_can_be_inherited_from_ObjectContext_as_false_when_using_ObjectContext_constructor() + { + Lazy_loading_flag_is_inherited_from_ObjectContext_when_using_ObjectContext_constructor( + lazyLoadingEnabled: false); + } + + private void Lazy_loading_flag_is_inherited_from_ObjectContext_when_using_ObjectContext_constructor( + bool lazyLoadingEnabled) + { + var objectContext = GetObjectContext(new F1Context()); + objectContext.ContextOptions.LazyLoadingEnabled = lazyLoadingEnabled; + + using (var context = new F1Context(objectContext, dbContextOwnsObjectContext: true)) + { + ValidateLazyLoading(context, lazyLoadingEnabled); + } + } + + [Fact] + public void Lazy_loading_can_be_switched_off_in_constructor_which_calls_to_base_empty_constructor() + { + using (var context = new F1Context(lazyLoadingEnabled: false)) + { + ValidateLazyLoading(context, lazyLoadingEnabled: false); + } + } + + [Fact] + public void Lazy_loading_can_be_switched_off_in_constructor_which_calls_to_base_String_constructor() + { + using (var context = new F1Context(DefaultDbName(), lazyLoadingEnabled: false)) + { + ValidateLazyLoading(context, lazyLoadingEnabled: false); + } + } + + [Fact] + public void Lazy_loading_can_be_switched_off_in_constructor_which_calls_to_base_DbCompiledModel_constructor() + { + using (var context = new F1Context(CreateF1Model(), lazyLoadingEnabled: false)) + { + ValidateLazyLoading(context, lazyLoadingEnabled: false); + } + } + + [Fact] + public void + Lazy_loading_can_be_switched_off_in_constructor_which_calls_to_base_String_and_DbCompiledModel_constructor() + { + using (var context = new F1Context(DefaultDbName(), CreateF1Model(), lazyLoadingEnabled: false)) + { + ValidateLazyLoading(context, lazyLoadingEnabled: false); + } + } + + [Fact] + public void Lazy_loading_can_be_switched_off_in_constructor_which_calls_to_base_DbConnection_constructor() + { + using ( + var context = new F1Context( + SimpleConnection(), contextOwnsConnection: true, + lazyLoadingEnabled: false)) + { + ValidateLazyLoading(context, lazyLoadingEnabled: false); + } + } + + [Fact] + public void Lazy_loading_can_be_switched_off_in_constructor_which_calls_to_base_DbConnection_and_DbCompiledModel_constructor() + { + using ( + var context = new F1Context( + SimpleConnection(), CreateF1Model(), contextOwnsConnection: true, + lazyLoadingEnabled: false)) + { + ValidateLazyLoading(context, lazyLoadingEnabled: false); + } + } + + [Fact] + public void Lazy_loading_can_be_switched_off_in_constructor_which_calls_to_base_ObjectContext_constructor() + { + var objectContext = GetObjectContext(new F1Context()); + objectContext.ContextOptions.LazyLoadingEnabled = true; + + using ( + var context = new F1Context(objectContext, dbContextOwnsObjectContext: true, lazyLoadingEnabled: false)) + { + ValidateLazyLoading(context, false); + } + } + + public class LazyLoadingFlagTestContext : EmptyContext + { + public LazyLoadingFlagTestContext() + : base(DefaultDbName()) + { + } + + public LazyLoadingFlagTestContext(string connectionString) + : base(connectionString) + { + } + + public LazyLoadingFlagTestContext(DbConnection connection) + : base(connection, contextOwnsConnection: true) + { + } + + public bool ModelCreated { get; set; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + ModelCreated = true; + base.OnModelCreating(modelBuilder); + } + } + + [Fact] + public void Lazy_loading_can_be_changed_after_DbContext_is_created_but_before_initialization_when_using_entity_connection_string() + { + Lazy_loading_can_be_changed_after_DbContext_is_created_but_before_initialization( + () => new LazyLoadingFlagTestContext(SimpleModelEntityConnectionString), expectOnModelCreation: false); + } + + [Fact] + public void Lazy_loading_can_be_changed_after_DbContext_is_created_but_before_initialization_when_using_EntityConnection() + { + Lazy_loading_can_be_changed_after_DbContext_is_created_but_before_initialization( + () => new LazyLoadingFlagTestContext(new EntityConnection(SimpleModelEntityConnectionString)), + expectOnModelCreation: false); + } + + [Fact] + public void + Lazy_loading_can_be_changed_after_DbContext_is_created_without_causing_ObjectContext_initialization_when_using_code_first() + { + Lazy_loading_can_be_changed_after_DbContext_is_created_but_before_initialization( + () => new LazyLoadingFlagTestContext(), expectOnModelCreation: true); + } + + private void Lazy_loading_can_be_changed_after_DbContext_is_created_but_before_initialization( + Func createContext, bool expectOnModelCreation) + { + using (var context = createContext()) + { + Assert.True(context.Configuration.LazyLoadingEnabled); + + context.Configuration.LazyLoadingEnabled = false; + Assert.False(context.Configuration.LazyLoadingEnabled); + + context.Configuration.LazyLoadingEnabled = true; + Assert.True(context.Configuration.LazyLoadingEnabled); + + context.Configuration.LazyLoadingEnabled = false; + Assert.False(context.ModelCreated); + + Assert.Equal(false, GetObjectContext(context).ContextOptions.LazyLoadingEnabled); + Assert.Equal(expectOnModelCreation, context.ModelCreated); + } + } + + [Fact] + public void + Changing_lazy_loading_flag_after_ObjectContext_is_initialized_causes_lazy_loading_flag_in_DbContext_and_ObjectContext_to_change( + + ) + { + using (var context = new F1Context()) + { + ValidateLazyLoading(context, lazyLoadingEnabled: true); + + context.Configuration.LazyLoadingEnabled = false; + ValidateLazyLoading(context, lazyLoadingEnabled: false); + + context.Configuration.LazyLoadingEnabled = true; + ValidateLazyLoading(context, lazyLoadingEnabled: true); + } + } + + [Fact] + public void Changing_lazy_loading_flag_in_ObjectContext_causes_lazy_loading_flag_in_DbContext_and_ObjectContext_to_change() + { + using (var context = new F1Context()) + { + ValidateLazyLoading(context, lazyLoadingEnabled: true); + + GetObjectContext(context).ContextOptions.LazyLoadingEnabled = false; + ValidateLazyLoading(context, lazyLoadingEnabled: false); + + GetObjectContext(context).ContextOptions.LazyLoadingEnabled = true; + ValidateLazyLoading(context, lazyLoadingEnabled: true); + } + } + + [Fact] + public void Entity_reference_does_not_get_lazily_loaded_if_LazyLoadingEnabled_is_set_to_false() + { + using (var context = new F1Context()) + { + context.Configuration.LazyLoadingEnabled = false; + var driver = context.Drivers.FirstOrDefault(); + + Assert.Null(driver.Team); + } + } + + [Fact] + public void Entity_collection_does_not_get_lazily_loaded_if_LazyLoadingEnabled_is_set_to_false() + { + using (var context = new F1Context()) + { + context.Configuration.LazyLoadingEnabled = false; + var team = context.Teams.FirstOrDefault(); + + Assert.Equal(0, team.Drivers.Count); + } + } + + [Fact] + public void Lazy_loading_throws_when_done_outside_context_scope() + { + Team team; + using (var context = new F1Context()) + { + team = context.Teams.FirstOrDefault(); + } + + Assert.Throws(() => team.Engine); + Assert.Throws(() => team.Drivers); + } + + [Fact] + public void Lazy_loading_wires_up_references_navigations_correctly() + { + using (var context = new F1Context()) + { + // get driver and engine supplier that would navigate to the same engine + var query = context.Drivers.Select(d => new { DriverId = d.Id, EngineSupplierId = d.Team.Engine.EngineSupplier.Id }).AsNoTracking(); + var tuple = query.FirstOrDefault(); + var driverId = tuple.DriverId; + var engineSupplierId = tuple.EngineSupplierId; + + var driver = context.Drivers.Where(d => d.Id == driverId).Single(); + var team = driver.Team; + + var engineSupplier = context.EngineSuppliers.Where(es => es.Id == engineSupplierId).Single(); + var engine = engineSupplier.Engines; + + context.Configuration.LazyLoadingEnabled = false; + + Assert.NotNull(team.Engine); + } + } + + [Fact] + public void Lazy_loading_wires_up_collection_navigations_correctly() + { + using (var context = new F1Context()) + { + var query = context.Sponsors.SelectMany(s => s.Teams, (s, t) => new { SponsorId = s.Id, EngineId = t.Engine.Id }).AsNoTracking(); + var tuple = query.FirstOrDefault(); + var sponsor = context.Sponsors.Where(s => s.Id == tuple.SponsorId).Single(); + var sponsorTeams = sponsor.Teams; + + var engine = context.Engines.Where(e => e.Id == tuple.EngineId).Single(); + + context.Configuration.LazyLoadingEnabled = false; + + Assert.True(engine.Teams.Count > 0); + bool engineTeamsContainSponsorTeam = false; + foreach (var sponsorTeam in sponsorTeams) + { + if (engine.Teams.Contains(sponsorTeam)) + { + engineTeamsContainSponsorTeam = true; + } + } + + Assert.True(engineTeamsContainSponsorTeam); + + foreach (var engineTeam in engine.Teams) + { + Assert.True(sponsorTeams.Contains(engineTeam)); + } + } + } + + [Fact] + public void Lazy_loading_many_to_many_navigation_works_properly() + { + using (var context = new F1Context()) + { + var teamId = context.Teams.OrderBy(t => t.Id).AsNoTracking().FirstOrDefault().Id; + var sponsorsId = context.Teams.Where(t => t.Id == teamId).SelectMany(t => t.Sponsors).AsNoTracking().Select(s => s.Id).ToList(); + + var team = context.Teams.Where(t => t.Id == teamId).Single(); + var sponsors = team.Sponsors; + + context.Configuration.LazyLoadingEnabled = false; + + foreach (var sponsor in sponsors) + { + Assert.True(sponsorsId.Contains(sponsor.Id)); + } + } + } + + #endregion + + #region Proxy creation tests + + private void ValidateProxyCreation(F1Context context, bool proxyCreationEnabled) + { + Assert.Equal(proxyCreationEnabled, context.Configuration.ProxyCreationEnabled); + Assert.Equal(proxyCreationEnabled, GetObjectContext(context).ContextOptions.ProxyCreationEnabled); + + context.ChangeTracker.Entries().ToList().ForEach(e => e.State = EntityState.Detached); + + var driver = context.Drivers.First(); + if (proxyCreationEnabled) + { + Assert.NotEqual(typeof(Driver), driver.GetType()); + } + else + { + Assert.Equal(typeof(Driver), driver.GetType()); + } + } + + [Fact] + public void Proxy_creation_is_on_by_default_when_using_empty_constructor() + { + using (var context = new F1Context()) + { + ValidateProxyCreation(context, proxyCreationEnabled: true); + } + } + + [Fact] + public void Proxy_creation_is_on_by_default_when_using_String_constructor() + { + using (var context = new F1Context(DefaultDbName())) + { + ValidateProxyCreation(context, proxyCreationEnabled: true); + } + } + + [Fact] + public void Proxy_creation_is_on_by_default_when_using_DbCompiledModel_constructor() + { + using (var context = new F1Context(CreateF1Model())) + { + ValidateProxyCreation(context, proxyCreationEnabled: true); + } + } + + [Fact] + public void Proxy_creation_is_on_by_default_when_using_String_and_DbCompiledModel_constructor() + { + using (var context = new F1Context(DefaultDbName(), CreateF1Model())) + { + ValidateProxyCreation(context, proxyCreationEnabled: true); + } + } + + [Fact] + public void Proxy_creation_is_on_by_default_when_using_DbConnection_constructor() + { + using (var context = new F1Context(SimpleConnection(), contextOwnsConnection: true)) + { + ValidateProxyCreation(context, proxyCreationEnabled: true); + } + } + + [Fact] + public void Proxy_creation_is_on_by_default_when_using_DbConnection_and_DbCompiledModel_constructor() + { + using ( + var context = new F1Context(SimpleConnection(), CreateF1Model(), contextOwnsConnection: true) + ) + { + ValidateProxyCreation(context, proxyCreationEnabled: true); + } + } + + [Fact] + public void Proxy_creation_is_on_by_default_when_using_entity_connection_string_in_constructor() + { + using (var context = new DbContext(SimpleModelEntityConnectionString)) + { + Assert.True(context.Configuration.ProxyCreationEnabled); + var objectContext = GetObjectContext(context); + Assert.True(objectContext.ContextOptions.ProxyCreationEnabled); + } + } + + [Fact] + public void Proxy_creation_is_on_by_default_when_using_EntityConnection_object_in_constructor() + { + using ( + var context = new DbContext( + new EntityConnection(SimpleModelEntityConnectionString), + contextOwnsConnection: true)) + { + Assert.True(context.Configuration.ProxyCreationEnabled); + var objectContext = GetObjectContext(context); + Assert.True(objectContext.ContextOptions.ProxyCreationEnabled); + } + } + + [Fact] + public void Proxy_creation_flag_can_be_inherited_from_ObjectContext_as_true_when_using_ObjectContext_constructor() + { + Proxy_creation_flag_is_inherited_from_ObjectContext_when_using_ObjectContext_constructor( + proxyCreationEnabled: true); + } + + [Fact] + public void + Proxy_creation_flag_can_be_inherited_from_ObjectContext_as_false_when_using_ObjectContext_constructor() + { + Proxy_creation_flag_is_inherited_from_ObjectContext_when_using_ObjectContext_constructor( + proxyCreationEnabled: false); + } + + private void Proxy_creation_flag_is_inherited_from_ObjectContext_when_using_ObjectContext_constructor( + bool proxyCreationEnabled) + { + var objectContext = GetObjectContext(new F1Context()); + objectContext.ContextOptions.ProxyCreationEnabled = proxyCreationEnabled; + + using (var context = new F1Context(objectContext, dbContextOwnsObjectContext: true)) + { + ValidateProxyCreation(context, proxyCreationEnabled); + } + } + + [Fact] + public void Proxy_creation_can_be_switched_off_in_constructor_which_calls_to_base_empty_constructor() + { + using (var context = new F1Context(proxyCreationEnabled: false)) + { + ValidateProxyCreation(context, proxyCreationEnabled: false); + } + } + + [Fact] + public void Proxy_creation_can_be_switched_off_in_constructor_which_calls_to_base_String_constructor() + { + using (var context = new F1Context(DefaultDbName(), proxyCreationEnabled: false)) + { + ValidateProxyCreation(context, proxyCreationEnabled: false); + } + } + + [Fact] + public void Proxy_creation_can_be_switched_off_in_constructor_which_calls_to_base_DbCompiledModel_constructor() + { + using (var context = new F1Context(CreateF1Model(), proxyCreationEnabled: false)) + { + ValidateProxyCreation(context, proxyCreationEnabled: false); + } + } + + [Fact] + public void Proxy_creation_can_be_switched_off_in_constructor_which_calls_to_base_String_and_DbCompiledModel_constructor() + { + using (var context = new F1Context(DefaultDbName(), CreateF1Model(), proxyCreationEnabled: false) + ) + { + ValidateProxyCreation(context, proxyCreationEnabled: false); + } + } + + [Fact] + public void Proxy_creation_can_be_switched_off_in_constructor_which_calls_to_base_DbConnection_constructor() + { + using ( + var context = new F1Context( + SimpleConnection(), contextOwnsConnection: true, + proxyCreationEnabled: false)) + { + ValidateProxyCreation(context, proxyCreationEnabled: false); + } + } + + [Fact] + public void Proxy_creation_can_be_switched_off_in_constructor_which_calls_to_base_DbConnection_and_DbCompiledModel_constructor() + { + using ( + var context = new F1Context( + SimpleConnection(), CreateF1Model(), contextOwnsConnection: true, + proxyCreationEnabled: false)) + { + ValidateProxyCreation(context, proxyCreationEnabled: false); + } + } + + [Fact] + public void Proxy_creation_can_be_switched_off_in_constructor_which_calls_to_base_ObjectContext_constructor() + { + var objectContext = GetObjectContext(new F1Context()); + objectContext.ContextOptions.ProxyCreationEnabled = true; + + using ( + var context = new F1Context(objectContext, dbContextOwnsObjectContext: true, proxyCreationEnabled: false) + ) + { + ValidateProxyCreation(context, false); + } + } + + public class ProxyCreationFlagTestContext : EmptyContext + { + public ProxyCreationFlagTestContext() + : base(DefaultDbName()) + { + } + + public ProxyCreationFlagTestContext(string connectionString) + : base(connectionString) + { + } + + public ProxyCreationFlagTestContext(DbConnection connection) + : base(connection, contextOwnsConnection: true) + { + } + + public bool ModelCreated { get; set; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + ModelCreated = true; + base.OnModelCreating(modelBuilder); + } + } + + [Fact] + public void Proxy_creation_can_be_changed_after_DbContext_is_created_but_before_initialization_when_using_entity_connection_string() + { + Proxy_creation_can_be_changed_after_DbContext_is_created_but_before_initialization( + () => new ProxyCreationFlagTestContext(SimpleModelEntityConnectionString), expectOnModelCreation: false); + } + + [Fact] + public void Proxy_creation_can_be_changed_after_DbContext_is_created_but_before_initialization_when_using_EntityConnection() + { + Proxy_creation_can_be_changed_after_DbContext_is_created_but_before_initialization( + () => new ProxyCreationFlagTestContext(new EntityConnection(SimpleModelEntityConnectionString)), + expectOnModelCreation: false); + } + + [Fact] + public void + Proxy_creation_can_be_changed_after_DbContext_is_created_without_causing_ObjectContext_initialization_when_using_code_first() + { + Proxy_creation_can_be_changed_after_DbContext_is_created_but_before_initialization( + () => new ProxyCreationFlagTestContext(), expectOnModelCreation: true); + } + + private void Proxy_creation_can_be_changed_after_DbContext_is_created_but_before_initialization( + Func createContext, bool expectOnModelCreation) + { + using (var context = createContext()) + { + Assert.True(context.Configuration.ProxyCreationEnabled); + + context.Configuration.ProxyCreationEnabled = false; + Assert.False(context.Configuration.ProxyCreationEnabled); + + context.Configuration.ProxyCreationEnabled = true; + Assert.True(context.Configuration.ProxyCreationEnabled); + + context.Configuration.ProxyCreationEnabled = false; + Assert.False(context.ModelCreated); + + Assert.Equal(false, GetObjectContext(context).ContextOptions.ProxyCreationEnabled); + Assert.Equal(expectOnModelCreation, context.ModelCreated); + } + } + + [Fact] + public void + Changing_proxy_creation_flag_after_ObjectContext_is_initialized_causes_proxy_creation_flag_in_DbContext_and_ObjectContext_to_change + () + { + using (var context = new F1Context()) + { + ValidateProxyCreation(context, proxyCreationEnabled: true); + + context.Configuration.ProxyCreationEnabled = false; + ValidateProxyCreation(context, proxyCreationEnabled: false); + + context.Configuration.ProxyCreationEnabled = true; + ValidateProxyCreation(context, proxyCreationEnabled: true); + } + } + + [Fact] + public void Changing_proxy_creation_flag_in_ObjectContext_causes_proxy_creation_flag_in_DbContext_and_ObjectContext_to_change() + { + using (var context = new F1Context()) + { + ValidateProxyCreation(context, proxyCreationEnabled: true); + + GetObjectContext(context).ContextOptions.ProxyCreationEnabled = false; + ValidateProxyCreation(context, proxyCreationEnabled: false); + + GetObjectContext(context).ContextOptions.ProxyCreationEnabled = true; + ValidateProxyCreation(context, proxyCreationEnabled: true); + } + } + + #endregion + + #region DetectChanges tests + + [Fact] + public void AutoDetectChangesEnabled_is_on_by_default_and_can_be_changed() + { + using (var context = new F1Context()) + { + Assert.True(context.Configuration.AutoDetectChangesEnabled); + + context.Configuration.AutoDetectChangesEnabled = false; + + Assert.False(context.Configuration.AutoDetectChangesEnabled); + } + } + + [Fact] + public void Explicitly_calling_DetectChanges_results_in_change_detection() + { + TestDetectChanges(c => c.ChangeTracker.DetectChanges(), autoDetectChanges: true); + } + + [Fact] + public void + Explicitly_calling_DetectChanges_results_in_change_detection_even_when_AutoDetectChangesEnabled_is_off() + { + TestDetectChanges(c => c.ChangeTracker.DetectChanges(), autoDetectChanges: false, expectDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_called_by_Find_on_generic_DbSet_when_AutoDetectChangesEnabled_is_on() + { + TestDetectChanges(c => c.Teams.Find(Team.Williams), autoDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_called_by_Add_on_generic_DbSet_when_AutoDetectChangesEnabled_is_on() + { + TestDetectChanges(c => c.Drivers.Add(new Driver()), autoDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_called_by_Attach_on_generic_DbSet_when_AutoDetectChangesEnabled_is_on() + { + TestDetectChanges(c => c.Drivers.Attach(new Driver()), autoDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_called_by_Remove_on_generic_DbSet_when_AutoDetectChangesEnabled_is_on() + { + Driver driver = null; + TestDetectChanges( + c => { driver = c.Drivers.Add(new Driver()); }, c => c.Drivers.Remove(driver), + autoDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_called_by_Local_on_generic_DbSet_when_AutoDetectChangesEnabled_is_on() + { + TestDetectChanges(c => { var _ = c.Drivers.Local; }, autoDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_called_by_Find_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_on() + { + TestDetectChanges(c => c.Set(typeof(Team)).Find(Team.Williams), autoDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_called_by_Add_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_on() + { + TestDetectChanges(c => c.Set(typeof(Driver)).Add(new Driver()), autoDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_called_by_Attach_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_on() + { + TestDetectChanges(c => c.Set(typeof(Driver)).Attach(new Driver()), autoDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_called_by_Remove_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_on() + { + Driver driver = null; + TestDetectChanges( + c => { driver = c.Drivers.Add(new Driver()); }, c => c.Set(typeof(Driver)).Remove(driver), + autoDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_called_by_Local_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_on() + { + TestDetectChanges(c => { var _ = c.Set(typeof(Driver)).Local; }, autoDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_called_by_non_generic_Entry_when_AutoDetectChangesEnabled_is_on() + { + TestDetectChanges(c => c.Entry((object)new Driver()), autoDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_called_by_generic_Entry_when_AutoDetectChangesEnabled_is_on() + { + TestDetectChanges(c => c.Entry(new Driver()), autoDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_called_by_non_generic_Entries_when_AutoDetectChangesEnabled_is_on() + { + TestDetectChanges(c => c.ChangeTracker.Entries(), autoDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_called_by_generic_Entries_when_AutoDetectChangesEnabled_is_on() + { + TestDetectChanges(c => c.ChangeTracker.Entries(), autoDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_not_called_by_Find_on_generic_DbSet_when_AutoDetectChangesEnabled_is_off() + { + TestDetectChanges(c => c.Teams.Find(Team.Williams), autoDetectChanges: false); + } + + [Fact] + public void DetectChanges_is_not_called_by_Add_on_generic_DbSet_when_AutoDetectChangesEnabled_is_off() + { + TestDetectChanges(c => c.Drivers.Add(new Driver()), autoDetectChanges: false); + } + + [Fact] + public void DetectChanges_is_not_called_by_Attach_on_generic_DbSet_when_AutoDetectChangesEnabled_is_off() + { + TestDetectChanges(c => c.Drivers.Attach(new Driver()), autoDetectChanges: false); + } + + [Fact] + public void DetectChanges_is_not_called_by_Remove_on_generic_DbSet_when_AutoDetectChangesEnabled_is_off() + { + Driver driver = null; + TestDetectChanges( + c => { driver = c.Drivers.Add(new Driver()); }, c => c.Drivers.Remove(driver), + autoDetectChanges: false); + } + + [Fact] + public void DetectChanges_is_not_called_by_Local_on_generic_DbSet_when_AutoDetectChangesEnabled_is_off() + { + TestDetectChanges(c => { var _ = c.Drivers.Local; }, autoDetectChanges: false); + } + + [Fact] + public void DetectChanges_is_not_called_by_Find_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_off() + { + TestDetectChanges(c => c.Set(typeof(Team)).Find(Team.Williams), autoDetectChanges: false); + } + + [Fact] + public void DetectChanges_is_not_called_by_Add_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_off() + { + TestDetectChanges(c => c.Set(typeof(Driver)).Add(new Driver()), autoDetectChanges: false); + } + + [Fact] + public void DetectChanges_is_not_called_by_Attach_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_off() + { + TestDetectChanges(c => c.Set(typeof(Driver)).Attach(new Driver()), autoDetectChanges: false); + } + + [Fact] + public void DetectChanges_is_not_called_by_Remove_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_off() + { + Driver driver = null; + TestDetectChanges( + c => { driver = c.Drivers.Add(new Driver()); }, c => c.Set(typeof(Driver)).Remove(driver), + autoDetectChanges: false); + } + + [Fact] + public void DetectChanges_is_not_called_by_Local_on_non_generic_DbSet_when_AutoDetectChangesEnabled_is_off() + { + TestDetectChanges(c => { var _ = c.Set(typeof(Driver)).Local; }, autoDetectChanges: false); + } + + [Fact] + public void DetectChanges_is_not_called_by_non_generic_Entry_when_AutoDetectChangesEnabled_is_off() + { + TestDetectChanges(c => c.Entry((object)new Driver()), autoDetectChanges: false); + } + + [Fact] + public void DetectChanges_is_not_called_by_generic_Entry_when_AutoDetectChangesEnabled_is_off() + { + TestDetectChanges(c => c.Entry(new Driver()), autoDetectChanges: false); + } + + [Fact] + public void DetectChanges_is_not_called_by_non_generic_Entries_when_AutoDetectChangesEnabled_is_off() + { + TestDetectChanges(c => c.ChangeTracker.Entries(), autoDetectChanges: false); + } + + [Fact] + public void DetectChanges_is_not_called_by_generic_Entries_when_AutoDetectChangesEnabled_is_off() + { + TestDetectChanges(c => c.ChangeTracker.Entries(), autoDetectChanges: false); + } + + private void TestDetectChanges( + Action actOnContext, bool autoDetectChanges, + bool? expectDetectChanges = null) + { + TestDetectChanges(c => { }, actOnContext, autoDetectChanges, expectDetectChanges); + } + + private void TestDetectChanges( + Action setupContext, Action actOnContext, + bool autoDetectChanges, bool? expectDetectChanges = null) + { + using (var context = new F1Context()) + { + context.Configuration.AutoDetectChangesEnabled = autoDetectChanges; + + setupContext(context); + + var mclaren = context.Teams.Find(Team.McLaren); + var larryEntry = context.Entry( + new Driver + { + Name = "Larry David" + }); + mclaren.Drivers.Add(larryEntry.Entity); + + actOnContext(context); + + Assert.Equal( + expectDetectChanges ?? autoDetectChanges ? EntityState.Added : EntityState.Detached, + larryEntry.State); + } + } + + [Fact] + public void DetectChanges_is_called_by_SaveChanges_when_AutoDetectChangesEnabled_is_on() + { + TestDetectChangesWithSaveChanges(autoDetectChanges: true); + } + + [Fact] + public void DetectChanges_is_not_called_by_SaveChanges_when_AutoDetectChangesEnabled_is_off() + { + TestDetectChangesWithSaveChanges(autoDetectChanges: false); + } + + private void TestDetectChangesWithSaveChanges(bool autoDetectChanges) + { + using (var context = new F1Context()) + { + context.Database.Initialize(force: false); + + using (new TransactionScope()) + { + context.Configuration.AutoDetectChangesEnabled = autoDetectChanges; + + var mclaren = context.Teams.Find(Team.McLaren); + var larryEntry = context.Entry( + new Driver + { + Name = "Larry David" + }); + mclaren.Drivers.Add(larryEntry.Entity); + + Assert.Equal(autoDetectChanges ? EntityState.Added : EntityState.Detached, larryEntry.State); + + context.SaveChanges(); + + Assert.Equal(autoDetectChanges ? EntityState.Unchanged : EntityState.Detached, larryEntry.State); + } + } + } + + #endregion + + #region ValidateOnSaveEnabled tests + + [Fact] + public void ValidateOnSaveEnabled_is_on_by_default_when_using_empty_constructor() + { + using (var context = new F1Context()) + { + Assert.True(context.Configuration.ValidateOnSaveEnabled); + } + } + + [Fact] + public void ValidateOnSaveEnabled_is_on_by_default_when_using_String_constructor() + { + using (var context = new F1Context(DefaultDbName())) + { + Assert.True(context.Configuration.ValidateOnSaveEnabled); + } + } + + [Fact] + public void ValidateOnSaveEnabled_is_on_by_default_when_using_DbCompiledModel_constructor() + { + using (var context = new F1Context(CreateF1Model())) + { + Assert.True(context.Configuration.ValidateOnSaveEnabled); + } + } + + [Fact] + public void ValidateOnSaveEnabled_is_on_by_default_when_using_String_and_DbCompiledModel_constructor() + { + using (var context = new F1Context(DefaultDbName(), CreateF1Model())) + { + Assert.True(context.Configuration.ValidateOnSaveEnabled); + } + } + + [Fact] + public void ValidateOnSaveEnabled_is_on_by_default_when_using_DbConnection_constructor() + { + using (var context = new F1Context(SimpleConnection(), contextOwnsConnection: true)) + { + Assert.True(context.Configuration.ValidateOnSaveEnabled); + } + } + + [Fact] + public void ValidateOnSaveEnabled_is_on_by_default_when_using_DbConnection_and_DbCompiledModel_constructor() + { + using ( + var context = new F1Context(SimpleConnection(), CreateF1Model(), contextOwnsConnection: true) + ) + { + Assert.True(context.Configuration.ValidateOnSaveEnabled); + } + } + + [Fact] + public void ValidateOnSaveEnabled_is_on_by_default_when_using_entity_connection_string_in_constructor() + { + using (var context = new DbContext(SimpleModelEntityConnectionString)) + { + Assert.True(context.Configuration.ValidateOnSaveEnabled); + } + } + + [Fact] + public void ValidateOnSaveEnabled_is_on_by_default_when_using_EntityConnection_object_in_constructor() + { + using ( + var context = new DbContext( + new EntityConnection(SimpleModelEntityConnectionString), + contextOwnsConnection: true)) + { + Assert.True(context.Configuration.ValidateOnSaveEnabled); + } + } + + [Fact] + public void ValidateOnSaveEnabled_flag_is_on_by_default_when_using_ObjectContext_constructor() + { + var objectContext = GetObjectContext(new F1Context()); + using (var context = new F1Context(objectContext, dbContextOwnsObjectContext: true)) + { + Assert.True(context.Configuration.ValidateOnSaveEnabled); + } + } + + [Fact] + public void ValidateOnSaveEnabled_can_be_changed() + { + using (var context = new F1Context()) + { + Assert.True(context.Configuration.ValidateOnSaveEnabled); + context.Configuration.ValidateOnSaveEnabled = false; + Assert.False(context.Configuration.ValidateOnSaveEnabled); + context.Configuration.ValidateOnSaveEnabled = true; + Assert.True(context.Configuration.ValidateOnSaveEnabled); + } + } + + public class ValidationTestContext : DbContext + { + public DbSet Categories { get; set; } + + public Func ValidateEntityFunc { get; set; } + + protected override bool ShouldValidateEntity(DbEntityEntry entityEntry) + { + return true; + } + + protected override DbEntityValidationResult ValidateEntity( + DbEntityEntry entityEntry, + IDictionary items) + { + if (ValidateEntityFunc != null) + { + return ValidateEntityFunc(entityEntry); + } + return new DbEntityValidationResult(entityEntry, Enumerable.Empty()); + } + } + + [Fact] + public void ValidateEntity_is_called_by_SaveChanges_when_ValidateOnSaveEnabled_is_on() + { + TestValidateEntityWithSaveChanges(validateOnSaveEnabled: true); + } + + [Fact] + public void ValidateEntity_is_not_called_by_SaveChanges_when_ValidateOnSaveEnabled_is_off() + { + TestValidateEntityWithSaveChanges(validateOnSaveEnabled: false); + } + + private void TestValidateEntityWithSaveChanges(bool validateOnSaveEnabled) + { + using (var context = new ValidationTestContext()) + { + context.Database.Initialize(force: false); + + using (new TransactionScope()) + { + context.Configuration.ValidateOnSaveEnabled = validateOnSaveEnabled; + var validateCalled = false; + + context.ValidateEntityFunc = (entry) => + { + validateCalled = true; + return new DbEntityValidationResult( + entry, + Enumerable.Empty + ()); + }; + context.Categories.Add(new Category("FOOD")); + context.SaveChanges(); + + Assert.True(validateOnSaveEnabled == validateCalled); + } + } + } + + [Fact] + public void DetectChanges_is_called_by_SaveChanges_once_when_ValidateOnSaveEnabled_is_on() + { + TestDetectChangesWithSaveChangesAndValidation(validateOnSaveEnabled: true); + } + + [Fact] + public void DetectChanges_is_called_by_SaveChanges_once_when_ValidateOnSaveEnabled_is_off() + { + TestDetectChangesWithSaveChangesAndValidation(validateOnSaveEnabled: false); + } + + private void TestDetectChangesWithSaveChangesAndValidation(bool validateOnSaveEnabled) + { + using (var context = new ValidationTestContext()) + { + context.Database.Initialize(force: false); + + using (new TransactionScope()) + { + context.Configuration.ValidateOnSaveEnabled = validateOnSaveEnabled; + + var food = context.Entry(new Category("FOOD")); + context.Categories.Add(food.Entity); + context.SaveChanges(); + + Assert.Equal(null, food.Entity.DetailedDescription); + Assert.Equal(EntityState.Unchanged, food.State); + + food.Entity.DetailedDescription = "foo"; + Assert.Equal(EntityState.Unchanged, food.State); + + context.ValidateEntityFunc = (entry) => + { + Assert.Equal( + validateOnSaveEnabled + ? EntityState.Modified + : EntityState.Unchanged, entry.State); + entry.State = EntityState.Unchanged; + + food.Entity.DetailedDescription = "bar"; + Assert.Equal(EntityState.Unchanged, entry.State); + + return new DbEntityValidationResult( + entry, + Enumerable.Empty + ()); + }; + + context.SaveChanges(); + Assert.Equal(validateOnSaveEnabled ? "bar" : "foo", food.Entity.DetailedDescription); + + food.Reload(); + Assert.Equal(validateOnSaveEnabled ? null : "foo", food.Entity.DetailedDescription); + } + } + } + + #endregion + + #region Replace connection tests + + [Fact] + public void Can_replace_connection() + { + using (var context = new ReplaceConnectionContext()) + { + using (var newConnection = new LazyInternalConnection( + new DbConnectionInfo( + SimpleConnectionString("NewReplaceConnectionContextDatabase"), + "System.Data.SqlClient"))) + { + Can_replace_connection_implementation(context, newConnection); + } + } + } + + [Fact] + public void Can_replace_connection_with_different_provider() + { + using (var context = new ReplaceConnectionContext()) + { + using (var newConnection = new LazyInternalConnection( + new DbConnectionInfo( + "Data Source=NewReplaceConnectionContextDatabase.sdf", + "System.Data.SqlServerCe.4.0"))) + { + Can_replace_connection_implementation(context, newConnection); + } + } + } + + private void Can_replace_connection_implementation( + ReplaceConnectionContext context, + LazyInternalConnection newConnection) + { + Database.Delete(newConnection.Connection); + Database.Delete(typeof(ReplaceConnectionContext).DatabaseName()); + + context.InternalContext.OverrideConnection(newConnection); + + context.Entities.Add( + new PersistEntity + { + Name = "Testing" + }); + context.SaveChanges(); + + Assert.Same(newConnection.Connection, context.Database.Connection); + Assert.True(Database.Exists(newConnection.Connection)); + Assert.False(Database.Exists(typeof(ReplaceConnectionContext).DatabaseName())); + + // By pass EF just to make sure everything targetted the correct database + var cmd = newConnection.Connection.CreateCommand(); + cmd.CommandText = "SELECT Count(*) FROM PersistEntities"; + cmd.Connection.Open(); + Assert.Equal(1, cmd.ExecuteScalar()); + cmd.Connection.Close(); + } + + #endregion + + #region Test EntityConnection-Store Connection state correlation when opening EntityConnection implicitly through context + + [Fact] + public void Implicit_EntityConnection_throws_if_close_underlying_StoreConnection() + { + using (var context = new SimpleModelContext()) + { + EntityConnection entityConnection = (EntityConnection)((IObjectContextAdapter)context).ObjectContext.Connection; + + Assert.True(context.Products.Count() >= 2, "Need at least 2 product entries for test to work below"); + + ConnectionEventsTracker dbConnectionTracker = new ConnectionEventsTracker(entityConnection.StoreConnection); + ConnectionEventsTracker entityConnectionTracker = new ConnectionEventsTracker(entityConnection); + + var query = from p in context.Products + select p.Name; + + query = query.AsStreaming(); + + Assert.Equal(ConnectionState.Closed, entityConnection.State); // entityConnection state + Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); // underlying storeConnection state + + IEnumerator enumerator = query.GetEnumerator(); + enumerator.MoveNext(); + + // close the underlying store connection without explicitly closing entityConnection + // (but entityConnection state is updated automatically) + entityConnection.StoreConnection.Close(); + Assert.Equal(ConnectionState.Closed, entityConnection.State); + Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); + + // verify that the open and close events have been fired once and only once on both EntityConnection and underlying DbConnection + dbConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); + entityConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); + + // check that we throw when we attempt to use the implicitly-opened entityConnection with closed underlying store connection + Assert.Throws(() => enumerator.MoveNext()).ValidateMessage("ADP_DataReaderClosed", "Read"); + + enumerator.Dispose(); + Assert.Equal(ConnectionState.Closed, entityConnection.State); + Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); + + // verify that the open and close events are not fired again by the second MoveNext() above + dbConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); + entityConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); + + // prove that can still re-use the connection even after the above + Assert.True(context.Products.Count() > 0); // this will check that the query will still execute + + // and show that the entity connection and the store connection are once again closed + Assert.Equal(ConnectionState.Closed, entityConnection.State); + Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); + } + } + + [Fact] + public void Implicit_EntityConnection_throws_if_close_EntityConnection_during_query() + { + using (var context = new SimpleModelContext()) + { + EntityConnection entityConnection = (EntityConnection)((IObjectContextAdapter)context).ObjectContext.Connection; + + Assert.True(context.Products.Count() >= 2, "Need at least 2 product entries for test to work below"); + + ConnectionEventsTracker dbConnectionTracker = new ConnectionEventsTracker(entityConnection.StoreConnection); + ConnectionEventsTracker entityConnectionTracker = new ConnectionEventsTracker(entityConnection); + + var query = from p in context.Products + select p.Name; + + query = query.AsStreaming(); + + Assert.Equal(ConnectionState.Closed, entityConnection.State); // entityConnection state + Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); // underlying storeConnection state + + IEnumerator enumerator = query.GetEnumerator(); + enumerator.MoveNext(); + + // close the entity connection explicitly (i.e. not through context) in middle of query + entityConnection.Close(); + Assert.Equal(ConnectionState.Closed, entityConnection.State); + Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); + + // verify that the open and close events have been fired once and only once on both EntityConnection and underlying DbConnection + dbConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); + entityConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); + + // check that we throw when we attempt to use the implicitly-opened entityConnection + Assert.Throws(() => enumerator.MoveNext()).ValidateMessage("ADP_DataReaderClosed", "Read"); + + enumerator.Dispose(); + Assert.Equal(ConnectionState.Closed, entityConnection.State); + Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); + + // verify that the open and close events are not fired again by the second MoveNext() above + dbConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); + entityConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); + + // prove that can still re-use the connection even after the above + Assert.True(context.Products.Count() > 0); // this will check that the query will still execute + + // and show that the entity connection and the store connection are once again closed + Assert.Equal(ConnectionState.Closed, entityConnection.State); + Assert.Equal(ConnectionState.Closed, entityConnection.StoreConnection.State); + } + } + + [Fact] + public void EntityConnection_StateChangeEvents_are_fired_when_state_changes() + { + using (var context = new SimpleModelContext()) + { + EntityConnection entityConnection = (EntityConnection)((IObjectContextAdapter)context).ObjectContext.Connection; + + var dbConnectionTracker = new ConnectionEventsTracker(entityConnection.StoreConnection); + var entityConnectionTracker = new ConnectionEventsTracker(entityConnection); + + // verify that the open and close events have not been fired yet + dbConnectionTracker.VerifyNoConnectionEventsWereFired(); + entityConnectionTracker.VerifyNoConnectionEventsWereFired(); + + var storeConnection = entityConnection.StoreConnection; + storeConnection.Open(); + + // verify the open event has been fired on the store connection and the EntityConnection + // was subscribed so it updated too + dbConnectionTracker.VerifyConnectionOpenedEventWasFired(); + entityConnectionTracker.VerifyConnectionOpenedEventWasFired(); + + storeConnection.Close(); + + // verify the close event has been fired on the store connection and the EntityConnection + // was subscribed so it updated too + dbConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); + entityConnectionTracker.VerifyConnectionOpenCloseEventsWereFired(); + } + } + #endregion + } + + #region Fake contexts + + public class ReplaceConnectionContext : DbContext + { + public DbSet Entities { get; set; } + } + + public class PersistEntity + { + public int Id { get; set; } + public string Name { get; set; } + } + + #endregion +} diff --git a/test/EntityFramework/FunctionalTests/ProductivityApi/DbFunctionScenarios.cs b/test/EntityFramework/FunctionalTests.Transitional/ProductivityApi/DbFunctionScenarios.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/ProductivityApi/DbFunctionScenarios.cs rename to test/EntityFramework/FunctionalTests.Transitional/ProductivityApi/DbFunctionScenarios.cs index f94a5ada..58c524f2 100644 --- a/test/EntityFramework/FunctionalTests/ProductivityApi/DbFunctionScenarios.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/ProductivityApi/DbFunctionScenarios.cs @@ -1,1561 +1,1561 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.ProductivityApi -{ - using System; - using System.Collections.Generic; - using System.Data.Entity; - using System.Data.Entity.Core.Objects; - using System.Data.Entity.Infrastructure; - using System.Data.Entity.Utilities; - using System.Linq; - using Xunit; - - public class DbFunctionScenarios : FunctionalTestBase - { - public class StandardDeviation : FunctionalTestBase - { - [Fact] - public void StandardDeviation_for_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.Decimal)), 2); - Assert.Equal( - 0.71, (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.Decimal)), 2); - } - } - - [Fact] - public void StandardDeviation_for_nullable_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.NullableDecimal)), 2); - Assert.Equal( - 0.71, - (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.NullableDecimal)), 2); - } - } - - [Fact] - public void StandardDeviation_for_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.Double)), 2); - Assert.Equal( - 0.71, (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.Double)), 2); - } - } - - [Fact] - public void StandardDeviation_for_nullable_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.NullableDouble)), 2); - Assert.Equal( - 0.71, - (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.NullableDouble)), 2); - } - } - - [Fact] - public void StandardDeviation_for_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.Int)), 2); - Assert.Equal( - 0.71, (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.Int)), 2); - } - } - - [Fact] - public void StandardDeviation_for_nullable_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.NullableInt)), 2); - Assert.Equal( - 0.71, (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.NullableInt)), - 2); - } - } - - [Fact] - public void StandardDeviation_for_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.Long)), 2); - Assert.Equal( - 0.71, (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.Long)), 2); - } - } - - [Fact] - public void StandardDeviation_for_nullable_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.NullableLong)), 2); - Assert.Equal( - 0.71, (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.NullableLong)), - 2); - } - } - - [Fact] - public void StandardDeviation_can_be_used_on_nested_collection_with_ObjectQuery_or_DbQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 0.71, (double)context.WithRelationships.Select( - e => new - { - Result = DbFunctions.StandardDeviation(e.Types.Select(t => t.Decimal)) - }).First().Result, 2); - - Assert.Equal( - 0.71, (double)GetObjectSet(context).Select( - e => new - { - Result = DbFunctions.StandardDeviation(e.Types.Select(t => t.Decimal)) - }).First().Result, 2); - } - } - } - - public class StandardDeviationP : FunctionalTestBase - { - [Fact] - public void StandardDeviationP_for_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.Decimal)), 2); - Assert.Equal( - 0.5, (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.Decimal)), 2); - } - } - - [Fact] - public void StandardDeviationP_for_nullable_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.NullableDecimal)), 2); - Assert.Equal( - 0.5, - (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.NullableDecimal)), 2); - } - } - - [Fact] - public void StandardDeviationP_for_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.Double)), 2); - Assert.Equal( - 0.5, (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.Double)), 2); - } - } - - [Fact] - public void StandardDeviationP_for_nullable_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.NullableDouble)), 2); - Assert.Equal( - 0.5, - (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.NullableDouble)), 2); - } - } - - [Fact] - public void StandardDeviationP_for_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.Int)), 2); - Assert.Equal( - 0.5, (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.Int)), 2); - } - } - - [Fact] - public void StandardDeviationP_for_nullable_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.NullableInt)), 2); - Assert.Equal( - 0.5, (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.NullableInt)), - 2); - } - } - - [Fact] - public void StandardDeviationP_for_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.Long)), 2); - Assert.Equal( - 0.5, (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.Long)), 2); - } - } - - [Fact] - public void StandardDeviationP_for_nullable_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.NullableLong)), 2); - Assert.Equal( - 0.5, (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.NullableLong)), - 2); - } - } - - [Fact] - public void StandardDeviationP_can_be_used_on_nested_collection_with_ObjectQuery_or_DbQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 0.5, (double)context.WithRelationships.Select( - e => new - { - Result = DbFunctions.StandardDeviationP(e.Types.Select(t => t.Decimal)) - }).First().Result, 2); - - Assert.Equal( - 0.5, (double)GetObjectSet(context).Select( - e => new - { - Result = DbFunctions.StandardDeviationP(e.Types.Select(t => t.Decimal)) - }).First().Result, 2); - } - } - } - - public class Var : FunctionalTestBase - { - [Fact] - public void Var_for_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.Decimal)), 2); - Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.Decimal)), 2); - } - } - - [Fact] - public void Var_for_nullable_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.NullableDecimal)), 2); - Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.NullableDecimal)), 2); - } - } - - [Fact] - public void Var_for_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.Double)), 2); - Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.Double)), 2); - } - } - - [Fact] - public void Var_for_nullable_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.NullableDouble)), 2); - Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.NullableDouble)), 2); - } - } - - [Fact] - public void Var_for_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.Int)), 2); - Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.Int)), 2); - } - } - - [Fact] - public void Var_for_nullable_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.NullableInt)), 2); - Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.NullableInt)), 2); - } - } - - [Fact] - public void Var_for_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.Long)), 2); - Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.Long)), 2); - } - } - - [Fact] - public void Var_for_nullable_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.NullableLong)), 2); - Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.NullableLong)), 2); - } - } - - [Fact] - public void Var_can_be_used_on_nested_collection_with_ObjectQuery_or_DbQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 0.5, (double)context.WithRelationships.Select( - e => new - { - Result = DbFunctions.Var(e.Types.Select(t => t.Decimal)) - }).First().Result, 2); - - Assert.Equal( - 0.5, (double)GetObjectSet(context).Select( - e => new - { - Result = DbFunctions.Var(e.Types.Select(t => t.Decimal)) - }).First().Result, 2); - } - } - } - - public class VarP : FunctionalTestBase - { - [Fact] - public void VarP_for_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.Decimal)), 2); - Assert.Equal(0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.Decimal)), 2); - } - } - - [Fact] - public void VarP_for_nullable_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.NullableDecimal)), 2); - Assert.Equal( - 0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.NullableDecimal)), 2); - } - } - - [Fact] - public void VarP_for_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.Double)), 2); - Assert.Equal(0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.Double)), 2); - } - } - - [Fact] - public void VarP_for_nullable_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.NullableDouble)), 2); - Assert.Equal( - 0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.NullableDouble)), 2); - } - } - - [Fact] - public void VarP_for_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.Int)), 2); - Assert.Equal(0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.Int)), 2); - } - } - - [Fact] - public void VarP_for_nullable_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.NullableInt)), 2); - Assert.Equal(0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.NullableInt)), 2); - } - } - - [Fact] - public void VarP_for_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.Long)), 2); - Assert.Equal(0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.Long)), 2); - } - } - - [Fact] - public void VarP_for_nullable_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.NullableLong)), 2); - Assert.Equal(0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.NullableLong)), 2); - } - } - - [Fact] - public void VarP_can_be_used_on_nested_collection_with_ObjectQuery_or_DbQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 0.25, (double)context.WithRelationships.Select( - e => new - { - Result = DbFunctions.VarP(e.Types.Select(t => t.Decimal)) - }).First().Result, 2); - - Assert.Equal( - 0.25, (double)GetObjectSet(context).Select( - e => new - { - Result = DbFunctions.VarP(e.Types.Select(t => t.Decimal)) - }).First().Result, 2); - } - } - } - - public class StringFunctions : FunctionalTestBase - { - [Fact] - public void Left_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - "Magic Unic", - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.Left(e.String, 10)).First()); - - Assert.Equal( - "Magic Unic", - GetObjectSet(context).OrderBy(e => e.Id).Select(e => DbFunctions.Left(e.String, 10)).First()); - } - } - - [Fact] - public void Right_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - "corns Rock", - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.Right(e.String, 10)).First()); - - Assert.Equal( - "corns Rock", - GetObjectSet(context).OrderBy(e => e.Id).Select(e => DbFunctions.Right(e.String, 10)).First()); - } - } - - [Fact] - public void Reverse_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - "kcoR snrocinU cigaM", - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.Reverse(e.String)).First()); - - Assert.Equal( - "kcoR snrocinU cigaM", - GetObjectSet(context).OrderBy(e => e.Id).Select(e => DbFunctions.Reverse(e.String)).First()); - } - } - - [Fact] - public void AsUnicode_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - "Magic Unicorns Rock And Roll All Night Long ツ", - context.WithTypes.OrderBy(e => e.Id).Select( - e => e.String + DbFunctions.AsUnicode(" And Roll All Night Long ツ")).First()); - - Assert.Equal( - "Magic Unicorns Rock And Roll All Night Long ツ", - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => e.String + DbFunctions.AsUnicode(" And Roll All Night Long ツ")).First()); - } - } - - [Fact] - public void AsNonUnicode_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - "Magic Unicorns Rock And Roll All Night Long ?", - context.WithTypes.OrderBy(e => e.Id).Select( - e => e.String + DbFunctions.AsNonUnicode(" And Roll All Night Long ツ")).First()); - - Assert.Equal( - "Magic Unicorns Rock And Roll All Night Long ?", - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => e.String + DbFunctions.AsNonUnicode(" And Roll All Night Long ツ")).First()); - } - } - } - - public class DateTimeFunctions : FunctionalTestBase - { - private const long EF41Ticks = 634380912600000000; - private static readonly DateTime _ef43DateTime = new DateTime(2012, 2, 29, 4, 3, 1, 0, DateTimeKind.Utc); - private static readonly DateTimeOffset _ef43Offset = new DateTimeOffset(2012, 2, 29, 4, 3, 1, 0, new TimeSpan(8, 0, 0)); - - [Fact] - public void GetTotalOffsetMinutes_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 8 * 60, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.GetTotalOffsetMinutes(e.DateTimeOffset)).First()); - - Assert.Equal( - 8 * 60, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.GetTotalOffsetMinutes(e.DateTimeOffset)).First()); - } - } - - [Fact] - public void TruncateTime_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTimeOffset(2011, 4, 11, 0, 0, 0, 0, new TimeSpan(8, 0, 0)), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.TruncateTime(e.DateTimeOffset)).First()); - - Assert.Equal( - new DateTimeOffset(2011, 4, 11, 0, 0, 0, 0, new TimeSpan(8, 0, 0)), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.TruncateTime(e.DateTimeOffset)).First()); - } - } - - [Fact] - public void TruncateTime_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTime(2011, 4, 11, 0, 0, 0, 0, DateTimeKind.Utc), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.TruncateTime(e.DateTime)).First()); - - Assert.Equal( - new DateTime(2011, 4, 11, 0, 0, 0, 0, DateTimeKind.Utc), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.TruncateTime(e.DateTime)).First()); - } - } - - [Fact] - public void CreateDateTime_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTime(2011, 4, 11, 0, 0, 1, 0, DateTimeKind.Utc), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.CreateDateTime(2011, 4, 11, 0, 0, e.Int)).First()); - - Assert.Equal( - new DateTime(2011, 4, 11, 0, 0, 1, 0, DateTimeKind.Utc), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.CreateDateTime(2011, 4, 11, 0, 0, e.Int)).First()); - } - } - - [Fact] - public void CreateDateTimeOffset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTimeOffset(2011, 4, 11, 0, 0, 1, 0, new TimeSpan(0, 1, 0)), - context.WithTypes.OrderBy(e => e.Id).Select( - e => DbFunctions.CreateDateTimeOffset(2011, 4, 11, 0, 0, e.Int, e.Int)).First()); - - Assert.Equal( - new DateTimeOffset(2011, 4, 11, 0, 0, 1, 0, new TimeSpan(0, 1, 0)), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.CreateDateTimeOffset(2011, 4, 11, 0, 0, e.Int, e.Int)).First()); - } - } - - [Fact] - public void CreateTime_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new TimeSpan(1, 2, 3), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.CreateTime(e.Int, 2, 3)).First()); - - Assert.Equal( - new TimeSpan(1, 2, 3), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.CreateTime(e.Int, 2, 3)).First()); - } - } - - [Fact] - public void AddYears_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTimeOffset(2012, 4, 11, 4, 1, 0, 0, new TimeSpan(8, 0, 0)), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddYears(e.DateTimeOffset, e.Int)).First()); - - Assert.Equal( - new DateTimeOffset(2012, 4, 11, 4, 1, 0, 0, new TimeSpan(8, 0, 0)), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddYears(e.DateTimeOffset, e.Int)).First()); - } - } - - [Fact] - public void AddYears_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTime(2012, 4, 11, 4, 1, 0, 0, DateTimeKind.Utc), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddYears(e.DateTime, e.Int)).First()); - - Assert.Equal( - new DateTime(2012, 4, 11, 4, 1, 0, 0, DateTimeKind.Utc), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddYears(e.DateTime, e.Int)).First()); - } - } - - [Fact] - public void AddMonths_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTimeOffset(2011, 5, 11, 4, 1, 0, 0, new TimeSpan(8, 0, 0)), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMonths(e.DateTimeOffset, e.Int)).First()); - - Assert.Equal( - new DateTimeOffset(2011, 5, 11, 4, 1, 0, 0, new TimeSpan(8, 0, 0)), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddMonths(e.DateTimeOffset, e.Int)).First()); - } - } - - [Fact] - public void AddMonths_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTime(2011, 5, 11, 4, 1, 0, 0, DateTimeKind.Utc), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMonths(e.DateTime, e.Int)).First()); - - Assert.Equal( - new DateTime(2011, 5, 11, 4, 1, 0, 0, DateTimeKind.Utc), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddMonths(e.DateTime, e.Int)).First()); - } - } - - [Fact] - public void AddDays_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTimeOffset(2011, 4, 12, 4, 1, 0, 0, new TimeSpan(8, 0, 0)), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddDays(e.DateTimeOffset, e.Int)).First()); - - Assert.Equal( - new DateTimeOffset(2011, 4, 12, 4, 1, 0, 0, new TimeSpan(8, 0, 0)), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddDays(e.DateTimeOffset, e.Int)).First()); - } - } - - [Fact] - public void AddDays_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTime(2011, 4, 12, 4, 1, 0, 0, DateTimeKind.Utc), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddDays(e.DateTime, e.Int)).First()); - - Assert.Equal( - new DateTime(2011, 4, 12, 4, 1, 0, 0, DateTimeKind.Utc), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddDays(e.DateTime, e.Int)).First()); - } - } - - [Fact] - public void AddHours_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTimeOffset(2011, 4, 11, 5, 1, 0, 0, new TimeSpan(8, 0, 0)), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddHours(e.DateTimeOffset, e.Int)).First()); - - Assert.Equal( - new DateTimeOffset(2011, 4, 11, 5, 1, 0, 0, new TimeSpan(8, 0, 0)), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddHours(e.DateTimeOffset, e.Int)).First()); - } - } - - [Fact] - public void AddHours_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTime(2011, 4, 11, 5, 1, 0, 0, DateTimeKind.Utc), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddHours(e.DateTime, e.Int)).First()); - - Assert.Equal( - new DateTime(2011, 4, 11, 5, 1, 0, 0, DateTimeKind.Utc), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddHours(e.DateTime, e.Int)).First()); - } - } - - [Fact] - public void AddHours_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new TimeSpan(5, 1, 0), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddHours(e.TimeSpan, e.Int)).First()); - - Assert.Equal( - new TimeSpan(5, 1, 0), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddHours(e.TimeSpan, e.Int)).First()); - } - } - - [Fact] - public void AddMinutes_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTimeOffset(2011, 4, 11, 4, 2, 0, 0, new TimeSpan(8, 0, 0)), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMinutes(e.DateTimeOffset, e.Int)).First()); - - Assert.Equal( - new DateTimeOffset(2011, 4, 11, 4, 2, 0, 0, new TimeSpan(8, 0, 0)), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddMinutes(e.DateTimeOffset, e.Int)).First()); - } - } - - [Fact] - public void AddMinutes_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTime(2011, 4, 11, 4, 2, 0, 0, DateTimeKind.Utc), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMinutes(e.DateTime, e.Int)).First()); - - Assert.Equal( - new DateTime(2011, 4, 11, 4, 2, 0, 0, DateTimeKind.Utc), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddMinutes(e.DateTime, e.Int)).First()); - } - } - - [Fact] - public void AddMinutes_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new TimeSpan(4, 2, 0), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMinutes(e.TimeSpan, e.Int)).First()); - - Assert.Equal( - new TimeSpan(4, 2, 0), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddMinutes(e.TimeSpan, e.Int)).First()); - } - } - - [Fact] - public void AddSeconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTimeOffset(2011, 4, 11, 4, 1, 1, 0, new TimeSpan(8, 0, 0)), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddSeconds(e.DateTimeOffset, e.Int)).First()); - - Assert.Equal( - new DateTimeOffset(2011, 4, 11, 4, 1, 1, 0, new TimeSpan(8, 0, 0)), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddSeconds(e.DateTimeOffset, e.Int)).First()); - } - } - - [Fact] - public void AddSeconds_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTime(2011, 4, 11, 4, 1, 1, 0, DateTimeKind.Utc), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddSeconds(e.DateTime, e.Int)).First()); - - Assert.Equal( - new DateTime(2011, 4, 11, 4, 1, 1, 0, DateTimeKind.Utc), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddSeconds(e.DateTime, e.Int)).First()); - } - } - - [Fact] - public void AddSeconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new TimeSpan(4, 1, 1), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddSeconds(e.TimeSpan, e.Int)).First()); - - Assert.Equal( - new TimeSpan(4, 1, 1), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddSeconds(e.TimeSpan, e.Int)).First()); - } - } - - [Fact] - public void AddMilliseconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTimeOffset(2011, 4, 11, 4, 1, 0, 1, new TimeSpan(8, 0, 0)), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMilliseconds(e.DateTimeOffset, e.Int)).First()); - - Assert.Equal( - new DateTimeOffset(2011, 4, 11, 4, 1, 0, 1, new TimeSpan(8, 0, 0)), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddMilliseconds(e.DateTimeOffset, e.Int)).First()); - } - } - - [Fact] - public void AddMilliseconds_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new DateTime(2011, 4, 11, 4, 1, 0, 1, DateTimeKind.Utc), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMilliseconds(e.DateTime, e.Int)).First()); - - Assert.Equal( - new DateTime(2011, 4, 11, 4, 1, 0, 1, DateTimeKind.Utc), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddMilliseconds(e.DateTime, e.Int)).First()); - } - } - - [Fact] - public void AddMilliseconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new TimeSpan(0, 4, 1, 0, 1), - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMilliseconds(e.TimeSpan, e.Int)).First()); - - Assert.Equal( - new TimeSpan(0, 4, 1, 0, 1), - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddMilliseconds(e.TimeSpan, e.Int)).First()); - } - } - - [Fact] - public void AddMicroseconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - EF41Ticks + 10, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMicroseconds(e.DateTimeOffset, e.Int)).First(). - Value.Ticks); - - Assert.Equal( - EF41Ticks + 10, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddMicroseconds(e.DateTimeOffset, e.Int)).First().Value.Ticks); - } - } - - [Fact] - public void AddMicroseconds_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - EF41Ticks + 10, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMicroseconds(e.DateTime, e.Int)).First().Value. - Ticks); - - Assert.Equal( - EF41Ticks + 10, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddMicroseconds(e.DateTime, e.Int)).First().Value.Ticks); - } - } - - [Fact] - public void AddMicroseconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new TimeSpan(4, 1, 0).Ticks + 10, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMicroseconds(e.TimeSpan, e.Int)).First().Value.Ticks); - - Assert.Equal( - new TimeSpan(4, 1, 0).Ticks + 10, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddMicroseconds(e.TimeSpan, e.Int)).First().Value.Ticks); - } - } - - [Fact] - public void AddNanoseconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - EF41Ticks + 1, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddNanoseconds(e.DateTimeOffset, e.Int * 100)). - First(). - Value.Ticks); - - Assert.Equal( - EF41Ticks + 1, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddNanoseconds(e.DateTimeOffset, e.Int * 100)).First().Value.Ticks); - } - } - - [Fact] - public void AddNanoseconds_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - EF41Ticks + 1, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddNanoseconds(e.DateTime, e.Int * 100)).First(). - Value. - Ticks); - - Assert.Equal( - EF41Ticks + 1, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddNanoseconds(e.DateTime, e.Int * 100)).First().Value.Ticks); - } - } - - [Fact] - public void AddNanoseconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - new TimeSpan(4, 1, 0).Ticks + 1, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddNanoseconds(e.TimeSpan, e.Int * 100)).First().Value. - Ticks); - - Assert.Equal( - new TimeSpan(4, 1, 0).Ticks + 1, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.AddNanoseconds(e.TimeSpan, e.Int * 100)).First().Value.Ticks); - } - } - - [Fact] - public void DiffYears_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 1, context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffYears(e.DateTimeOffset, _ef43Offset)).First()); - - Assert.Equal( - 1, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffYears(e.DateTimeOffset, _ef43Offset)).First()); - } - } - - [Fact] - public void DiffYears_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 1, context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffYears(e.DateTime, _ef43DateTime)).First()); - - Assert.Equal( - 1, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffYears(e.DateTime, _ef43DateTime)).First()); - } - } - - [Fact] - public void DiffMonths_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 10, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffMonths(e.DateTimeOffset, _ef43Offset)).First()); - - Assert.Equal( - 10, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffMonths(e.DateTimeOffset, _ef43Offset)).First()); - } - } - - [Fact] - public void DiffMonths_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 10, context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffMonths(e.DateTime, _ef43DateTime)).First()); - - Assert.Equal( - 10, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffMonths(e.DateTime, _ef43DateTime)).First()); - } - } - - [Fact] - public void DiffDays_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 324, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffDays(e.DateTimeOffset, _ef43Offset)).First()); - - Assert.Equal( - 324, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffDays(e.DateTimeOffset, _ef43Offset)).First()); - } - } - - [Fact] - public void DiffDays_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 324, context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffDays(e.DateTime, _ef43DateTime)).First()); - - Assert.Equal( - 324, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffDays(e.DateTime, _ef43DateTime)).First()); - } - } - - [Fact] - public void DiffHours_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 7776, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffHours(e.DateTimeOffset, _ef43Offset)).First()); - - Assert.Equal( - 7776, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffHours(e.DateTimeOffset, _ef43Offset)).First()); - } - } - - [Fact] - public void DiffHours_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 7776, context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffHours(e.DateTime, _ef43DateTime)).First()); - - Assert.Equal( - 7776, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffHours(e.DateTime, _ef43DateTime)).First()); - } - } - - [Fact] - public void DiffHours_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 1, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffHours(e.TimeSpan, new TimeSpan(5, 1, 0))).First()); - - Assert.Equal( - 1, GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffHours(e.TimeSpan, new TimeSpan(5, 1, 0))).First()); - } - } - - [Fact] - public void DiffMinutes_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 466562, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffMinutes(e.DateTimeOffset, _ef43Offset)).First()); - - Assert.Equal( - 466562, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffMinutes(e.DateTimeOffset, _ef43Offset)).First()); - } - } - - [Fact] - public void DiffMinutes_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 466562, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffMinutes(e.DateTime, _ef43DateTime)).First()); - - Assert.Equal( - 466562, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffMinutes(e.DateTime, _ef43DateTime)).First()); - } - } - - [Fact] - public void DiffMinutes_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 1, - context.WithTypes.OrderBy(e => e.Id).Select( - e => DbFunctions.DiffMinutes(e.TimeSpan, new TimeSpan(4, 2, 0))).First()); - - Assert.Equal( - 1, GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffMinutes(e.TimeSpan, new TimeSpan(4, 2, 0))).First()); - } - } - - [Fact] - public void DiffSeconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 27993721, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffSeconds(e.DateTimeOffset, _ef43Offset)).First()); - - Assert.Equal( - 27993721, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffSeconds(e.DateTimeOffset, _ef43Offset)).First()); - } - } - - [Fact] - public void DiffSeconds_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 27993721, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffSeconds(e.DateTime, _ef43DateTime)).First()); - - Assert.Equal( - 27993721, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffSeconds(e.DateTime, _ef43DateTime)).First()); - } - } - - [Fact] - public void DiffSeconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 1, - context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffSeconds(e.TimeSpan, new TimeSpan(4, 1, 1))).First()); - - Assert.Equal( - 1, GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffSeconds(e.TimeSpan, new TimeSpan(4, 1, 1))).First()); - } - } - - [Fact] - public void DiffMilliseconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 100, - context.WithTypes.OrderBy(e => e.Id).Select( - e => - DbFunctions.DiffMilliseconds( - e.DateTimeOffset, new DateTimeOffset(EF41Ticks + 1000000, new TimeSpan(8, 0, 0)))).First()); - - Assert.Equal( - 100, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => - DbFunctions.DiffMilliseconds( - e.DateTimeOffset, new DateTimeOffset(EF41Ticks + 1000000, new TimeSpan(8, 0, 0)))).First()); - } - } - - [Fact] - public void DiffMilliseconds_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 100, - context.WithTypes.OrderBy(e => e.Id).Select( - e => DbFunctions.DiffMilliseconds(e.DateTime, new DateTime(EF41Ticks + 1000000, DateTimeKind.Utc))).First()); - - Assert.Equal( - 100, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffMilliseconds(e.DateTime, new DateTime(EF41Ticks + 1000000, DateTimeKind.Utc))).First()); - } - } - - [Fact] - public void DiffMilliseconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 1, - context.WithTypes.OrderBy(e => e.Id).Select( - e => DbFunctions.DiffMilliseconds(e.TimeSpan, new TimeSpan(0, 4, 1, 0, 1))).First()); - - Assert.Equal( - 1, GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffMilliseconds(e.TimeSpan, new TimeSpan(0, 4, 1, 0, 1))).First()); - } - } - - [Fact] - public void DiffMicroseconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 100000, - context.WithTypes.OrderBy(e => e.Id).Select( - e => - DbFunctions.DiffMicroseconds( - e.DateTimeOffset, new DateTimeOffset(EF41Ticks + 1000000, new TimeSpan(8, 0, 0)))).First()); - - Assert.Equal( - 100000, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => - DbFunctions.DiffMicroseconds( - e.DateTimeOffset, new DateTimeOffset(EF41Ticks + 1000000, new TimeSpan(8, 0, 0)))).First()); - } - } - - [Fact] - public void DiffMicroseconds_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 100000, - context.WithTypes.OrderBy(e => e.Id).Select( - e => DbFunctions.DiffMicroseconds(e.DateTime, new DateTime(EF41Ticks + 1000000, DateTimeKind.Utc))).First()); - - Assert.Equal( - 100000, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffMicroseconds(e.DateTime, new DateTime(EF41Ticks + 1000000, DateTimeKind.Utc))).First()); - } - } - - [Fact] - public void DiffMicroseconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - var ticks = new TimeSpan(4, 1, 0).Ticks + 10; - Assert.Equal( - 1, context.WithTypes.OrderBy(e => e.Id).Select( - e => DbFunctions.DiffMicroseconds(e.TimeSpan, new TimeSpan(ticks))).First()); - - Assert.Equal( - 1, GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffMicroseconds(e.TimeSpan, new TimeSpan(ticks))).First()); - } - } - - [Fact] - public void DiffNanoseconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 100000000, - context.WithTypes.OrderBy(e => e.Id).Select( - e => - DbFunctions.DiffNanoseconds( - e.DateTimeOffset, new DateTimeOffset(EF41Ticks + 1000000, new TimeSpan(8, 0, 0)))).First()); - - Assert.Equal( - 100000000, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => - DbFunctions.DiffNanoseconds( - e.DateTimeOffset, new DateTimeOffset(EF41Ticks + 1000000, new TimeSpan(8, 0, 0)))).First()); - } - } - - [Fact] - public void DiffNanoseconds_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 100000000, - context.WithTypes.OrderBy(e => e.Id).Select( - e => DbFunctions.DiffNanoseconds(e.DateTime, new DateTime(EF41Ticks + 1000000, DateTimeKind.Utc))).First()); - - Assert.Equal( - 100000000, - GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffNanoseconds(e.DateTime, new DateTime(EF41Ticks + 1000000, DateTimeKind.Utc))).First()); - } - } - - [Fact] - public void DiffNanoseconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - var ticks = new TimeSpan(4, 1, 0).Ticks + 1; - Assert.Equal( - 100, context.WithTypes.OrderBy(e => e.Id).Select( - e => DbFunctions.DiffNanoseconds(e.TimeSpan, new TimeSpan(ticks))).First()); - - Assert.Equal( - 100, GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.DiffNanoseconds(e.TimeSpan, new TimeSpan(ticks))).First()); - } - } - } - - public class Truncate : FunctionalTestBase - { - [Fact] - public void Truncate_on_double_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 1.0, (double)context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.Truncate(e.Double, e.Int)).First(), 7); - - Assert.Equal( - 1.0, (double)GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.Truncate(e.Double, e.Int)).First(), 7); - } - } - - [Fact] - public void Truncate_on_decimal_can_be_used_in_DbQuery_or_ObjectQuery() - { - using (var context = new EntityFunctionContext()) - { - Assert.Equal( - 1, (decimal)context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.Truncate(e.Decimal, e.Int)).First(), 7); - - Assert.Equal( - 1, (decimal)GetObjectSet(context).OrderBy(e => e.Id).Select( - e => DbFunctions.Truncate(e.Decimal, e.Int)).First(), 7); - } - } - } - - public static ObjectSet GetObjectSet(DbContext context) where TEntity : class - { - return ((IObjectContextAdapter)context).ObjectContext.CreateObjectSet(); - } - } - - public class EntityFunctionContext : DbContext - { - static EntityFunctionContext() - { - Database.SetInitializer(new EntityFunctionInitializer()); - } - - public DbSet WithTypes { get; set; } - public DbSet WithRelationships { get; set; } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - modelBuilder - .Entity() - .Property(e => e.DateTime) - .HasColumnType("datetime2"); - } - } - - public class EntityWithTypes - { - public int Id { get; set; } - - public decimal Decimal { get; set; } - public decimal? NullableDecimal { get; set; } - - public double Double { get; set; } - public double? NullableDouble { get; set; } - - public int Int { get; set; } - public int? NullableInt { get; set; } - - public long Long { get; set; } - public long? NullableLong { get; set; } - - public DateTime? DateTime { get; set; } - public DateTimeOffset? DateTimeOffset { get; set; } - public TimeSpan? TimeSpan { get; set; } - - public string String { get; set; } - - public int RelationshipId { get; set; } - public EntityWithRelationship Relationship { get; set; } - } - - public class EntityWithRelationship - { - public int Id { get; set; } - - public ICollection Types { get; set; } - } - - public class EntityFunctionInitializer : DropCreateDatabaseAlways - { - protected override void Seed(EntityFunctionContext context) - { - var entityWithRelationship = new EntityWithRelationship(); - new[] - { - new EntityWithTypes - { - Decimal = 1.0001m, - NullableDecimal = 1m, - Double = 1.0001, - NullableDouble = 1.0, - Int = 1, - NullableInt = 1, - Long = 1, - NullableLong = 1, - String = "Magic Unicorns Rock", - DateTime = new DateTime(2011, 4, 11, 4, 1, 0, 0, DateTimeKind.Utc), - DateTimeOffset = new DateTimeOffset(2011, 4, 11, 4, 1, 0, 0, new TimeSpan(8, 0, 0)), - TimeSpan = new TimeSpan(4, 1, 0), - Relationship = entityWithRelationship - }, - new EntityWithTypes - { - Decimal = 2m, - NullableDecimal = 2m, - Double = 2.0, - NullableDouble = 2.0, - Int = 2, - NullableInt = 2, - Long = 2, - NullableLong = 2, - String = "Magic Unicorns Roll", - DateTime = new DateTime(2012, 2, 29, 4, 3, 1, 0, DateTimeKind.Utc), - DateTimeOffset = new DateTimeOffset(2012, 2, 29, 4, 3, 1, 0, new TimeSpan(8, 0, 0)), - TimeSpan = new TimeSpan(4, 3, 1), - Relationship = entityWithRelationship - } - }.Each(e => context.WithTypes.Add(e)); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.ProductivityApi +{ + using System; + using System.Collections.Generic; + using System.Data.Entity; + using System.Data.Entity.Core.Objects; + using System.Data.Entity.Infrastructure; + using System.Data.Entity.Utilities; + using System.Linq; + using Xunit; + + public class DbFunctionScenarios : FunctionalTestBase + { + public class StandardDeviation : FunctionalTestBase + { + [Fact] + public void StandardDeviation_for_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.Decimal)), 2); + Assert.Equal( + 0.71, (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.Decimal)), 2); + } + } + + [Fact] + public void StandardDeviation_for_nullable_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.NullableDecimal)), 2); + Assert.Equal( + 0.71, + (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.NullableDecimal)), 2); + } + } + + [Fact] + public void StandardDeviation_for_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.Double)), 2); + Assert.Equal( + 0.71, (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.Double)), 2); + } + } + + [Fact] + public void StandardDeviation_for_nullable_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.NullableDouble)), 2); + Assert.Equal( + 0.71, + (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.NullableDouble)), 2); + } + } + + [Fact] + public void StandardDeviation_for_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.Int)), 2); + Assert.Equal( + 0.71, (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.Int)), 2); + } + } + + [Fact] + public void StandardDeviation_for_nullable_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.NullableInt)), 2); + Assert.Equal( + 0.71, (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.NullableInt)), + 2); + } + } + + [Fact] + public void StandardDeviation_for_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.Long)), 2); + Assert.Equal( + 0.71, (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.Long)), 2); + } + } + + [Fact] + public void StandardDeviation_for_nullable_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.71, (double)DbFunctions.StandardDeviation(context.WithTypes.Select(e => e.NullableLong)), 2); + Assert.Equal( + 0.71, (double)DbFunctions.StandardDeviation(GetObjectSet(context).Select(e => e.NullableLong)), + 2); + } + } + + [Fact] + public void StandardDeviation_can_be_used_on_nested_collection_with_ObjectQuery_or_DbQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 0.71, (double)context.WithRelationships.Select( + e => new + { + Result = DbFunctions.StandardDeviation(e.Types.Select(t => t.Decimal)) + }).First().Result, 2); + + Assert.Equal( + 0.71, (double)GetObjectSet(context).Select( + e => new + { + Result = DbFunctions.StandardDeviation(e.Types.Select(t => t.Decimal)) + }).First().Result, 2); + } + } + } + + public class StandardDeviationP : FunctionalTestBase + { + [Fact] + public void StandardDeviationP_for_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.Decimal)), 2); + Assert.Equal( + 0.5, (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.Decimal)), 2); + } + } + + [Fact] + public void StandardDeviationP_for_nullable_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.NullableDecimal)), 2); + Assert.Equal( + 0.5, + (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.NullableDecimal)), 2); + } + } + + [Fact] + public void StandardDeviationP_for_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.Double)), 2); + Assert.Equal( + 0.5, (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.Double)), 2); + } + } + + [Fact] + public void StandardDeviationP_for_nullable_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.NullableDouble)), 2); + Assert.Equal( + 0.5, + (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.NullableDouble)), 2); + } + } + + [Fact] + public void StandardDeviationP_for_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.Int)), 2); + Assert.Equal( + 0.5, (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.Int)), 2); + } + } + + [Fact] + public void StandardDeviationP_for_nullable_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.NullableInt)), 2); + Assert.Equal( + 0.5, (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.NullableInt)), + 2); + } + } + + [Fact] + public void StandardDeviationP_for_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.Long)), 2); + Assert.Equal( + 0.5, (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.Long)), 2); + } + } + + [Fact] + public void StandardDeviationP_for_nullable_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.StandardDeviationP(context.WithTypes.Select(e => e.NullableLong)), 2); + Assert.Equal( + 0.5, (double)DbFunctions.StandardDeviationP(GetObjectSet(context).Select(e => e.NullableLong)), + 2); + } + } + + [Fact] + public void StandardDeviationP_can_be_used_on_nested_collection_with_ObjectQuery_or_DbQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 0.5, (double)context.WithRelationships.Select( + e => new + { + Result = DbFunctions.StandardDeviationP(e.Types.Select(t => t.Decimal)) + }).First().Result, 2); + + Assert.Equal( + 0.5, (double)GetObjectSet(context).Select( + e => new + { + Result = DbFunctions.StandardDeviationP(e.Types.Select(t => t.Decimal)) + }).First().Result, 2); + } + } + } + + public class Var : FunctionalTestBase + { + [Fact] + public void Var_for_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.Decimal)), 2); + Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.Decimal)), 2); + } + } + + [Fact] + public void Var_for_nullable_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.NullableDecimal)), 2); + Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.NullableDecimal)), 2); + } + } + + [Fact] + public void Var_for_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.Double)), 2); + Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.Double)), 2); + } + } + + [Fact] + public void Var_for_nullable_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.NullableDouble)), 2); + Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.NullableDouble)), 2); + } + } + + [Fact] + public void Var_for_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.Int)), 2); + Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.Int)), 2); + } + } + + [Fact] + public void Var_for_nullable_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.NullableInt)), 2); + Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.NullableInt)), 2); + } + } + + [Fact] + public void Var_for_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.Long)), 2); + Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.Long)), 2); + } + } + + [Fact] + public void Var_for_nullable_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.5, (double)DbFunctions.Var(context.WithTypes.Select(e => e.NullableLong)), 2); + Assert.Equal(0.5, (double)DbFunctions.Var(GetObjectSet(context).Select(e => e.NullableLong)), 2); + } + } + + [Fact] + public void Var_can_be_used_on_nested_collection_with_ObjectQuery_or_DbQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 0.5, (double)context.WithRelationships.Select( + e => new + { + Result = DbFunctions.Var(e.Types.Select(t => t.Decimal)) + }).First().Result, 2); + + Assert.Equal( + 0.5, (double)GetObjectSet(context).Select( + e => new + { + Result = DbFunctions.Var(e.Types.Select(t => t.Decimal)) + }).First().Result, 2); + } + } + } + + public class VarP : FunctionalTestBase + { + [Fact] + public void VarP_for_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.Decimal)), 2); + Assert.Equal(0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.Decimal)), 2); + } + } + + [Fact] + public void VarP_for_nullable_decimal_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.NullableDecimal)), 2); + Assert.Equal( + 0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.NullableDecimal)), 2); + } + } + + [Fact] + public void VarP_for_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.Double)), 2); + Assert.Equal(0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.Double)), 2); + } + } + + [Fact] + public void VarP_for_nullable_double_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.NullableDouble)), 2); + Assert.Equal( + 0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.NullableDouble)), 2); + } + } + + [Fact] + public void VarP_for_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.Int)), 2); + Assert.Equal(0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.Int)), 2); + } + } + + [Fact] + public void VarP_for_nullable_int_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.NullableInt)), 2); + Assert.Equal(0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.NullableInt)), 2); + } + } + + [Fact] + public void VarP_for_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.Long)), 2); + Assert.Equal(0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.Long)), 2); + } + } + + [Fact] + public void VarP_for_nullable_long_can_be_bootstrapped_from_DbContext_or_ObjectContext() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal(0.25, (double)DbFunctions.VarP(context.WithTypes.Select(e => e.NullableLong)), 2); + Assert.Equal(0.25, (double)DbFunctions.VarP(GetObjectSet(context).Select(e => e.NullableLong)), 2); + } + } + + [Fact] + public void VarP_can_be_used_on_nested_collection_with_ObjectQuery_or_DbQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 0.25, (double)context.WithRelationships.Select( + e => new + { + Result = DbFunctions.VarP(e.Types.Select(t => t.Decimal)) + }).First().Result, 2); + + Assert.Equal( + 0.25, (double)GetObjectSet(context).Select( + e => new + { + Result = DbFunctions.VarP(e.Types.Select(t => t.Decimal)) + }).First().Result, 2); + } + } + } + + public class StringFunctions : FunctionalTestBase + { + [Fact] + public void Left_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + "Magic Unic", + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.Left(e.String, 10)).First()); + + Assert.Equal( + "Magic Unic", + GetObjectSet(context).OrderBy(e => e.Id).Select(e => DbFunctions.Left(e.String, 10)).First()); + } + } + + [Fact] + public void Right_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + "corns Rock", + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.Right(e.String, 10)).First()); + + Assert.Equal( + "corns Rock", + GetObjectSet(context).OrderBy(e => e.Id).Select(e => DbFunctions.Right(e.String, 10)).First()); + } + } + + [Fact] + public void Reverse_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + "kcoR snrocinU cigaM", + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.Reverse(e.String)).First()); + + Assert.Equal( + "kcoR snrocinU cigaM", + GetObjectSet(context).OrderBy(e => e.Id).Select(e => DbFunctions.Reverse(e.String)).First()); + } + } + + [Fact] + public void AsUnicode_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + "Magic Unicorns Rock And Roll All Night Long ツ", + context.WithTypes.OrderBy(e => e.Id).Select( + e => e.String + DbFunctions.AsUnicode(" And Roll All Night Long ツ")).First()); + + Assert.Equal( + "Magic Unicorns Rock And Roll All Night Long ツ", + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => e.String + DbFunctions.AsUnicode(" And Roll All Night Long ツ")).First()); + } + } + + [Fact] + public void AsNonUnicode_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + "Magic Unicorns Rock And Roll All Night Long ?", + context.WithTypes.OrderBy(e => e.Id).Select( + e => e.String + DbFunctions.AsNonUnicode(" And Roll All Night Long ツ")).First()); + + Assert.Equal( + "Magic Unicorns Rock And Roll All Night Long ?", + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => e.String + DbFunctions.AsNonUnicode(" And Roll All Night Long ツ")).First()); + } + } + } + + public class DateTimeFunctions : FunctionalTestBase + { + private const long EF41Ticks = 634380912600000000; + private static readonly DateTime _ef43DateTime = new DateTime(2012, 2, 29, 4, 3, 1, 0, DateTimeKind.Utc); + private static readonly DateTimeOffset _ef43Offset = new DateTimeOffset(2012, 2, 29, 4, 3, 1, 0, new TimeSpan(8, 0, 0)); + + [Fact] + public void GetTotalOffsetMinutes_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 8 * 60, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.GetTotalOffsetMinutes(e.DateTimeOffset)).First()); + + Assert.Equal( + 8 * 60, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.GetTotalOffsetMinutes(e.DateTimeOffset)).First()); + } + } + + [Fact] + public void TruncateTime_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTimeOffset(2011, 4, 11, 0, 0, 0, 0, new TimeSpan(8, 0, 0)), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.TruncateTime(e.DateTimeOffset)).First()); + + Assert.Equal( + new DateTimeOffset(2011, 4, 11, 0, 0, 0, 0, new TimeSpan(8, 0, 0)), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.TruncateTime(e.DateTimeOffset)).First()); + } + } + + [Fact] + public void TruncateTime_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTime(2011, 4, 11, 0, 0, 0, 0, DateTimeKind.Utc), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.TruncateTime(e.DateTime)).First()); + + Assert.Equal( + new DateTime(2011, 4, 11, 0, 0, 0, 0, DateTimeKind.Utc), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.TruncateTime(e.DateTime)).First()); + } + } + + [Fact] + public void CreateDateTime_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTime(2011, 4, 11, 0, 0, 1, 0, DateTimeKind.Utc), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.CreateDateTime(2011, 4, 11, 0, 0, e.Int)).First()); + + Assert.Equal( + new DateTime(2011, 4, 11, 0, 0, 1, 0, DateTimeKind.Utc), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.CreateDateTime(2011, 4, 11, 0, 0, e.Int)).First()); + } + } + + [Fact] + public void CreateDateTimeOffset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTimeOffset(2011, 4, 11, 0, 0, 1, 0, new TimeSpan(0, 1, 0)), + context.WithTypes.OrderBy(e => e.Id).Select( + e => DbFunctions.CreateDateTimeOffset(2011, 4, 11, 0, 0, e.Int, e.Int)).First()); + + Assert.Equal( + new DateTimeOffset(2011, 4, 11, 0, 0, 1, 0, new TimeSpan(0, 1, 0)), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.CreateDateTimeOffset(2011, 4, 11, 0, 0, e.Int, e.Int)).First()); + } + } + + [Fact] + public void CreateTime_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new TimeSpan(1, 2, 3), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.CreateTime(e.Int, 2, 3)).First()); + + Assert.Equal( + new TimeSpan(1, 2, 3), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.CreateTime(e.Int, 2, 3)).First()); + } + } + + [Fact] + public void AddYears_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTimeOffset(2012, 4, 11, 4, 1, 0, 0, new TimeSpan(8, 0, 0)), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddYears(e.DateTimeOffset, e.Int)).First()); + + Assert.Equal( + new DateTimeOffset(2012, 4, 11, 4, 1, 0, 0, new TimeSpan(8, 0, 0)), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddYears(e.DateTimeOffset, e.Int)).First()); + } + } + + [Fact] + public void AddYears_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTime(2012, 4, 11, 4, 1, 0, 0, DateTimeKind.Utc), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddYears(e.DateTime, e.Int)).First()); + + Assert.Equal( + new DateTime(2012, 4, 11, 4, 1, 0, 0, DateTimeKind.Utc), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddYears(e.DateTime, e.Int)).First()); + } + } + + [Fact] + public void AddMonths_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTimeOffset(2011, 5, 11, 4, 1, 0, 0, new TimeSpan(8, 0, 0)), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMonths(e.DateTimeOffset, e.Int)).First()); + + Assert.Equal( + new DateTimeOffset(2011, 5, 11, 4, 1, 0, 0, new TimeSpan(8, 0, 0)), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddMonths(e.DateTimeOffset, e.Int)).First()); + } + } + + [Fact] + public void AddMonths_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTime(2011, 5, 11, 4, 1, 0, 0, DateTimeKind.Utc), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMonths(e.DateTime, e.Int)).First()); + + Assert.Equal( + new DateTime(2011, 5, 11, 4, 1, 0, 0, DateTimeKind.Utc), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddMonths(e.DateTime, e.Int)).First()); + } + } + + [Fact] + public void AddDays_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTimeOffset(2011, 4, 12, 4, 1, 0, 0, new TimeSpan(8, 0, 0)), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddDays(e.DateTimeOffset, e.Int)).First()); + + Assert.Equal( + new DateTimeOffset(2011, 4, 12, 4, 1, 0, 0, new TimeSpan(8, 0, 0)), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddDays(e.DateTimeOffset, e.Int)).First()); + } + } + + [Fact] + public void AddDays_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTime(2011, 4, 12, 4, 1, 0, 0, DateTimeKind.Utc), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddDays(e.DateTime, e.Int)).First()); + + Assert.Equal( + new DateTime(2011, 4, 12, 4, 1, 0, 0, DateTimeKind.Utc), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddDays(e.DateTime, e.Int)).First()); + } + } + + [Fact] + public void AddHours_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTimeOffset(2011, 4, 11, 5, 1, 0, 0, new TimeSpan(8, 0, 0)), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddHours(e.DateTimeOffset, e.Int)).First()); + + Assert.Equal( + new DateTimeOffset(2011, 4, 11, 5, 1, 0, 0, new TimeSpan(8, 0, 0)), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddHours(e.DateTimeOffset, e.Int)).First()); + } + } + + [Fact] + public void AddHours_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTime(2011, 4, 11, 5, 1, 0, 0, DateTimeKind.Utc), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddHours(e.DateTime, e.Int)).First()); + + Assert.Equal( + new DateTime(2011, 4, 11, 5, 1, 0, 0, DateTimeKind.Utc), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddHours(e.DateTime, e.Int)).First()); + } + } + + [Fact] + public void AddHours_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new TimeSpan(5, 1, 0), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddHours(e.TimeSpan, e.Int)).First()); + + Assert.Equal( + new TimeSpan(5, 1, 0), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddHours(e.TimeSpan, e.Int)).First()); + } + } + + [Fact] + public void AddMinutes_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTimeOffset(2011, 4, 11, 4, 2, 0, 0, new TimeSpan(8, 0, 0)), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMinutes(e.DateTimeOffset, e.Int)).First()); + + Assert.Equal( + new DateTimeOffset(2011, 4, 11, 4, 2, 0, 0, new TimeSpan(8, 0, 0)), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddMinutes(e.DateTimeOffset, e.Int)).First()); + } + } + + [Fact] + public void AddMinutes_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTime(2011, 4, 11, 4, 2, 0, 0, DateTimeKind.Utc), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMinutes(e.DateTime, e.Int)).First()); + + Assert.Equal( + new DateTime(2011, 4, 11, 4, 2, 0, 0, DateTimeKind.Utc), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddMinutes(e.DateTime, e.Int)).First()); + } + } + + [Fact] + public void AddMinutes_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new TimeSpan(4, 2, 0), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMinutes(e.TimeSpan, e.Int)).First()); + + Assert.Equal( + new TimeSpan(4, 2, 0), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddMinutes(e.TimeSpan, e.Int)).First()); + } + } + + [Fact] + public void AddSeconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTimeOffset(2011, 4, 11, 4, 1, 1, 0, new TimeSpan(8, 0, 0)), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddSeconds(e.DateTimeOffset, e.Int)).First()); + + Assert.Equal( + new DateTimeOffset(2011, 4, 11, 4, 1, 1, 0, new TimeSpan(8, 0, 0)), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddSeconds(e.DateTimeOffset, e.Int)).First()); + } + } + + [Fact] + public void AddSeconds_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTime(2011, 4, 11, 4, 1, 1, 0, DateTimeKind.Utc), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddSeconds(e.DateTime, e.Int)).First()); + + Assert.Equal( + new DateTime(2011, 4, 11, 4, 1, 1, 0, DateTimeKind.Utc), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddSeconds(e.DateTime, e.Int)).First()); + } + } + + [Fact] + public void AddSeconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new TimeSpan(4, 1, 1), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddSeconds(e.TimeSpan, e.Int)).First()); + + Assert.Equal( + new TimeSpan(4, 1, 1), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddSeconds(e.TimeSpan, e.Int)).First()); + } + } + + [Fact] + public void AddMilliseconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTimeOffset(2011, 4, 11, 4, 1, 0, 1, new TimeSpan(8, 0, 0)), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMilliseconds(e.DateTimeOffset, e.Int)).First()); + + Assert.Equal( + new DateTimeOffset(2011, 4, 11, 4, 1, 0, 1, new TimeSpan(8, 0, 0)), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddMilliseconds(e.DateTimeOffset, e.Int)).First()); + } + } + + [Fact] + public void AddMilliseconds_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new DateTime(2011, 4, 11, 4, 1, 0, 1, DateTimeKind.Utc), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMilliseconds(e.DateTime, e.Int)).First()); + + Assert.Equal( + new DateTime(2011, 4, 11, 4, 1, 0, 1, DateTimeKind.Utc), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddMilliseconds(e.DateTime, e.Int)).First()); + } + } + + [Fact] + public void AddMilliseconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new TimeSpan(0, 4, 1, 0, 1), + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMilliseconds(e.TimeSpan, e.Int)).First()); + + Assert.Equal( + new TimeSpan(0, 4, 1, 0, 1), + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddMilliseconds(e.TimeSpan, e.Int)).First()); + } + } + + [Fact] + public void AddMicroseconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + EF41Ticks + 10, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMicroseconds(e.DateTimeOffset, e.Int)).First(). + Value.Ticks); + + Assert.Equal( + EF41Ticks + 10, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddMicroseconds(e.DateTimeOffset, e.Int)).First().Value.Ticks); + } + } + + [Fact] + public void AddMicroseconds_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + EF41Ticks + 10, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMicroseconds(e.DateTime, e.Int)).First().Value. + Ticks); + + Assert.Equal( + EF41Ticks + 10, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddMicroseconds(e.DateTime, e.Int)).First().Value.Ticks); + } + } + + [Fact] + public void AddMicroseconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new TimeSpan(4, 1, 0).Ticks + 10, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddMicroseconds(e.TimeSpan, e.Int)).First().Value.Ticks); + + Assert.Equal( + new TimeSpan(4, 1, 0).Ticks + 10, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddMicroseconds(e.TimeSpan, e.Int)).First().Value.Ticks); + } + } + + [Fact] + public void AddNanoseconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + EF41Ticks + 1, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddNanoseconds(e.DateTimeOffset, e.Int * 100)). + First(). + Value.Ticks); + + Assert.Equal( + EF41Ticks + 1, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddNanoseconds(e.DateTimeOffset, e.Int * 100)).First().Value.Ticks); + } + } + + [Fact] + public void AddNanoseconds_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + EF41Ticks + 1, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddNanoseconds(e.DateTime, e.Int * 100)).First(). + Value. + Ticks); + + Assert.Equal( + EF41Ticks + 1, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddNanoseconds(e.DateTime, e.Int * 100)).First().Value.Ticks); + } + } + + [Fact] + public void AddNanoseconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + new TimeSpan(4, 1, 0).Ticks + 1, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.AddNanoseconds(e.TimeSpan, e.Int * 100)).First().Value. + Ticks); + + Assert.Equal( + new TimeSpan(4, 1, 0).Ticks + 1, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.AddNanoseconds(e.TimeSpan, e.Int * 100)).First().Value.Ticks); + } + } + + [Fact] + public void DiffYears_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 1, context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffYears(e.DateTimeOffset, _ef43Offset)).First()); + + Assert.Equal( + 1, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffYears(e.DateTimeOffset, _ef43Offset)).First()); + } + } + + [Fact] + public void DiffYears_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 1, context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffYears(e.DateTime, _ef43DateTime)).First()); + + Assert.Equal( + 1, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffYears(e.DateTime, _ef43DateTime)).First()); + } + } + + [Fact] + public void DiffMonths_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 10, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffMonths(e.DateTimeOffset, _ef43Offset)).First()); + + Assert.Equal( + 10, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffMonths(e.DateTimeOffset, _ef43Offset)).First()); + } + } + + [Fact] + public void DiffMonths_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 10, context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffMonths(e.DateTime, _ef43DateTime)).First()); + + Assert.Equal( + 10, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffMonths(e.DateTime, _ef43DateTime)).First()); + } + } + + [Fact] + public void DiffDays_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 324, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffDays(e.DateTimeOffset, _ef43Offset)).First()); + + Assert.Equal( + 324, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffDays(e.DateTimeOffset, _ef43Offset)).First()); + } + } + + [Fact] + public void DiffDays_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 324, context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffDays(e.DateTime, _ef43DateTime)).First()); + + Assert.Equal( + 324, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffDays(e.DateTime, _ef43DateTime)).First()); + } + } + + [Fact] + public void DiffHours_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 7776, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffHours(e.DateTimeOffset, _ef43Offset)).First()); + + Assert.Equal( + 7776, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffHours(e.DateTimeOffset, _ef43Offset)).First()); + } + } + + [Fact] + public void DiffHours_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 7776, context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffHours(e.DateTime, _ef43DateTime)).First()); + + Assert.Equal( + 7776, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffHours(e.DateTime, _ef43DateTime)).First()); + } + } + + [Fact] + public void DiffHours_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 1, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffHours(e.TimeSpan, new TimeSpan(5, 1, 0))).First()); + + Assert.Equal( + 1, GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffHours(e.TimeSpan, new TimeSpan(5, 1, 0))).First()); + } + } + + [Fact] + public void DiffMinutes_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 466562, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffMinutes(e.DateTimeOffset, _ef43Offset)).First()); + + Assert.Equal( + 466562, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffMinutes(e.DateTimeOffset, _ef43Offset)).First()); + } + } + + [Fact] + public void DiffMinutes_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 466562, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffMinutes(e.DateTime, _ef43DateTime)).First()); + + Assert.Equal( + 466562, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffMinutes(e.DateTime, _ef43DateTime)).First()); + } + } + + [Fact] + public void DiffMinutes_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 1, + context.WithTypes.OrderBy(e => e.Id).Select( + e => DbFunctions.DiffMinutes(e.TimeSpan, new TimeSpan(4, 2, 0))).First()); + + Assert.Equal( + 1, GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffMinutes(e.TimeSpan, new TimeSpan(4, 2, 0))).First()); + } + } + + [Fact] + public void DiffSeconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 27993721, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffSeconds(e.DateTimeOffset, _ef43Offset)).First()); + + Assert.Equal( + 27993721, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffSeconds(e.DateTimeOffset, _ef43Offset)).First()); + } + } + + [Fact] + public void DiffSeconds_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 27993721, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffSeconds(e.DateTime, _ef43DateTime)).First()); + + Assert.Equal( + 27993721, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffSeconds(e.DateTime, _ef43DateTime)).First()); + } + } + + [Fact] + public void DiffSeconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 1, + context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.DiffSeconds(e.TimeSpan, new TimeSpan(4, 1, 1))).First()); + + Assert.Equal( + 1, GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffSeconds(e.TimeSpan, new TimeSpan(4, 1, 1))).First()); + } + } + + [Fact] + public void DiffMilliseconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 100, + context.WithTypes.OrderBy(e => e.Id).Select( + e => + DbFunctions.DiffMilliseconds( + e.DateTimeOffset, new DateTimeOffset(EF41Ticks + 1000000, new TimeSpan(8, 0, 0)))).First()); + + Assert.Equal( + 100, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => + DbFunctions.DiffMilliseconds( + e.DateTimeOffset, new DateTimeOffset(EF41Ticks + 1000000, new TimeSpan(8, 0, 0)))).First()); + } + } + + [Fact] + public void DiffMilliseconds_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 100, + context.WithTypes.OrderBy(e => e.Id).Select( + e => DbFunctions.DiffMilliseconds(e.DateTime, new DateTime(EF41Ticks + 1000000, DateTimeKind.Utc))).First()); + + Assert.Equal( + 100, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffMilliseconds(e.DateTime, new DateTime(EF41Ticks + 1000000, DateTimeKind.Utc))).First()); + } + } + + [Fact] + public void DiffMilliseconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 1, + context.WithTypes.OrderBy(e => e.Id).Select( + e => DbFunctions.DiffMilliseconds(e.TimeSpan, new TimeSpan(0, 4, 1, 0, 1))).First()); + + Assert.Equal( + 1, GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffMilliseconds(e.TimeSpan, new TimeSpan(0, 4, 1, 0, 1))).First()); + } + } + + [Fact] + public void DiffMicroseconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 100000, + context.WithTypes.OrderBy(e => e.Id).Select( + e => + DbFunctions.DiffMicroseconds( + e.DateTimeOffset, new DateTimeOffset(EF41Ticks + 1000000, new TimeSpan(8, 0, 0)))).First()); + + Assert.Equal( + 100000, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => + DbFunctions.DiffMicroseconds( + e.DateTimeOffset, new DateTimeOffset(EF41Ticks + 1000000, new TimeSpan(8, 0, 0)))).First()); + } + } + + [Fact] + public void DiffMicroseconds_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 100000, + context.WithTypes.OrderBy(e => e.Id).Select( + e => DbFunctions.DiffMicroseconds(e.DateTime, new DateTime(EF41Ticks + 1000000, DateTimeKind.Utc))).First()); + + Assert.Equal( + 100000, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffMicroseconds(e.DateTime, new DateTime(EF41Ticks + 1000000, DateTimeKind.Utc))).First()); + } + } + + [Fact] + public void DiffMicroseconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + var ticks = new TimeSpan(4, 1, 0).Ticks + 10; + Assert.Equal( + 1, context.WithTypes.OrderBy(e => e.Id).Select( + e => DbFunctions.DiffMicroseconds(e.TimeSpan, new TimeSpan(ticks))).First()); + + Assert.Equal( + 1, GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffMicroseconds(e.TimeSpan, new TimeSpan(ticks))).First()); + } + } + + [Fact] + public void DiffNanoseconds_on_offset_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 100000000, + context.WithTypes.OrderBy(e => e.Id).Select( + e => + DbFunctions.DiffNanoseconds( + e.DateTimeOffset, new DateTimeOffset(EF41Ticks + 1000000, new TimeSpan(8, 0, 0)))).First()); + + Assert.Equal( + 100000000, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => + DbFunctions.DiffNanoseconds( + e.DateTimeOffset, new DateTimeOffset(EF41Ticks + 1000000, new TimeSpan(8, 0, 0)))).First()); + } + } + + [Fact] + public void DiffNanoseconds_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 100000000, + context.WithTypes.OrderBy(e => e.Id).Select( + e => DbFunctions.DiffNanoseconds(e.DateTime, new DateTime(EF41Ticks + 1000000, DateTimeKind.Utc))).First()); + + Assert.Equal( + 100000000, + GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffNanoseconds(e.DateTime, new DateTime(EF41Ticks + 1000000, DateTimeKind.Utc))).First()); + } + } + + [Fact] + public void DiffNanoseconds_on_time_span_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + var ticks = new TimeSpan(4, 1, 0).Ticks + 1; + Assert.Equal( + 100, context.WithTypes.OrderBy(e => e.Id).Select( + e => DbFunctions.DiffNanoseconds(e.TimeSpan, new TimeSpan(ticks))).First()); + + Assert.Equal( + 100, GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.DiffNanoseconds(e.TimeSpan, new TimeSpan(ticks))).First()); + } + } + } + + public class Truncate : FunctionalTestBase + { + [Fact] + public void Truncate_on_double_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 1.0, (double)context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.Truncate(e.Double, e.Int)).First(), 7); + + Assert.Equal( + 1.0, (double)GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.Truncate(e.Double, e.Int)).First(), 7); + } + } + + [Fact] + public void Truncate_on_decimal_can_be_used_in_DbQuery_or_ObjectQuery() + { + using (var context = new EntityFunctionContext()) + { + Assert.Equal( + 1, (decimal)context.WithTypes.OrderBy(e => e.Id).Select(e => DbFunctions.Truncate(e.Decimal, e.Int)).First(), 7); + + Assert.Equal( + 1, (decimal)GetObjectSet(context).OrderBy(e => e.Id).Select( + e => DbFunctions.Truncate(e.Decimal, e.Int)).First(), 7); + } + } + } + + public static ObjectSet GetObjectSet(DbContext context) where TEntity : class + { + return ((IObjectContextAdapter)context).ObjectContext.CreateObjectSet(); + } + } + + public class EntityFunctionContext : DbContext + { + static EntityFunctionContext() + { + Database.SetInitializer(new EntityFunctionInitializer()); + } + + public DbSet WithTypes { get; set; } + public DbSet WithRelationships { get; set; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + modelBuilder + .Entity() + .Property(e => e.DateTime) + .HasColumnType("datetime2"); + } + } + + public class EntityWithTypes + { + public int Id { get; set; } + + public decimal Decimal { get; set; } + public decimal? NullableDecimal { get; set; } + + public double Double { get; set; } + public double? NullableDouble { get; set; } + + public int Int { get; set; } + public int? NullableInt { get; set; } + + public long Long { get; set; } + public long? NullableLong { get; set; } + + public DateTime? DateTime { get; set; } + public DateTimeOffset? DateTimeOffset { get; set; } + public TimeSpan? TimeSpan { get; set; } + + public string String { get; set; } + + public int RelationshipId { get; set; } + public EntityWithRelationship Relationship { get; set; } + } + + public class EntityWithRelationship + { + public int Id { get; set; } + + public ICollection Types { get; set; } + } + + public class EntityFunctionInitializer : DropCreateDatabaseAlways + { + protected override void Seed(EntityFunctionContext context) + { + var entityWithRelationship = new EntityWithRelationship(); + new[] + { + new EntityWithTypes + { + Decimal = 1.0001m, + NullableDecimal = 1m, + Double = 1.0001, + NullableDouble = 1.0, + Int = 1, + NullableInt = 1, + Long = 1, + NullableLong = 1, + String = "Magic Unicorns Rock", + DateTime = new DateTime(2011, 4, 11, 4, 1, 0, 0, DateTimeKind.Utc), + DateTimeOffset = new DateTimeOffset(2011, 4, 11, 4, 1, 0, 0, new TimeSpan(8, 0, 0)), + TimeSpan = new TimeSpan(4, 1, 0), + Relationship = entityWithRelationship + }, + new EntityWithTypes + { + Decimal = 2m, + NullableDecimal = 2m, + Double = 2.0, + NullableDouble = 2.0, + Int = 2, + NullableInt = 2, + Long = 2, + NullableLong = 2, + String = "Magic Unicorns Roll", + DateTime = new DateTime(2012, 2, 29, 4, 3, 1, 0, DateTimeKind.Utc), + DateTimeOffset = new DateTimeOffset(2012, 2, 29, 4, 3, 1, 0, new TimeSpan(8, 0, 0)), + TimeSpan = new TimeSpan(4, 3, 1), + Relationship = entityWithRelationship + } + }.Each(e => context.WithTypes.Add(e)); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/ProductivityApi/PluralizationServiceTests.cs b/test/EntityFramework/FunctionalTests.Transitional/ProductivityApi/PluralizationServiceTests.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/ProductivityApi/PluralizationServiceTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/ProductivityApi/PluralizationServiceTests.cs diff --git a/test/EntityFramework/FunctionalTests/ProductivityApi/TemplateTests.cs b/test/EntityFramework/FunctionalTests.Transitional/ProductivityApi/TemplateTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/ProductivityApi/TemplateTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/ProductivityApi/TemplateTests.cs index c11bb067..5c9e7aed 100644 --- a/test/EntityFramework/FunctionalTests/ProductivityApi/TemplateTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/ProductivityApi/TemplateTests.cs @@ -1,743 +1,743 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace ProductivityApiTests -{ - using System; - using System.Collections.Generic; - using System.Data.Entity; - using System.Data.Entity.Core.Objects; - using System.Data.Entity.Infrastructure; - using System.Linq; - using System.Reflection; - using System.Transactions; - using Another.Place; - using FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns; - using FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel; - using Xunit; - using Xunit.Extensions; - - /// - /// Tests for context/entity classes generated from productivity T4 templates. - /// - /// The infrastructure for generating code from the T4 templates at build time does not yet work - /// in the DataSvc branch/Productivity project. We will revisit this later, but for now the - /// process for making changes to the templates is as follows: - /// 1. Change the templates in “ndp\fx\src\DataEntityDesign\Design\T4Templates” - /// 2. Run ProcessTemplates.bat from the command line while in the - /// “src\qa\devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityFunctionalTests\ProductivityApi\TemplateModels” - /// directory. This will copy the source templates into the functional test project with appropriate names - /// and will replace the Model.edmx marker in each template with a path to the schema to use. - /// 3. Use Visual Studio to “Transform All Templates”. For example, click the icon at the top of the Solution - /// Explorer window while something in the FunctionalTests project is selected. - /// - public class TemplateTests : FunctionalTestBase - { - #region Infrastructure/setup - - private const BindingFlags MemberBindingFlags = - BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; - - static TemplateTests() - { - InitializeModelFirstDatabases(); - } - - #endregion - - #region Simple tests that the context and entities works - - private const string Building18Id = "18181818-1818-1818-1818-181818181818"; - - [Fact] - public void Read_and_write_using_AdvancedPatternsModelFirst_created_from_T4_template() - { - var building18 = CreateBuilding(); - - using (new TransactionScope()) - { - using (var context = new AdvancedPatternsModelFirstContext()) - { - context.Buildings.Add(building18); - - var foundBuilding = context.Buildings.Find(new Guid(Building18Id)); - Assert.Equal("Building 18", foundBuilding.Name); - - context.SaveChanges(); - } - - using (var context = new AdvancedPatternsModelFirstContext()) - { - var foundBuilding = context.Buildings.Find(new Guid(Building18Id)); - Assert.Equal("Building 18", foundBuilding.Name); - Assert.Equal(3, context.Entry(foundBuilding).Collection(b => b.Offices).Query().Count()); - - var arthursOffice = context.Offices.Single(o => o.Number == "1/1125"); - Assert.Same(foundBuilding, arthursOffice.GetBuilding()); - } - } - } - - private static BuildingMf CreateBuilding() - { - var building18 = new BuildingMf( - new Guid(Building18Id), "Building 18", -1000000m, - new AddressMf("Across From 25", "Redmond", "WA", "98052", 7, "70's")); - - foreach (var office in new[] - { - new OfficeMf - { - Number = "1/1125" - }, - new OfficeMf - { - Number = "1/1120" - }, - new OfficeMf - { - Number = "1/1123" - }, - }) - { - building18.Offices.Add(office); - } - - return building18; - } - - [Fact] - [AutoRollback] - public void Read_and_write_using_MonsterModel_created_from_T4_template() - { - int orderId; - int? customerId; - - using (var context = new MonsterModel()) - { - var entry = context.Entry(CreateOrder()); - entry.State = EntityState.Added; - - context.SaveChanges(); - - orderId = entry.Entity.OrderId; - customerId = entry.Entity.CustomerId; - } - - using (var context = new MonsterModel()) - { - var order = context.Order.Include(o => o.Customer).Single(o => o.CustomerId == customerId); - - Assert.Equal(orderId, order.OrderId); - Assert.True(order.Customer.Orders.Contains(order)); - } - } - - private static OrderMm CreateOrder() - { - return new OrderMm - { - OrderId = -1, - Customer = - new CustomerMm - { - CustomerId = -1, - Name = "Jim Lathrop", - ContactInfo = - new ContactDetailsMm - { - Email = "jil@newmonics.com", - HomePhone = - new PhoneMm - { - PhoneNumber = "555-5555-551", - Extension = "x555", - PhoneType = PhoneTypeMm.Cell - }, - WorkPhone = - new PhoneMm - { - PhoneNumber = "555-5555-552", - Extension = "x555", - PhoneType = PhoneTypeMm.Land - }, - MobilePhone = - new PhoneMm - { - PhoneNumber = "555-5555-553", - Extension = "x555", - PhoneType = PhoneTypeMm.Satellite - }, - }, - Auditing = - new AuditInfoMm - { - ModifiedBy = "barney", - ModifiedDate = DateTime.Now, - Concurrency = - new ConcurrencyInfoMm - { - QueriedDateTime = DateTime.Now, - Token = "1" - }, - }, - }, - Concurrency = new ConcurrencyInfoMm - { - QueriedDateTime = DateTime.Now, - Token = "1" - }, - }; - } - - #endregion - - #region Tests for default container name when using model/database first (Dev11 142609) - - [Fact] - public void Default_container_name_is_set_when_there_is_a_single_container_in_the_model() - { - using (var context = new AdvancedPatternsModelFirstContext()) - { - Assert.Equal( - "AdvancedPatternsModelFirstContext", - ((IObjectContextAdapter)context).ObjectContext.DefaultContainerName); - } - } - - #endregion - - #region Tests for not needing LoadFromAssembly with model/database first (Dev11 142609) - - [Fact] - public void Object_space_types_are_loaded_when_code_drops_down_to_ObjectContext() - { - using (var context = new AdvancedPatternsModelFirstContext()) - { - var objectContext = ((IObjectContextAdapter)context).ObjectContext; - - // The following would previously throw because it requires manual o-space loading - var results = - objectContext.CreateQuery( - "select e.Number from AdvancedPatternsModelFirstContext.Offices as e").ToList(); - - Assert.Equal(4, results.Count); - } - } - - #endregion - - #region Function import tests - - [Fact] - public void Can_read_entities_from_a_stored_proc_mapped_to_a_function_import() - { - using (var context = new AdvancedPatternsModelFirstContext()) - { - var offices = context.AllOfficesStoredProc().ToList(); - - Assert.Equal(4, offices.Count); - Assert.Equal(4, context.Offices.Local.Count); - new List - { - "1/1221", - "1/1223", - "2/1458", - "2/1789" - }.ForEach( - n => offices.Where(o => o.Number == n).Single()); - } - } - - [Fact] - public void Can_read_entities_from_a_stored_proc_mapped_to_a_function_import_with_merge_option() - { - using (var context = new AdvancedPatternsModelFirstContext()) - { - var offices = context.AllOfficesStoredProc(MergeOption.NoTracking).ToList(); - - Assert.Equal(4, offices.Count); - Assert.Equal(0, context.Offices.Local.Count); - new List - { - "1/1221", - "1/1223", - "2/1458", - "2/1789" - }.ForEach( - n => offices.Where(o => o.Number == n).Single()); - } - } - - [Fact] - public void Can_read_entities_from_a_stored_proc_with_parameters_mapped_to_a_function_import() - { - using (var context = new AdvancedPatternsModelFirstContext()) - { - var offices = - context.OfficesInBuildingStoredProc(AdvancedPatternsModelFirstInitializer.KnownBuildingGuid).ToList(); - - Assert.Equal(2, offices.Count); - Assert.Equal(2, context.Offices.Local.Count); - new List - { - "1/1221", - "1/1223" - }.ForEach(n => offices.Where(o => o.Number == n).Single()); - } - } - - [Fact] - public void Can_read_entities_from_a_stored_proc_with_parameters_mapped_to_a_function_import_with_merge_option() - { - using (var context = new AdvancedPatternsModelFirstContext()) - { - var offices = - context.OfficesInBuildingStoredProc( - AdvancedPatternsModelFirstInitializer.KnownBuildingGuid, - MergeOption.NoTracking).ToList(); - - Assert.Equal(2, offices.Count); - Assert.Equal(0, context.Offices.Local.Count); - new List - { - "1/1221", - "1/1223" - }.ForEach(n => offices.Where(o => o.Number == n).Single()); - } - } - - [Fact] - public void Can_read_complex_objects_from_a_stored_proc_mapped_to_a_function_import() - { - using (var context = new AdvancedPatternsModelFirstContext()) - { - var siteInfo = context.AllSiteInfoStoredProc().ToList(); - - Assert.Equal(2, siteInfo.Count); - new List - { - "Clean", - "Contaminated" - }.ForEach( - n => siteInfo.Where(o => o.Environment == n).Single()); - } - } - - [Fact] - public void Can_read_scalar_return_from_a_stored_proc_mapped_to_a_function_import() - { - using (var context = new AdvancedPatternsModelFirstContext()) - { - var employeeIds = - context.EmployeeIdsInOfficeStoredProc( - "1/1221", - AdvancedPatternsModelFirstInitializer.KnownBuildingGuid). - ToList(); - - Assert.Equal(1, employeeIds.Count); - Assert.Equal("Rowan", context.Employees.Find(employeeIds.Single()).FirstName); - } - } - - [Fact] - public void Can_execute_a_stored_proc_that_returns_no_results_mapped_to_a_function_import() - { - using (var context = new AdvancedPatternsModelFirstContext()) - { - var result = context.SkimOffLeaveBalanceStoredProc("Arthur", "Vickers"); - - Assert.Equal(-1, result); - Assert.Equal( - 0M, - context.Set().Where(e => e.FirstName == "Arthur").Single().LeaveBalance); - } - } - - [Fact] - public void Executing_a_stored_proc_mapped_to_a_function_import_honors_append_only_merge_option() - { - using (var context = new AdvancedPatternsModelFirstContext()) - { - // Arrange - var office = context.Offices.Find("1/1221", AdvancedPatternsModelFirstInitializer.KnownBuildingGuid); - context.Entry(office).Property("Description").CurrentValue = "Test"; - - // Act - var offices = context.AllOfficesStoredProc(MergeOption.AppendOnly).ToList(); - - // Verify - Assert.True(context.Entry(office).State == EntityState.Modified); - Assert.True(context.ChangeTracker.Entries().Count() == 4); - } - } - - [Fact] - public void Executing_a_stored_proc_mapped_to_a_function_import_honors_no_tracking_merge_option() - { - using (var context = new AdvancedPatternsModelFirstContext()) - { - // Act - var offices = context.AllOfficesStoredProc(MergeOption.NoTracking).ToList(); - - // Verify - Assert.True(context.ChangeTracker.Entries().Count() == 0); - } - } - - [Fact] - public void Executing_a_stored_proc_mapped_to_a_function_import_with_merge_option_overwrite_changes() - { - using (var context = new AdvancedPatternsModelFirstContext()) - { - // Arrange - var office = context.Offices.Find("1/1221", AdvancedPatternsModelFirstInitializer.KnownBuildingGuid); - context.Entry(office).Property("Description").CurrentValue = "Test"; - - // Act - var offices = context.AllOfficesStoredProc(MergeOption.OverwriteChanges).ToList(); - - // Verify - Assert.True(context.Entry(office).State == EntityState.Unchanged); - Assert.True(context.ChangeTracker.Entries().Count() == 4); - } - } - - [Fact] - public void Executing_a_stored_proc_mapped_to_a_function_import_with_merge_option_preserve_changes() - { - using (var context = new AdvancedPatternsModelFirstContext()) - { - // Arrange - var office1 = context.Offices.Find("1/1221", AdvancedPatternsModelFirstInitializer.KnownBuildingGuid); - var office2 = context.Offices.Find("1/1223", AdvancedPatternsModelFirstInitializer.KnownBuildingGuid); - context.Entry(office2).Property("Description").CurrentValue = "Test"; - - // Act - var offices = context.AllOfficesStoredProc(MergeOption.PreserveChanges).ToList(); - - // Verify - Assert.True(context.Entry(office1).State == EntityState.Unchanged); - Assert.True(context.Entry(office2).State == EntityState.Modified); - Assert.True(context.ChangeTracker.Entries().Count() == 4); - } - } - - #endregion - - #region Tests for specific properties of the generated code - - [Fact] - public void CSharp_DbContext_template_creates_collections_that_are_initialized_with_HashSets() - { - Assert.IsType>(new OrderMm().OrderLines); - } - - [Fact] - public void CSharp_DbContext_template_initializes_complex_properties_on_entities() - { - Assert.NotNull(new CustomerMm().ContactInfo); - } - - [Fact] - public void CSharp_DbContext_template_initializes_complex_properties_on_complex_objects() - { - Assert.NotNull(new CustomerMm().ContactInfo.HomePhone); - } - - [Fact] - public void CSharp_DbContext_template_initializes_default_values() - { - Assert.Equal(1, new OrderLineMm().Quantity); - Assert.Equal("C", new LicenseMm().LicenseClass); - } - - [Fact] - public void CSharp_DbContext_template_initializes_default_values_on_complex_objects() - { - Assert.Equal("None", new PhoneMm().Extension); - } - - [Fact] - public void CSharp_DbContext_template_creates_non_virtual_scalar_and_complex_properties() - { - Assert.False(typeof(CustomerMm).GetProperty("Name").GetGetMethod().IsVirtual); - Assert.False(typeof(CustomerMm).GetProperty("Name").GetSetMethod().IsVirtual); - Assert.False(typeof(CustomerMm).GetProperty("ContactInfo").GetGetMethod().IsVirtual); - Assert.False(typeof(CustomerMm).GetProperty("ContactInfo").GetSetMethod().IsVirtual); - } - - [Fact] - public void CSharp_DbContext_template_creates_virtual_collection_and_reference_navigation_properties() - { - Assert.True(typeof(CustomerMm).GetProperty("Orders").GetGetMethod().IsVirtual); - Assert.True(typeof(CustomerMm).GetProperty("Orders").GetSetMethod().IsVirtual); - Assert.True(typeof(CustomerMm).GetProperty("Info").GetGetMethod().IsVirtual); - Assert.True(typeof(CustomerMm).GetProperty("Info").GetSetMethod().IsVirtual); - } - - [Fact] - public void CSharp_DbContext_template_creates_an_abstract_class_for_abstract_types_in_the_model() - { - Assert.True(typeof(EmployeeMf).IsAbstract); - } - - [Fact] - public void CSharp_DbContext_template_can_create_private_non_virtual_nav_prop() - { - var navProp = typeof(OfficeMf).GetProperty("Building", MemberBindingFlags); - Assert.True(navProp.GetGetMethod(nonPublic: true).IsPrivate); - Assert.False(navProp.GetGetMethod(nonPublic: true).IsVirtual); - Assert.True(navProp.GetSetMethod(nonPublic: true).IsPrivate); - Assert.False(navProp.GetSetMethod(nonPublic: true).IsVirtual); - } - - [Fact] - public void CSharp_DbContext_template_can_create_fully_internal_nav_prop() - { - var navProp = typeof(WorkOrderMf).GetProperty("Employee", MemberBindingFlags); - Assert.True(navProp.GetGetMethod(nonPublic: true).IsAssembly); - Assert.True(navProp.GetGetMethod(nonPublic: true).IsVirtual); - Assert.True(navProp.GetSetMethod(nonPublic: true).IsAssembly); - Assert.True(navProp.GetSetMethod(nonPublic: true).IsVirtual); - } - - [Fact] - public void CSharp_DbContext_template_can_create_nav_prop_with_specific_getter_access() - { - var navProp = typeof(OfficeMf).GetProperty("WhiteBoards", MemberBindingFlags); - Assert.True(navProp.GetGetMethod(nonPublic: true).IsAssembly); - Assert.True(navProp.GetGetMethod(nonPublic: true).IsVirtual); - Assert.True(navProp.GetSetMethod(nonPublic: true).IsPublic); - Assert.True(navProp.GetSetMethod(nonPublic: true).IsVirtual); - } - - [Fact] - public void CSharp_DbContext_template_can_create_nav_prop_with_specific_setter_access() - { - var navProp = typeof(BuildingMf).GetProperty("MailRooms", MemberBindingFlags); - Assert.True(navProp.GetGetMethod(nonPublic: true).IsAssembly); - Assert.True(navProp.GetGetMethod(nonPublic: true).IsVirtual); - Assert.True(navProp.GetSetMethod(nonPublic: true).IsPrivate); - Assert.False(navProp.GetSetMethod(nonPublic: true).IsVirtual); - } - - [Fact] - public void CSharp_DbContext_template_can_create_fully_internal_primitive_prop() - { - var prop = typeof(BuildingMf).GetProperty("Value", MemberBindingFlags); - Assert.True(prop.GetGetMethod(nonPublic: true).IsAssembly); - Assert.True(prop.GetSetMethod(nonPublic: true).IsAssembly); - } - - [Fact] - public void CSharp_DbContext_template_can_create_primitive_prop_with_specific_getter_access() - { - var prop = typeof(EmployeeMf).GetProperty("LastName", MemberBindingFlags); - Assert.True(prop.GetGetMethod(nonPublic: true).IsPrivate); - Assert.True(prop.GetSetMethod(nonPublic: true).IsAssembly); - } - - [Fact] - public void CSharp_DbContext_template_can_create_primitive_prop_with_specific_setter_access() - { - var prop = typeof(EmployeeMf).GetProperty("FirstName", MemberBindingFlags); - Assert.True(prop.GetGetMethod(nonPublic: true).IsPublic); - Assert.True(prop.GetSetMethod(nonPublic: true).IsPrivate); - } - - [Fact] - public void CSharp_DbContext_template_can_create_fully_internal_primitive_prop_on_a_complex_type() - { - var prop = typeof(AddressMf).GetProperty("State", MemberBindingFlags); - Assert.True(prop.GetGetMethod(nonPublic: true).IsAssembly); - Assert.True(prop.GetSetMethod(nonPublic: true).IsAssembly); - } - - [Fact] - public void CSharp_DbContext_template_can_create_primitive_prop_on_a_complex_type_with_specific_getter_access() - { - var prop = typeof(AddressMf).GetProperty("City", MemberBindingFlags); - Assert.True(prop.GetGetMethod(nonPublic: true).IsPrivate); - Assert.True(prop.GetSetMethod(nonPublic: true).IsPublic); - } - - [Fact] - public void CSharp_DbContext_template_can_create_primitive_prop_on_a_complex_type_with_specific_setter_access() - { - var prop = typeof(AddressMf).GetProperty("ZipCode", MemberBindingFlags); - Assert.True(prop.GetGetMethod(nonPublic: true).IsAssembly); - Assert.True(prop.GetSetMethod(nonPublic: true).IsPrivate); - } - - [Fact] - public void CSharp_DbContext_template_can_create_complex_prop_with_different_getter_and_setter_access() - { - var prop = typeof(BuildingMf).GetProperty("Address", MemberBindingFlags); - Assert.True(prop.GetGetMethod(nonPublic: true).IsAssembly); - Assert.True(prop.GetSetMethod(nonPublic: true).IsPrivate); - } - - [Fact] - public void - CSharp_DbContext_template_can_create_complex_prop_on_a_complex_type_with_different_getter_and_setter_access() - { - var prop = typeof(AddressMf).GetProperty("SiteInfo", MemberBindingFlags); - Assert.True(prop.GetGetMethod(nonPublic: true).IsAssembly); - Assert.True(prop.GetSetMethod(nonPublic: true).IsPrivate); - } - - [Fact] - public void CSharp_DbContext_template_can_create_non_public_DbSet_property() - { - var prop = typeof(AdvancedPatternsModelFirstContext).GetProperty("MailRooms", MemberBindingFlags); - Assert.True(prop.GetGetMethod(nonPublic: true).IsAssembly); - Assert.True(prop.GetSetMethod(nonPublic: true).IsAssembly); - } - - [Fact] - public void CSharp_DbContext_template_can_create_non_public_complex_type() - { - Assert.True(typeof(SiteInfoMf).IsNotPublic); - } - - [Fact] - public void CSharp_DbContext_template_can_create_non_public_entity_type() - { - Assert.True(typeof(MailRoomMf).IsNotPublic); - } - - [Fact] - public void CSharp_DbContext_template_can_create_non_public_context_type() - { - Assert.True(typeof(AdvancedPatternsModelFirstContext).IsNotPublic); - } - - [Fact] - public void CSharp_DbContext_template_has_lazy_loading_enabled_by_default() - { - using (var context = new MonsterModel()) - { - Assert.True(context.Configuration.LazyLoadingEnabled); - } - } - - [Fact] - public void CSharp_DbContext_template_allows_lazy_loading_to_be_turned_off() - { - using (var context = new AdvancedPatternsModelFirstContext()) - { - Assert.False(context.Configuration.LazyLoadingEnabled); - } - } - - [Fact] - public void CSharp_DbContext_template_creates_sets_for_all_base_types_but_not_derived_types() - { - var expectedMonsterSets = new[] - { - "Customer", "Barcode", "IncorrectScan", "BarcodeDetail", "Complaint", - "Resolution", - "Login", "SuspiciousActivity", "SmartCard", "RSAToken", "PasswordReset", - "PageView", - "LastLogin", "Message", "Order", "OrderNote", "OrderQualityCheck", "OrderLine" - , - "Product", "ProductDetail", "ProductReview", "ProductPhoto", - "ProductWebFeature", "Supplier", - "SupplierLogo", "SupplierInfo", "CustomerInfo", "Computer", "ComputerDetail", - "Driver", - "License", - }; - - var notExpectedMonsterSets = new[] - { - "ProductPageView", "BackOrderLine", "DiscontinuedProduct", - }; - - var properties = new HashSet(typeof(MonsterModel).GetProperties().Select(p => p.Name)); - - foreach (var expected in expectedMonsterSets) - { - Assert.True(properties.Contains(expected), String.Format("No DbSet property found for {0}", expected)); - } - - foreach (var notExpected in notExpectedMonsterSets) - { - Assert.False( - properties.Contains(notExpected), - String.Format("Found unexpected DbSet property for {0}", notExpected)); - } - } - - [Fact] - public void CSharp_DbContext_template_creates_a_derived_class_for_derived_types_in_the_model() - { - Assert.True(typeof(CurrentEmployeeMf).BaseType == typeof(EmployeeMf)); - } - - [Fact] - public void CSharp_DbContext_template_can_create_private_non_virtual_function_import() - { - Assert.True(typeof(MonsterModel).GetMethod("FunctionImport1", MemberBindingFlags).IsPrivate); - Assert.False(typeof(MonsterModel).GetMethod("FunctionImport1", MemberBindingFlags).IsVirtual); - } - - [Fact] - public void CSharp_DbContext_template_can_create_function_import_with_specific_method_access() - { - Assert.True( - typeof(MonsterModel).GetMethod("FunctionImport2", MemberBindingFlags, null, new Type[0], null). - IsAssembly); - Assert.True( - typeof(MonsterModel).GetMethod( - "FunctionImport2", MemberBindingFlags, null, - new[] { typeof(MergeOption) }, null).IsAssembly); - } - - [Fact] - public void CSharp_DbContext_template_creates_virtual_function_imports() - { - Assert.True( - typeof(AdvancedPatternsModelFirstContext).GetMethod( - "AllOfficesStoredProc", MemberBindingFlags, null, - new Type[0], null).IsVirtual); - Assert.True( - typeof(AdvancedPatternsModelFirstContext).GetMethod( - "AllOfficesStoredProc", MemberBindingFlags, null, - new[] { typeof(MergeOption) }, null).IsVirtual); - } - - [Fact] - public void CSharp_DbContext_template_can_create_nullable_prop() - { - Assert.True( - typeof(CurrentEmployeeMf).GetProperty("LeaveBalance", MemberBindingFlags).PropertyType == - typeof(decimal?)); - } - - [Fact] - public void CSharp_DbContext_template_can_create_nullable_prop_on_a_complex_type() - { - Assert.True(typeof(SiteInfoMf).GetProperty("Zone", MemberBindingFlags).PropertyType == typeof(int?)); - } - - #endregion - - #region Code First mode - - [Fact] - public void Template_generated_context_throws_when_used_in_Code_First_mode() - { - using ( - var context = - new AdvancedPatternsModelFirstContext(SimpleConnectionString("AdvancedPatternsModelFirstContext"))) - { - Assert.Equal( - new UnintentionalCodeFirstException().Message, - Assert.Throws( - () => context.Database.Initialize(force: false)).Message); - } - } - - #endregion - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace ProductivityApiTests +{ + using System; + using System.Collections.Generic; + using System.Data.Entity; + using System.Data.Entity.Core.Objects; + using System.Data.Entity.Infrastructure; + using System.Linq; + using System.Reflection; + using System.Transactions; + using Another.Place; + using FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns; + using FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel; + using Xunit; + using Xunit.Extensions; + + /// + /// Tests for context/entity classes generated from productivity T4 templates. + /// + /// The infrastructure for generating code from the T4 templates at build time does not yet work + /// in the DataSvc branch/Productivity project. We will revisit this later, but for now the + /// process for making changes to the templates is as follows: + /// 1. Change the templates in “ndp\fx\src\DataEntityDesign\Design\T4Templates” + /// 2. Run ProcessTemplates.bat from the command line while in the + /// “src\qa\devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityFunctionalTests\ProductivityApi\TemplateModels” + /// directory. This will copy the source templates into the functional test project with appropriate names + /// and will replace the Model.edmx marker in each template with a path to the schema to use. + /// 3. Use Visual Studio to “Transform All Templates”. For example, click the icon at the top of the Solution + /// Explorer window while something in the FunctionalTests project is selected. + /// + public class TemplateTests : FunctionalTestBase + { + #region Infrastructure/setup + + private const BindingFlags MemberBindingFlags = + BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; + + static TemplateTests() + { + InitializeModelFirstDatabases(); + } + + #endregion + + #region Simple tests that the context and entities works + + private const string Building18Id = "18181818-1818-1818-1818-181818181818"; + + [Fact] + public void Read_and_write_using_AdvancedPatternsModelFirst_created_from_T4_template() + { + var building18 = CreateBuilding(); + + using (new TransactionScope()) + { + using (var context = new AdvancedPatternsModelFirstContext()) + { + context.Buildings.Add(building18); + + var foundBuilding = context.Buildings.Find(new Guid(Building18Id)); + Assert.Equal("Building 18", foundBuilding.Name); + + context.SaveChanges(); + } + + using (var context = new AdvancedPatternsModelFirstContext()) + { + var foundBuilding = context.Buildings.Find(new Guid(Building18Id)); + Assert.Equal("Building 18", foundBuilding.Name); + Assert.Equal(3, context.Entry(foundBuilding).Collection(b => b.Offices).Query().Count()); + + var arthursOffice = context.Offices.Single(o => o.Number == "1/1125"); + Assert.Same(foundBuilding, arthursOffice.GetBuilding()); + } + } + } + + private static BuildingMf CreateBuilding() + { + var building18 = new BuildingMf( + new Guid(Building18Id), "Building 18", -1000000m, + new AddressMf("Across From 25", "Redmond", "WA", "98052", 7, "70's")); + + foreach (var office in new[] + { + new OfficeMf + { + Number = "1/1125" + }, + new OfficeMf + { + Number = "1/1120" + }, + new OfficeMf + { + Number = "1/1123" + }, + }) + { + building18.Offices.Add(office); + } + + return building18; + } + + [Fact] + [AutoRollback] + public void Read_and_write_using_MonsterModel_created_from_T4_template() + { + int orderId; + int? customerId; + + using (var context = new MonsterModel()) + { + var entry = context.Entry(CreateOrder()); + entry.State = EntityState.Added; + + context.SaveChanges(); + + orderId = entry.Entity.OrderId; + customerId = entry.Entity.CustomerId; + } + + using (var context = new MonsterModel()) + { + var order = context.Order.Include(o => o.Customer).Single(o => o.CustomerId == customerId); + + Assert.Equal(orderId, order.OrderId); + Assert.True(order.Customer.Orders.Contains(order)); + } + } + + private static OrderMm CreateOrder() + { + return new OrderMm + { + OrderId = -1, + Customer = + new CustomerMm + { + CustomerId = -1, + Name = "Jim Lathrop", + ContactInfo = + new ContactDetailsMm + { + Email = "jil@newmonics.com", + HomePhone = + new PhoneMm + { + PhoneNumber = "555-5555-551", + Extension = "x555", + PhoneType = PhoneTypeMm.Cell + }, + WorkPhone = + new PhoneMm + { + PhoneNumber = "555-5555-552", + Extension = "x555", + PhoneType = PhoneTypeMm.Land + }, + MobilePhone = + new PhoneMm + { + PhoneNumber = "555-5555-553", + Extension = "x555", + PhoneType = PhoneTypeMm.Satellite + }, + }, + Auditing = + new AuditInfoMm + { + ModifiedBy = "barney", + ModifiedDate = DateTime.Now, + Concurrency = + new ConcurrencyInfoMm + { + QueriedDateTime = DateTime.Now, + Token = "1" + }, + }, + }, + Concurrency = new ConcurrencyInfoMm + { + QueriedDateTime = DateTime.Now, + Token = "1" + }, + }; + } + + #endregion + + #region Tests for default container name when using model/database first (Dev11 142609) + + [Fact] + public void Default_container_name_is_set_when_there_is_a_single_container_in_the_model() + { + using (var context = new AdvancedPatternsModelFirstContext()) + { + Assert.Equal( + "AdvancedPatternsModelFirstContext", + ((IObjectContextAdapter)context).ObjectContext.DefaultContainerName); + } + } + + #endregion + + #region Tests for not needing LoadFromAssembly with model/database first (Dev11 142609) + + [Fact] + public void Object_space_types_are_loaded_when_code_drops_down_to_ObjectContext() + { + using (var context = new AdvancedPatternsModelFirstContext()) + { + var objectContext = ((IObjectContextAdapter)context).ObjectContext; + + // The following would previously throw because it requires manual o-space loading + var results = + objectContext.CreateQuery( + "select e.Number from AdvancedPatternsModelFirstContext.Offices as e").ToList(); + + Assert.Equal(4, results.Count); + } + } + + #endregion + + #region Function import tests + + [Fact] + public void Can_read_entities_from_a_stored_proc_mapped_to_a_function_import() + { + using (var context = new AdvancedPatternsModelFirstContext()) + { + var offices = context.AllOfficesStoredProc().ToList(); + + Assert.Equal(4, offices.Count); + Assert.Equal(4, context.Offices.Local.Count); + new List + { + "1/1221", + "1/1223", + "2/1458", + "2/1789" + }.ForEach( + n => offices.Where(o => o.Number == n).Single()); + } + } + + [Fact] + public void Can_read_entities_from_a_stored_proc_mapped_to_a_function_import_with_merge_option() + { + using (var context = new AdvancedPatternsModelFirstContext()) + { + var offices = context.AllOfficesStoredProc(MergeOption.NoTracking).ToList(); + + Assert.Equal(4, offices.Count); + Assert.Equal(0, context.Offices.Local.Count); + new List + { + "1/1221", + "1/1223", + "2/1458", + "2/1789" + }.ForEach( + n => offices.Where(o => o.Number == n).Single()); + } + } + + [Fact] + public void Can_read_entities_from_a_stored_proc_with_parameters_mapped_to_a_function_import() + { + using (var context = new AdvancedPatternsModelFirstContext()) + { + var offices = + context.OfficesInBuildingStoredProc(AdvancedPatternsModelFirstInitializer.KnownBuildingGuid).ToList(); + + Assert.Equal(2, offices.Count); + Assert.Equal(2, context.Offices.Local.Count); + new List + { + "1/1221", + "1/1223" + }.ForEach(n => offices.Where(o => o.Number == n).Single()); + } + } + + [Fact] + public void Can_read_entities_from_a_stored_proc_with_parameters_mapped_to_a_function_import_with_merge_option() + { + using (var context = new AdvancedPatternsModelFirstContext()) + { + var offices = + context.OfficesInBuildingStoredProc( + AdvancedPatternsModelFirstInitializer.KnownBuildingGuid, + MergeOption.NoTracking).ToList(); + + Assert.Equal(2, offices.Count); + Assert.Equal(0, context.Offices.Local.Count); + new List + { + "1/1221", + "1/1223" + }.ForEach(n => offices.Where(o => o.Number == n).Single()); + } + } + + [Fact] + public void Can_read_complex_objects_from_a_stored_proc_mapped_to_a_function_import() + { + using (var context = new AdvancedPatternsModelFirstContext()) + { + var siteInfo = context.AllSiteInfoStoredProc().ToList(); + + Assert.Equal(2, siteInfo.Count); + new List + { + "Clean", + "Contaminated" + }.ForEach( + n => siteInfo.Where(o => o.Environment == n).Single()); + } + } + + [Fact] + public void Can_read_scalar_return_from_a_stored_proc_mapped_to_a_function_import() + { + using (var context = new AdvancedPatternsModelFirstContext()) + { + var employeeIds = + context.EmployeeIdsInOfficeStoredProc( + "1/1221", + AdvancedPatternsModelFirstInitializer.KnownBuildingGuid). + ToList(); + + Assert.Equal(1, employeeIds.Count); + Assert.Equal("Rowan", context.Employees.Find(employeeIds.Single()).FirstName); + } + } + + [Fact] + public void Can_execute_a_stored_proc_that_returns_no_results_mapped_to_a_function_import() + { + using (var context = new AdvancedPatternsModelFirstContext()) + { + var result = context.SkimOffLeaveBalanceStoredProc("Arthur", "Vickers"); + + Assert.Equal(-1, result); + Assert.Equal( + 0M, + context.Set().Where(e => e.FirstName == "Arthur").Single().LeaveBalance); + } + } + + [Fact] + public void Executing_a_stored_proc_mapped_to_a_function_import_honors_append_only_merge_option() + { + using (var context = new AdvancedPatternsModelFirstContext()) + { + // Arrange + var office = context.Offices.Find("1/1221", AdvancedPatternsModelFirstInitializer.KnownBuildingGuid); + context.Entry(office).Property("Description").CurrentValue = "Test"; + + // Act + var offices = context.AllOfficesStoredProc(MergeOption.AppendOnly).ToList(); + + // Verify + Assert.True(context.Entry(office).State == EntityState.Modified); + Assert.True(context.ChangeTracker.Entries().Count() == 4); + } + } + + [Fact] + public void Executing_a_stored_proc_mapped_to_a_function_import_honors_no_tracking_merge_option() + { + using (var context = new AdvancedPatternsModelFirstContext()) + { + // Act + var offices = context.AllOfficesStoredProc(MergeOption.NoTracking).ToList(); + + // Verify + Assert.True(context.ChangeTracker.Entries().Count() == 0); + } + } + + [Fact] + public void Executing_a_stored_proc_mapped_to_a_function_import_with_merge_option_overwrite_changes() + { + using (var context = new AdvancedPatternsModelFirstContext()) + { + // Arrange + var office = context.Offices.Find("1/1221", AdvancedPatternsModelFirstInitializer.KnownBuildingGuid); + context.Entry(office).Property("Description").CurrentValue = "Test"; + + // Act + var offices = context.AllOfficesStoredProc(MergeOption.OverwriteChanges).ToList(); + + // Verify + Assert.True(context.Entry(office).State == EntityState.Unchanged); + Assert.True(context.ChangeTracker.Entries().Count() == 4); + } + } + + [Fact] + public void Executing_a_stored_proc_mapped_to_a_function_import_with_merge_option_preserve_changes() + { + using (var context = new AdvancedPatternsModelFirstContext()) + { + // Arrange + var office1 = context.Offices.Find("1/1221", AdvancedPatternsModelFirstInitializer.KnownBuildingGuid); + var office2 = context.Offices.Find("1/1223", AdvancedPatternsModelFirstInitializer.KnownBuildingGuid); + context.Entry(office2).Property("Description").CurrentValue = "Test"; + + // Act + var offices = context.AllOfficesStoredProc(MergeOption.PreserveChanges).ToList(); + + // Verify + Assert.True(context.Entry(office1).State == EntityState.Unchanged); + Assert.True(context.Entry(office2).State == EntityState.Modified); + Assert.True(context.ChangeTracker.Entries().Count() == 4); + } + } + + #endregion + + #region Tests for specific properties of the generated code + + [Fact] + public void CSharp_DbContext_template_creates_collections_that_are_initialized_with_HashSets() + { + Assert.IsType>(new OrderMm().OrderLines); + } + + [Fact] + public void CSharp_DbContext_template_initializes_complex_properties_on_entities() + { + Assert.NotNull(new CustomerMm().ContactInfo); + } + + [Fact] + public void CSharp_DbContext_template_initializes_complex_properties_on_complex_objects() + { + Assert.NotNull(new CustomerMm().ContactInfo.HomePhone); + } + + [Fact] + public void CSharp_DbContext_template_initializes_default_values() + { + Assert.Equal(1, new OrderLineMm().Quantity); + Assert.Equal("C", new LicenseMm().LicenseClass); + } + + [Fact] + public void CSharp_DbContext_template_initializes_default_values_on_complex_objects() + { + Assert.Equal("None", new PhoneMm().Extension); + } + + [Fact] + public void CSharp_DbContext_template_creates_non_virtual_scalar_and_complex_properties() + { + Assert.False(typeof(CustomerMm).GetProperty("Name").GetGetMethod().IsVirtual); + Assert.False(typeof(CustomerMm).GetProperty("Name").GetSetMethod().IsVirtual); + Assert.False(typeof(CustomerMm).GetProperty("ContactInfo").GetGetMethod().IsVirtual); + Assert.False(typeof(CustomerMm).GetProperty("ContactInfo").GetSetMethod().IsVirtual); + } + + [Fact] + public void CSharp_DbContext_template_creates_virtual_collection_and_reference_navigation_properties() + { + Assert.True(typeof(CustomerMm).GetProperty("Orders").GetGetMethod().IsVirtual); + Assert.True(typeof(CustomerMm).GetProperty("Orders").GetSetMethod().IsVirtual); + Assert.True(typeof(CustomerMm).GetProperty("Info").GetGetMethod().IsVirtual); + Assert.True(typeof(CustomerMm).GetProperty("Info").GetSetMethod().IsVirtual); + } + + [Fact] + public void CSharp_DbContext_template_creates_an_abstract_class_for_abstract_types_in_the_model() + { + Assert.True(typeof(EmployeeMf).IsAbstract); + } + + [Fact] + public void CSharp_DbContext_template_can_create_private_non_virtual_nav_prop() + { + var navProp = typeof(OfficeMf).GetProperty("Building", MemberBindingFlags); + Assert.True(navProp.GetGetMethod(nonPublic: true).IsPrivate); + Assert.False(navProp.GetGetMethod(nonPublic: true).IsVirtual); + Assert.True(navProp.GetSetMethod(nonPublic: true).IsPrivate); + Assert.False(navProp.GetSetMethod(nonPublic: true).IsVirtual); + } + + [Fact] + public void CSharp_DbContext_template_can_create_fully_internal_nav_prop() + { + var navProp = typeof(WorkOrderMf).GetProperty("Employee", MemberBindingFlags); + Assert.True(navProp.GetGetMethod(nonPublic: true).IsAssembly); + Assert.True(navProp.GetGetMethod(nonPublic: true).IsVirtual); + Assert.True(navProp.GetSetMethod(nonPublic: true).IsAssembly); + Assert.True(navProp.GetSetMethod(nonPublic: true).IsVirtual); + } + + [Fact] + public void CSharp_DbContext_template_can_create_nav_prop_with_specific_getter_access() + { + var navProp = typeof(OfficeMf).GetProperty("WhiteBoards", MemberBindingFlags); + Assert.True(navProp.GetGetMethod(nonPublic: true).IsAssembly); + Assert.True(navProp.GetGetMethod(nonPublic: true).IsVirtual); + Assert.True(navProp.GetSetMethod(nonPublic: true).IsPublic); + Assert.True(navProp.GetSetMethod(nonPublic: true).IsVirtual); + } + + [Fact] + public void CSharp_DbContext_template_can_create_nav_prop_with_specific_setter_access() + { + var navProp = typeof(BuildingMf).GetProperty("MailRooms", MemberBindingFlags); + Assert.True(navProp.GetGetMethod(nonPublic: true).IsAssembly); + Assert.True(navProp.GetGetMethod(nonPublic: true).IsVirtual); + Assert.True(navProp.GetSetMethod(nonPublic: true).IsPrivate); + Assert.False(navProp.GetSetMethod(nonPublic: true).IsVirtual); + } + + [Fact] + public void CSharp_DbContext_template_can_create_fully_internal_primitive_prop() + { + var prop = typeof(BuildingMf).GetProperty("Value", MemberBindingFlags); + Assert.True(prop.GetGetMethod(nonPublic: true).IsAssembly); + Assert.True(prop.GetSetMethod(nonPublic: true).IsAssembly); + } + + [Fact] + public void CSharp_DbContext_template_can_create_primitive_prop_with_specific_getter_access() + { + var prop = typeof(EmployeeMf).GetProperty("LastName", MemberBindingFlags); + Assert.True(prop.GetGetMethod(nonPublic: true).IsPrivate); + Assert.True(prop.GetSetMethod(nonPublic: true).IsAssembly); + } + + [Fact] + public void CSharp_DbContext_template_can_create_primitive_prop_with_specific_setter_access() + { + var prop = typeof(EmployeeMf).GetProperty("FirstName", MemberBindingFlags); + Assert.True(prop.GetGetMethod(nonPublic: true).IsPublic); + Assert.True(prop.GetSetMethod(nonPublic: true).IsPrivate); + } + + [Fact] + public void CSharp_DbContext_template_can_create_fully_internal_primitive_prop_on_a_complex_type() + { + var prop = typeof(AddressMf).GetProperty("State", MemberBindingFlags); + Assert.True(prop.GetGetMethod(nonPublic: true).IsAssembly); + Assert.True(prop.GetSetMethod(nonPublic: true).IsAssembly); + } + + [Fact] + public void CSharp_DbContext_template_can_create_primitive_prop_on_a_complex_type_with_specific_getter_access() + { + var prop = typeof(AddressMf).GetProperty("City", MemberBindingFlags); + Assert.True(prop.GetGetMethod(nonPublic: true).IsPrivate); + Assert.True(prop.GetSetMethod(nonPublic: true).IsPublic); + } + + [Fact] + public void CSharp_DbContext_template_can_create_primitive_prop_on_a_complex_type_with_specific_setter_access() + { + var prop = typeof(AddressMf).GetProperty("ZipCode", MemberBindingFlags); + Assert.True(prop.GetGetMethod(nonPublic: true).IsAssembly); + Assert.True(prop.GetSetMethod(nonPublic: true).IsPrivate); + } + + [Fact] + public void CSharp_DbContext_template_can_create_complex_prop_with_different_getter_and_setter_access() + { + var prop = typeof(BuildingMf).GetProperty("Address", MemberBindingFlags); + Assert.True(prop.GetGetMethod(nonPublic: true).IsAssembly); + Assert.True(prop.GetSetMethod(nonPublic: true).IsPrivate); + } + + [Fact] + public void + CSharp_DbContext_template_can_create_complex_prop_on_a_complex_type_with_different_getter_and_setter_access() + { + var prop = typeof(AddressMf).GetProperty("SiteInfo", MemberBindingFlags); + Assert.True(prop.GetGetMethod(nonPublic: true).IsAssembly); + Assert.True(prop.GetSetMethod(nonPublic: true).IsPrivate); + } + + [Fact] + public void CSharp_DbContext_template_can_create_non_public_DbSet_property() + { + var prop = typeof(AdvancedPatternsModelFirstContext).GetProperty("MailRooms", MemberBindingFlags); + Assert.True(prop.GetGetMethod(nonPublic: true).IsAssembly); + Assert.True(prop.GetSetMethod(nonPublic: true).IsAssembly); + } + + [Fact] + public void CSharp_DbContext_template_can_create_non_public_complex_type() + { + Assert.True(typeof(SiteInfoMf).IsNotPublic); + } + + [Fact] + public void CSharp_DbContext_template_can_create_non_public_entity_type() + { + Assert.True(typeof(MailRoomMf).IsNotPublic); + } + + [Fact] + public void CSharp_DbContext_template_can_create_non_public_context_type() + { + Assert.True(typeof(AdvancedPatternsModelFirstContext).IsNotPublic); + } + + [Fact] + public void CSharp_DbContext_template_has_lazy_loading_enabled_by_default() + { + using (var context = new MonsterModel()) + { + Assert.True(context.Configuration.LazyLoadingEnabled); + } + } + + [Fact] + public void CSharp_DbContext_template_allows_lazy_loading_to_be_turned_off() + { + using (var context = new AdvancedPatternsModelFirstContext()) + { + Assert.False(context.Configuration.LazyLoadingEnabled); + } + } + + [Fact] + public void CSharp_DbContext_template_creates_sets_for_all_base_types_but_not_derived_types() + { + var expectedMonsterSets = new[] + { + "Customer", "Barcode", "IncorrectScan", "BarcodeDetail", "Complaint", + "Resolution", + "Login", "SuspiciousActivity", "SmartCard", "RSAToken", "PasswordReset", + "PageView", + "LastLogin", "Message", "Order", "OrderNote", "OrderQualityCheck", "OrderLine" + , + "Product", "ProductDetail", "ProductReview", "ProductPhoto", + "ProductWebFeature", "Supplier", + "SupplierLogo", "SupplierInfo", "CustomerInfo", "Computer", "ComputerDetail", + "Driver", + "License", + }; + + var notExpectedMonsterSets = new[] + { + "ProductPageView", "BackOrderLine", "DiscontinuedProduct", + }; + + var properties = new HashSet(typeof(MonsterModel).GetProperties().Select(p => p.Name)); + + foreach (var expected in expectedMonsterSets) + { + Assert.True(properties.Contains(expected), String.Format("No DbSet property found for {0}", expected)); + } + + foreach (var notExpected in notExpectedMonsterSets) + { + Assert.False( + properties.Contains(notExpected), + String.Format("Found unexpected DbSet property for {0}", notExpected)); + } + } + + [Fact] + public void CSharp_DbContext_template_creates_a_derived_class_for_derived_types_in_the_model() + { + Assert.True(typeof(CurrentEmployeeMf).BaseType == typeof(EmployeeMf)); + } + + [Fact] + public void CSharp_DbContext_template_can_create_private_non_virtual_function_import() + { + Assert.True(typeof(MonsterModel).GetMethod("FunctionImport1", MemberBindingFlags).IsPrivate); + Assert.False(typeof(MonsterModel).GetMethod("FunctionImport1", MemberBindingFlags).IsVirtual); + } + + [Fact] + public void CSharp_DbContext_template_can_create_function_import_with_specific_method_access() + { + Assert.True( + typeof(MonsterModel).GetMethod("FunctionImport2", MemberBindingFlags, null, new Type[0], null). + IsAssembly); + Assert.True( + typeof(MonsterModel).GetMethod( + "FunctionImport2", MemberBindingFlags, null, + new[] { typeof(MergeOption) }, null).IsAssembly); + } + + [Fact] + public void CSharp_DbContext_template_creates_virtual_function_imports() + { + Assert.True( + typeof(AdvancedPatternsModelFirstContext).GetMethod( + "AllOfficesStoredProc", MemberBindingFlags, null, + new Type[0], null).IsVirtual); + Assert.True( + typeof(AdvancedPatternsModelFirstContext).GetMethod( + "AllOfficesStoredProc", MemberBindingFlags, null, + new[] { typeof(MergeOption) }, null).IsVirtual); + } + + [Fact] + public void CSharp_DbContext_template_can_create_nullable_prop() + { + Assert.True( + typeof(CurrentEmployeeMf).GetProperty("LeaveBalance", MemberBindingFlags).PropertyType == + typeof(decimal?)); + } + + [Fact] + public void CSharp_DbContext_template_can_create_nullable_prop_on_a_complex_type() + { + Assert.True(typeof(SiteInfoMf).GetProperty("Zone", MemberBindingFlags).PropertyType == typeof(int?)); + } + + #endregion + + #region Code First mode + + [Fact] + public void Template_generated_context_throws_when_used_in_Code_First_mode() + { + using ( + var context = + new AdvancedPatternsModelFirstContext(SimpleConnectionString("AdvancedPatternsModelFirstContext"))) + { + Assert.Equal( + new UnintentionalCodeFirstException().Message, + Assert.Throws( + () => context.Database.Initialize(force: false)).Message); + } + } + + #endregion + } +} diff --git a/test/EntityFramework/FunctionalTests.Transitional/Properties/InternalsVisibleTo.cs b/test/EntityFramework/FunctionalTests.Transitional/Properties/InternalsVisibleTo.cs new file mode 100644 index 00000000..99d27261 --- /dev/null +++ b/test/EntityFramework/FunctionalTests.Transitional/Properties/InternalsVisibleTo.cs @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System.Runtime.CompilerServices; + +[assembly: + InternalsVisibleTo( + "EntityFramework.FunctionalTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293" + )] \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/Query/LinqToEntities/EnumTests.cs b/test/EntityFramework/FunctionalTests.Transitional/Query/LinqToEntities/EnumTests.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/Query/LinqToEntities/EnumTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/Query/LinqToEntities/EnumTests.cs diff --git a/test/EntityFramework/FunctionalTests/Query/ModelDefinedFunctionTests.cs b/test/EntityFramework/FunctionalTests.Transitional/Query/ModelDefinedFunctionTests.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/Query/ModelDefinedFunctionTests.cs rename to test/EntityFramework/FunctionalTests.Transitional/Query/ModelDefinedFunctionTests.cs index 92c8f6c0..6562c81b 100644 --- a/test/EntityFramework/FunctionalTests/Query/ModelDefinedFunctionTests.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Query/ModelDefinedFunctionTests.cs @@ -1,682 +1,682 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Query -{ - using System.Data.Entity.Core; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.Resources; - using Xunit; - - public class ModelDefinedFunctionTests : FunctionalTestBase - { - private static readonly MetadataWorkspace workspace = QueryTestHelpers.CreateMetadataWorkspace( - ProductModel.csdlWithFunctions, ProductModel.ssdl, ProductModel.msl); - - [Fact] - public void Exception_thrown_for_function_with_no_body() - { - var query = "ProductModel.F_NoBody()"; - var expectedExceptionMessage = Strings.Cqt_UDF_FunctionHasNoDefinition("ProductModel.F_NoBody()"); - - QueryTestHelpers.VerifyThrows(query, workspace, expectedExceptionMessage); - } - - [Fact] - public void Exception_thrown_if_invalid_parameter_passed_to_function() - { - var query = "ProductModel.F_I(10)"; - var expectedExceptionMessage = Strings.Cqt_UDF_FunctionDefinitionResultTypeMismatch( - "Edm.Int32", "ProductModel.F_I", "Edm.Int16"); - - QueryTestHelpers.VerifyThrows(query, workspace, expectedExceptionMessage); - } - - [Fact] - public void Project_function_referencing_other_functions() - { - var query = "ProductModel.F_A() - ProductModel.F_B() - ProductModel.F_C()"; - var expectedSql = - @"SELECT -((1 - (1 + 2)) - 1) - (1 + 2) AS [C1] -FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Function_that_takes_itself_as_argument() - { - var query = "ProductModel.F_J(ProductModel.F_J(ProductModel.F_J(1)))"; - var expectedSql = - @"SELECT -1 AS [C1] -FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Exception_thrown_for_function_with_direct_reference_to_itself_in_definition() - { - var query = "ProductModel.F_D()"; - var expectedExceptionMessage = Strings.Cqt_UDF_FunctionDefinitionWithCircularReference("ProductModel.F_D"); - - QueryTestHelpers.VerifyThrows(query, workspace, expectedExceptionMessage); - } - - [Fact] - public void Exception_thrown_for_function_with_indirect_reference_to_itself_in_definition() - { - var query1 = "ProductModel.F_E()"; - var expectedExceptionMessage1 = Strings.Cqt_UDF_FunctionDefinitionWithCircularReference("ProductModel.F_E"); - - QueryTestHelpers.VerifyThrows(query1, workspace, expectedExceptionMessage1); - - var query2 = "ProductModel.F_F()"; - var expectedExceptionMessage2 = Strings.Cqt_UDF_FunctionDefinitionWithCircularReference("ProductModel.F_F"); - - QueryTestHelpers.VerifyThrows(query2, workspace, expectedExceptionMessage2); - } - - [Fact] - public void Exception_thrown_for_function_that_references_inline_function_in_its_body() - { - var query = - @"using ProductModel; -function F_H() as (1) -F_G()"; - var expectedExceptionMessage = Strings.CannotResolveNameToTypeOrFunction("F_H") + " Near simple identifier, line 3, column 7."; - - QueryTestHelpers.VerifyThrows(query, workspace, expectedExceptionMessage); - } - - [Fact] - public void Function_returning_scalar() - { - var query = "ProductModel.F_Ret_ST() + 11"; - var expectedSql = - @"SELECT -[GroupBy1].[A1] + 11 AS [C1] -FROM ( SELECT - COUNT(3) AS [A1] - FROM [dbo].[Products] AS [Extent1] - WHERE [Extent1].[Discontinued] IN (0,1) -) AS [GroupBy1]"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Function_returning_collection_of_scalars() - { - var query = "select max(s) as maxs from ProductModel.F_Ret_ColST() as s"; - var expectedSql = - @"SELECT -1 AS [C1], -[GroupBy1].[A1] AS [C2] -FROM ( SELECT - MAX([Filter1].[A1]) AS [A1] - FROM ( SELECT - [Extent1].[ProductID] - 3 AS [A1] - FROM [dbo].[Products] AS [Extent1] - WHERE [Extent1].[Discontinued] IN (0,1) - ) AS [Filter1] -) AS [GroupBy1]"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Function_returning_entity() - { - var query = "ProductModel.F_Ret_ET().ProductID + 12"; - var expectedSql = - @"SELECT -[Limit1].[ProductID] + 12 AS [C1] -FROM ( SELECT 1 AS X ) AS [SingleRowTable1] -LEFT OUTER JOIN (SELECT TOP (1) [Extent1].[ProductID] AS [ProductID] - FROM [dbo].[Products] AS [Extent1] - WHERE [Extent1].[Discontinued] IN (0,1) - ORDER BY [Extent1].[ProductID] ASC ) AS [Limit1] ON 1 = 1"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Function_returning_collection_of_entities() - { - var query = "select p.ProductID + 5 as z from ProductModel.F_Ret_ColET() as p order by p.ProductID DESC"; - var expectedSql = - @"SELECT -[Project1].[ProductID] AS [ProductID], -[Project1].[C1] AS [C1] -FROM ( SELECT TOP (5) - [Extent1].[ProductID] AS [ProductID], - [Extent1].[ProductID] + 5 AS [C1] - FROM [dbo].[Products] AS [Extent1] - WHERE [Extent1].[Discontinued] IN (0,1) - ORDER BY [Extent1].[ProductID] ASC -) AS [Project1] -ORDER BY [Project1].[ProductID] DESC"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Function_returning_complex_type() - { - var query = "ProductModel.F_Ret_CT().City + ' ' + ProductModel.F_Ret_CT().Country"; - var expectedSql = - @"SELECT -[Limit1].[City] + ' ' + [Limit2].[Country] AS [C1] -FROM ( SELECT 1 AS X ) AS [SingleRowTable1] -LEFT OUTER JOIN (SELECT TOP (1) [Extent1].[City] AS [City] - FROM [dbo].[Customers] AS [Extent1] - ORDER BY [Extent1].[CustomerID] ASC ) AS [Limit1] ON 1 = 1 -LEFT OUTER JOIN (SELECT TOP (1) [Extent2].[Country] AS [Country] - FROM [dbo].[Customers] AS [Extent2] - ORDER BY [Extent2].[CustomerID] ASC ) AS [Limit2] ON 1 = 1"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Function_returning_collection_of_complex_types() - { - var query = "select ct from (ProductModel.F_Ret_ColCT()) as ct order by ct.City"; - var expectedSql = - @"SELECT -[Limit1].[C1] AS [C1], -[Limit1].[HomeAddress] AS [HomeAddress], -[Limit1].[City] AS [City], -[Limit1].[Region] AS [Region], -[Limit1].[PostalCode] AS [PostalCode], -[Limit1].[Country] AS [Country] -FROM ( SELECT TOP (5) [Project1].[HomeAddress] AS [HomeAddress], [Project1].[City] AS [City], [Project1].[Region] AS [Region], [Project1].[PostalCode] AS [PostalCode], [Project1].[Country] AS [Country], [Project1].[C1] AS [C1] - FROM ( SELECT - [Extent1].[CustomerID] AS [CustomerID], - [Extent1].[HomeAddress] AS [HomeAddress], - [Extent1].[City] AS [City], - [Extent1].[Region] AS [Region], - [Extent1].[PostalCode] AS [PostalCode], - [Extent1].[Country] AS [Country], - 1 AS [C1] - FROM [dbo].[Customers] AS [Extent1] - ) AS [Project1] - ORDER BY [Project1].[CustomerID] ASC -) AS [Limit1] -ORDER BY [Limit1].[City] ASC"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Function_taking_collection_of_scalars_as_argument_and_returns_collection_of_entities() - { - var query = - "SELECT top(5) et FROM ProductModel.F_In_ColST_Ret_ColET(SELECT VALUE c.CustomerID from ProductContainer.Customers as c) as et"; - - var expectedSql = - @"SELECT TOP (5) -[Project1].[C1] AS [C1], -[Project1].[CustomerID] AS [CustomerID], -[Project1].[HomeAddress] AS [HomeAddress], -[Project1].[City] AS [City], -[Project1].[Region] AS [Region], -[Project1].[PostalCode] AS [PostalCode], -[Project1].[Country] AS [Country] -FROM ( SELECT - [Extent1].[CustomerID] AS [CustomerID], - [Extent1].[HomeAddress] AS [HomeAddress], - [Extent1].[City] AS [City], - [Extent1].[Region] AS [Region], - [Extent1].[PostalCode] AS [PostalCode], - [Extent1].[Country] AS [Country], - 1 AS [C1] - FROM [dbo].[Customers] AS [Extent1] -) AS [Project1] -WHERE EXISTS (SELECT - 1 AS [C1] - FROM [dbo].[Customers] AS [Extent2] - WHERE [Project1].[CustomerID] = [Extent2].[CustomerID] -)"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Function_taking_collection_of_complex_types_as_argument_and_returns_a_scalar() - { - var query = "ProductModel.F_In_ColCT_Ret_ST(select value c.Address from ProductContainer.Customers as c)"; - - var expectedSql = - @"SELECT -[GroupBy1].[A1] AS [C1] -FROM ( SELECT - MIN([Extent1].[City]) AS [A1] - FROM [dbo].[Customers] AS [Extent1] - WHERE [Extent1].[Country] = 'Mexico' -) AS [GroupBy1]"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Function_taking_collection_of_entities_as_argument_and_returns_collection_of_entities() - { - var query = "select top(5) et FROM ProductModel.F_In_ColET_Ret_ColET(select value c from ProductContainer.Customers as c) as et"; - - var expectedSql = - @"SELECT -[Limit1].[C1] AS [C1], -[Limit1].[CustomerID] AS [CustomerID], -[Limit1].[HomeAddress] AS [HomeAddress], -[Limit1].[City] AS [City], -[Limit1].[Region] AS [Region], -[Limit1].[PostalCode] AS [PostalCode], -[Limit1].[Country] AS [Country] -FROM ( SELECT TOP (5) - [Extent1].[CustomerID] AS [CustomerID], - [Extent1].[HomeAddress] AS [HomeAddress], - [Extent1].[City] AS [City], - [Extent1].[Region] AS [Region], - [Extent1].[PostalCode] AS [PostalCode], - [Extent1].[Country] AS [Country], - 1 AS [C1] - FROM [dbo].[Customers] AS [Extent1] - WHERE [Extent1].[Country] = 'Mexico' -) AS [Limit1]"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Function_taking_collection_of_complex_types_as_argument_and_returns_collection_of_complex_types() - { - var query = - "SELECT TOP(5) ct FROM ProductModel.F_In_ColCT_Ret_ColCT(select value c.Address from ProductContainer.Customers as c) as ct"; - - var expectedSql = - @"SELECT -[Limit1].[C1] AS [C1], -[Limit1].[HomeAddress] AS [HomeAddress], -[Limit1].[City] AS [City], -[Limit1].[Region] AS [Region], -[Limit1].[PostalCode] AS [PostalCode], -[Limit1].[Country] AS [Country] -FROM ( SELECT TOP (5) - [Extent1].[HomeAddress] AS [HomeAddress], - [Extent1].[City] AS [City], - [Extent1].[Region] AS [Region], - [Extent1].[PostalCode] AS [PostalCode], - [Extent1].[Country] AS [Country], - 1 AS [C1] - FROM [dbo].[Customers] AS [Extent1] - WHERE [Extent1].[Country] = 'Mexico' -) AS [Limit1]"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Function_taking_collection_of_scalars_as_argument_and_returns_collection_of_scalars() - { - var query = - "SELECT top(5) s FROM ProductModel.F_In_ColST_Ret_ColST(SELECT VALUE c.CustomerID from ProductContainer.Customers as c) as s"; - - var expectedSql = - @"SELECT TOP (5) -1 AS [C1], -[c].[CustomerID] AS [C2] -FROM (SELECT - [Extent1].[CustomerID] AS [CustomerID] - FROM [dbo].[Customers] AS [Extent1] -INTERSECT - SELECT - [UnionAll2].[C1] AS [C1] - FROM (SELECT - [UnionAll1].[C1] AS [C1] - FROM (SELECT - 'a' AS [C1] - FROM ( SELECT 1 AS X ) AS [SingleRowTable1] - UNION ALL - SELECT - 'b' AS [C1] - FROM ( SELECT 1 AS X ) AS [SingleRowTable2]) AS [UnionAll1] - UNION ALL - SELECT - 'c' AS [C1] - FROM ( SELECT 1 AS X ) AS [SingleRowTable3]) AS [UnionAll2]) AS [c]"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Function_taking_row_as_argument_and_returns_a_row() - { - var query = "SELECT TOP(5) ProductModel.F_In_RT_Ret_RT(c) as r FROM (SELECT cust FROM ProductContainer.Customers as cust) as c"; - - var expectedSql = - @"SELECT -[Limit1].[C1] AS [C1], -LEN([Limit1].[CustomerID]) AS [C2], -[Limit1].[City] AS [City], -[Limit1].[HomeAddress] AS [HomeAddress], -[Limit1].[Region] AS [Region], -[Limit1].[PostalCode] AS [PostalCode], -[Limit1].[Country] AS [Country] -FROM ( SELECT TOP (5) - [Extent1].[CustomerID] AS [CustomerID], - [Extent1].[HomeAddress] AS [HomeAddress], - [Extent1].[City] AS [City], - [Extent1].[Region] AS [Region], - [Extent1].[PostalCode] AS [PostalCode], - [Extent1].[Country] AS [Country], - 1 AS [C1] - FROM [dbo].[Customers] AS [Extent1] -) AS [Limit1]"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Function_taking_collection_of_rows_as_argument_and_returns_collection_of_rows() - { - var query = "SELECT TOP(5) r FROM ProductModel.F_In_ColRT_Ret_ColRT(SELECT c FROM ProductContainer.Customers as c) as r"; - - var expectedSql = - @"SELECT -[Limit1].[C1] AS [C1], -[Limit1].[C2] AS [C2], -[Limit1].[City] AS [City], -[Limit1].[HomeAddress] AS [HomeAddress], -[Limit1].[Region] AS [Region], -[Limit1].[PostalCode] AS [PostalCode], -[Limit1].[Country] AS [Country] -FROM ( SELECT TOP (5) - [Extent1].[HomeAddress] AS [HomeAddress], - [Extent1].[City] AS [City], - [Extent1].[Region] AS [Region], - [Extent1].[PostalCode] AS [PostalCode], - [Extent1].[Country] AS [Country], - 1 AS [C1], - LEN([Extent1].[CustomerID]) AS [C2] - FROM [dbo].[Customers] AS [Extent1] -) AS [Limit1]"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Row_field_names_are_ignored_during_function_resolution() - { - var query = - @"select r.A as W, r.B as V from -ProductModel.F_RowFieldNamessIgnored( -{ - row(1 as z, '1' as y), - row(4 as r, '4' as q) -}) as r -order by W"; - - var expectedSql = - @"SELECT -[Project3].[C1] AS [C1], -[Project3].[C2] AS [C2], -[Project3].[C3] AS [C3] -FROM ( SELECT - [UnionAll1].[C1] AS [C1], - (CASE WHEN ([UnionAll1].[C1] = 0) THEN 1 ELSE 4 END) + 1 AS [C2], - CASE WHEN ([UnionAll1].[C1] = 0) THEN '1' ELSE '4' END + '1' AS [C3] - FROM (SELECT - 0 AS [C1] - FROM ( SELECT 1 AS X ) AS [SingleRowTable1] - WHERE ((CASE WHEN (0 = 0) THEN 1 ELSE 4 END) = 1) AND ((CASE WHEN (0 = 0) THEN '1' ELSE '4' END) = '1') - UNION ALL - SELECT - 1 AS [C1] - FROM ( SELECT 1 AS X ) AS [SingleRowTable2] - WHERE ((CASE WHEN (1 = 0) THEN 1 ELSE 4 END) = 1) AND ((CASE WHEN (1 = 0) THEN '1' ELSE '4' END) = '1')) AS [UnionAll1] -) AS [Project3] -ORDER BY [Project3].[C2] ASC"; - - QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); - } - - [Fact] - public void Overload_resolution_for_function_taking_integer_as_argument() - { - var query1 = "ProductModel.F_In_Number(CAST(1 as Byte))"; - var expectedSql1 = "SELECT '16' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); - - var query2 = "ProductModel.F_In_Number(CAST(1 as Int32))"; - var expectedSql2 = "SELECT '32' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); - - var query3 = "ProductModel.F_In_Number(CAST(1 as Int64))"; - var expectedSql3 = "SELECT 'Decimal' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query3, workspace, expectedSql3); - } - - [Fact] - public void Overload_resolution_for_function_taking_two_integers_as_arguments() - { - var query1 = "ProductModel.F_In_ST_1(CAST(1 as Int16), CAST(1 AS Single))"; - var expectedSql1 = "SELECT 1 AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); - - var query2 = "ProductModel.F_In_ST_1(CAST(1 as Int32), CAST(1 AS Int32))"; - var expectedSql2 = "SELECT 2 AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); - - var query3 = "ProductModel.F_In_ST_1(CAST(1 as Single), CAST(1 AS Int16))"; - var expectedSql3 = "SELECT 3 AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query3, workspace, expectedSql3); - - var query4 = "ProductModel.F_In_ST_2(CAST(1 as Byte), CAST(1 AS Int32))"; - var expectedSql4 = "SELECT 1 AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query4, workspace, expectedSql4); - - var query5 = "ProductModel.F_In_ST_2(CAST(1 as Int16), CAST(1 AS Int32))"; - var expectedSql5 = "SELECT 2 AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query5, workspace, expectedSql5); - } - - [Fact] - public void Overload_resolution_for_function_taking_two_integers_as_arguments_negative() - { - var query1 = "ProductModel.F_In_ST_1(CAST(1 as Int16), CAST(1 AS Int32))"; - var expectedExceptionMessage1 = Strings.AmbiguousFunctionArguments - + " Near function 'ProductModel.F_In_ST_1()', line 1, column 14."; - QueryTestHelpers.VerifyThrows(query1, workspace, expectedExceptionMessage1); - - var query2 = "ProductModel.F_In_ST_1(CAST(1 as Int16), CAST(1 AS Int16))"; - var expectedExceptionMessage2 = Strings.AmbiguousFunctionArguments - + " Near function 'ProductModel.F_In_ST_1()', line 1, column 14."; - QueryTestHelpers.VerifyThrows(query2, workspace, expectedExceptionMessage2); - - var query3 = "ProductModel.F_In_ST_1(CAST(1 as Int64), CAST(1 AS Int16))"; - var expectedExceptionMessage3 = Strings.AmbiguousFunctionArguments - + " Near function 'ProductModel.F_In_ST_1()', line 1, column 14."; - QueryTestHelpers.VerifyThrows(query3, workspace, expectedExceptionMessage3); - - var query4 = "ProductModel.F_In_ST_1(CAST(1 as Double), CAST(1 AS Double))"; - var expectedExceptionMessage4 = Strings.NoFunctionOverloadMatch( - "ProductModel", "F_In_ST_1", "F_In_ST_1(Edm.Double, Edm.Double)") + " Near function 'F_In_ST_1()', line 1, column 14."; - - QueryTestHelpers.VerifyThrows(query4, workspace, expectedExceptionMessage4); - } - - [Fact] - public void Overload_resolution_for_function_taking_entity_as_argument() - { - var query1 = "ProductModel.F_In_Entity(anyelement(ProductContainer.Products))"; - var expectedSql1 = "SELECT 'Product' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); - - var query2 = - "ProductModel.F_In_Entity(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p))"; - var expectedSql2 = "SELECT 'DiscontinuedProduct' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); - - var query3 = - "ProductModel.F_In_Entity2(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p))"; - var expectedSql3 = "SELECT 'Product' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query3, workspace, expectedSql3); - } - - [Fact] - public void Overload_resolution_for_function_taking_entity_and_integer_as_arguments() - { - var query1 = "ProductModel.F_In_ProdNumber(anyelement(ProductContainer.Products), CAST(1 as Int32))"; - var expectedSql1 = "SELECT 'Prod-32' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); - - var query2 = "ProductModel.F_In_ProdNumber(anyelement(ProductContainer.Products), CAST(1 as Int16))"; - var expectedSql2 = "SELECT 'Prod-32' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); - - var query3 = - "ProductModel.F_In_ProdNumber(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p), CAST(1 as Int32))"; - var expectedSql3 = "SELECT 'Prod-32' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query3, workspace, expectedSql3); - - var query4 = - "ProductModel.F_In_ProdNumber(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p), CAST(1 as Int16))"; - var expectedSql4 = "SELECT 'DiscProd-16' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query4, workspace, expectedSql4); - - var query5 = - "ProductModel.F_In_ProdNumber2(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p), CAST(1 as Int64))"; - var expectedSql5 = "SELECT 'DiscProd-Decimal' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query5, workspace, expectedSql5); - } - - [Fact] - public void Overload_resolution_for_function_taking_entity_and_integer_as_arguments_negative() - { - var query1 = - "ProductModel.F_In_ProdNumber2(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p), CAST(1 as Int32))"; - var expectedExceptionMessage1 = Strings.AmbiguousFunctionArguments - + " Near function 'ProductModel.F_In_ProdNumber2()', line 1, column 14."; - QueryTestHelpers.VerifyThrows(query1, workspace, expectedExceptionMessage1); - - var query2 = "ProductModel.F_In_ProdNumber2(anyelement(ProductContainer.Products), CAST(1 as Decimal))"; - var expectedExceptionMessage2 = Strings.NoFunctionOverloadMatch( - "ProductModel", "F_In_ProdNumber2", "F_In_ProdNumber2(ProductModel.Product, Edm.Decimal)") - + " Near function 'F_In_ProdNumber2()', line 1, column 14."; - QueryTestHelpers.VerifyThrows(query2, workspace, expectedExceptionMessage2); - } - - [Fact] - public void Overload_resolution_for_function_taking_entity_reference_as_argument() - { - var query1 = "ProductModel.F_In_Ref(REF(anyelement(ProductContainer.Products)))"; - var expectedSql1 = "SELECT 'Ref(Product)' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); - - var query2 = - "ProductModel.F_In_Ref(REF(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p)))"; - var expectedSql2 = "SELECT 'Ref(DiscontinuedProduct)' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); - - var query3 = - "ProductModel.F_In_Ref2(REF(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p)))"; - var expectedSql3 = "SELECT 'Ref(Product)' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query3, workspace, expectedSql3); - } - - [Fact] - public void Overload_resolution_for_function_taking_row_as_argument() - { - var query1 = - "ProductModel.F_In_Row(Row(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p) as x, CAST(1 as Int64) as y))"; - var expectedSql1 = "SELECT 'Row(DiscProd,Decimal)' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); - - var query2 = "ProductModel.F_In_Row(Row(anyelement(ProductContainer.Products) as x, CAST(1 as Int16) as y))"; - var expectedSql2 = "SELECT 'Row(Prod,32)' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); - } - - [Fact] - public void Overload_resolution_for_function_taking_row_as_argument_negative() - { - var query1 = - "ProductModel.F_In_Row(Row(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p) as x, CAST(1 as Int32) as y))"; - var expectedExceptionMessage1 = Strings.AmbiguousFunctionArguments - + " Near function 'ProductModel.F_In_Row()', line 1, column 14."; - QueryTestHelpers.VerifyThrows(query1, workspace, expectedExceptionMessage1); - - var query2 = "ProductModel.F_In_Row(Row(anyelement(ProductContainer.Products) as x, CAST(1 as Decimal) as y))"; - var expectedExceptionMessage2 = Strings.NoFunctionOverloadMatch( - "ProductModel", "F_In_Row", - "F_In_Row(Transient.rowtype[(x,ProductModel.Product(Nullable=True,DefaultValue=)),(y,Edm.Decimal(Nullable=True,DefaultValue=,Precision=,Scale=))])") - + " Near function 'F_In_Row()', line 1, column 14."; - QueryTestHelpers.VerifyThrows(query2, workspace, expectedExceptionMessage2); - } - - [Fact] - public void Overload_resolution_for_function_taking_collection_of_rows_as_argument() - { - var query1 = - "ProductModel.F_In_ColRow({Row(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p) as x, CAST(1 as Int64) as y)})"; - var expectedSql1 = "SELECT 'Col(Row(DiscProd,Decimal))' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); - - var query2 = "ProductModel.F_In_ColRow({Row(anyelement(ProductContainer.Products) as x, CAST(1 as Int16) as y)})"; - var expectedSql2 = "SELECT 'Col(Row(Prod,32))' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); - } - - [Fact] - public void Overload_resolution_for_function_taking_collection_of_rows_as_argument_negative() - { - var query1 = - "ProductModel.F_In_ColRow({Row(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p) as x, CAST(1 as Int32) as y)})"; - var expectedExceptionMessage1 = Strings.AmbiguousFunctionArguments - + " Near function 'ProductModel.F_In_ColRow()', line 1, column 14."; - QueryTestHelpers.VerifyThrows(query1, workspace, expectedExceptionMessage1); - - var query2 = "ProductModel.F_In_ColRow({Row(anyelement(ProductContainer.Products) as x, CAST(1 as Decimal) as y)})"; - var expectedExceptionMessage2 = Strings.NoFunctionOverloadMatch( - "ProductModel", "F_In_ColRow", - "F_In_ColRow(Transient.collection[Transient.rowtype[(x,ProductModel.Product(Nullable=True,DefaultValue=)),(y,Edm.Decimal(Nullable=True,DefaultValue=,Precision=,Scale=))](Nullable=True,DefaultValue=)])") - + " Near function 'F_In_ColRow()', line 1, column 14."; - QueryTestHelpers.VerifyThrows(query2, workspace, expectedExceptionMessage2); - } - - [Fact] - public void Overload_resolution_for_functions_with_nulls_as_arguments() - { - var query1 = "ProductModel.F_In_ProdNumber2(null, CAST(1 as Int64))"; - var expectedSql1 = "SELECT 'DiscProd-Decimal' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); - - var query2 = - "ProductModel.F_In_ProdNumber3(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p), null)"; - var expectedSql2 = "SELECT 'Prod-32' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); - - var query3 = "ProductModel.F_In_Row2(CAST(1 as Int16), null, CAST(1 as Int64))"; - var expectedSql3 = "SELECT 'Decimal-r-Decimal' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; - QueryTestHelpers.VerifyQuery(query3, workspace, expectedSql3); - } - - [Fact] - public void Overload_resolution_for_functions_with_nulls_as_arguments_negative() - { - var query1 = "ProductModel.F_In_Number(null)"; - var expectedExceptionMessage1 = Strings.AmbiguousFunctionArguments - + " Near function 'ProductModel.F_In_Number()', line 1, column 14."; - QueryTestHelpers.VerifyThrows(query1, workspace, expectedExceptionMessage1); - - var query2 = "ProductModel.F_In_ColRow2(CAST(1 as Int16), null, CAST(1 as Int64))"; - var expectedExceptionMessage2 = Strings.NoFunctionOverloadMatch( - "ProductModel", "F_In_ColRow2", "F_In_ColRow2(Edm.Int16, NULL, Edm.Int64)") - + " Near function 'F_In_ColRow2()', line 1, column 14."; - QueryTestHelpers.VerifyThrows(query2, workspace, expectedExceptionMessage2); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Query +{ + using System.Data.Entity.Core; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.Resources; + using Xunit; + + public class ModelDefinedFunctionTests : FunctionalTestBase + { + private static readonly MetadataWorkspace workspace = QueryTestHelpers.CreateMetadataWorkspace( + ProductModel.csdlWithFunctions, ProductModel.ssdl, ProductModel.msl); + + [Fact] + public void Exception_thrown_for_function_with_no_body() + { + var query = "ProductModel.F_NoBody()"; + var expectedExceptionMessage = Strings.Cqt_UDF_FunctionHasNoDefinition("ProductModel.F_NoBody()"); + + QueryTestHelpers.VerifyThrows(query, workspace, expectedExceptionMessage); + } + + [Fact] + public void Exception_thrown_if_invalid_parameter_passed_to_function() + { + var query = "ProductModel.F_I(10)"; + var expectedExceptionMessage = Strings.Cqt_UDF_FunctionDefinitionResultTypeMismatch( + "Edm.Int32", "ProductModel.F_I", "Edm.Int16"); + + QueryTestHelpers.VerifyThrows(query, workspace, expectedExceptionMessage); + } + + [Fact] + public void Project_function_referencing_other_functions() + { + var query = "ProductModel.F_A() - ProductModel.F_B() - ProductModel.F_C()"; + var expectedSql = + @"SELECT +((1 - (1 + 2)) - 1) - (1 + 2) AS [C1] +FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Function_that_takes_itself_as_argument() + { + var query = "ProductModel.F_J(ProductModel.F_J(ProductModel.F_J(1)))"; + var expectedSql = + @"SELECT +1 AS [C1] +FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Exception_thrown_for_function_with_direct_reference_to_itself_in_definition() + { + var query = "ProductModel.F_D()"; + var expectedExceptionMessage = Strings.Cqt_UDF_FunctionDefinitionWithCircularReference("ProductModel.F_D"); + + QueryTestHelpers.VerifyThrows(query, workspace, expectedExceptionMessage); + } + + [Fact] + public void Exception_thrown_for_function_with_indirect_reference_to_itself_in_definition() + { + var query1 = "ProductModel.F_E()"; + var expectedExceptionMessage1 = Strings.Cqt_UDF_FunctionDefinitionWithCircularReference("ProductModel.F_E"); + + QueryTestHelpers.VerifyThrows(query1, workspace, expectedExceptionMessage1); + + var query2 = "ProductModel.F_F()"; + var expectedExceptionMessage2 = Strings.Cqt_UDF_FunctionDefinitionWithCircularReference("ProductModel.F_F"); + + QueryTestHelpers.VerifyThrows(query2, workspace, expectedExceptionMessage2); + } + + [Fact] + public void Exception_thrown_for_function_that_references_inline_function_in_its_body() + { + var query = + @"using ProductModel; +function F_H() as (1) +F_G()"; + var expectedExceptionMessage = Strings.CannotResolveNameToTypeOrFunction("F_H") + " Near simple identifier, line 3, column 7."; + + QueryTestHelpers.VerifyThrows(query, workspace, expectedExceptionMessage); + } + + [Fact] + public void Function_returning_scalar() + { + var query = "ProductModel.F_Ret_ST() + 11"; + var expectedSql = + @"SELECT +[GroupBy1].[A1] + 11 AS [C1] +FROM ( SELECT + COUNT(3) AS [A1] + FROM [dbo].[Products] AS [Extent1] + WHERE [Extent1].[Discontinued] IN (0,1) +) AS [GroupBy1]"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Function_returning_collection_of_scalars() + { + var query = "select max(s) as maxs from ProductModel.F_Ret_ColST() as s"; + var expectedSql = + @"SELECT +1 AS [C1], +[GroupBy1].[A1] AS [C2] +FROM ( SELECT + MAX([Filter1].[A1]) AS [A1] + FROM ( SELECT + [Extent1].[ProductID] - 3 AS [A1] + FROM [dbo].[Products] AS [Extent1] + WHERE [Extent1].[Discontinued] IN (0,1) + ) AS [Filter1] +) AS [GroupBy1]"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Function_returning_entity() + { + var query = "ProductModel.F_Ret_ET().ProductID + 12"; + var expectedSql = + @"SELECT +[Limit1].[ProductID] + 12 AS [C1] +FROM ( SELECT 1 AS X ) AS [SingleRowTable1] +LEFT OUTER JOIN (SELECT TOP (1) [Extent1].[ProductID] AS [ProductID] + FROM [dbo].[Products] AS [Extent1] + WHERE [Extent1].[Discontinued] IN (0,1) + ORDER BY [Extent1].[ProductID] ASC ) AS [Limit1] ON 1 = 1"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Function_returning_collection_of_entities() + { + var query = "select p.ProductID + 5 as z from ProductModel.F_Ret_ColET() as p order by p.ProductID DESC"; + var expectedSql = + @"SELECT +[Project1].[ProductID] AS [ProductID], +[Project1].[C1] AS [C1] +FROM ( SELECT TOP (5) + [Extent1].[ProductID] AS [ProductID], + [Extent1].[ProductID] + 5 AS [C1] + FROM [dbo].[Products] AS [Extent1] + WHERE [Extent1].[Discontinued] IN (0,1) + ORDER BY [Extent1].[ProductID] ASC +) AS [Project1] +ORDER BY [Project1].[ProductID] DESC"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Function_returning_complex_type() + { + var query = "ProductModel.F_Ret_CT().City + ' ' + ProductModel.F_Ret_CT().Country"; + var expectedSql = + @"SELECT +[Limit1].[City] + ' ' + [Limit2].[Country] AS [C1] +FROM ( SELECT 1 AS X ) AS [SingleRowTable1] +LEFT OUTER JOIN (SELECT TOP (1) [Extent1].[City] AS [City] + FROM [dbo].[Customers] AS [Extent1] + ORDER BY [Extent1].[CustomerID] ASC ) AS [Limit1] ON 1 = 1 +LEFT OUTER JOIN (SELECT TOP (1) [Extent2].[Country] AS [Country] + FROM [dbo].[Customers] AS [Extent2] + ORDER BY [Extent2].[CustomerID] ASC ) AS [Limit2] ON 1 = 1"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Function_returning_collection_of_complex_types() + { + var query = "select ct from (ProductModel.F_Ret_ColCT()) as ct order by ct.City"; + var expectedSql = + @"SELECT +[Limit1].[C1] AS [C1], +[Limit1].[HomeAddress] AS [HomeAddress], +[Limit1].[City] AS [City], +[Limit1].[Region] AS [Region], +[Limit1].[PostalCode] AS [PostalCode], +[Limit1].[Country] AS [Country] +FROM ( SELECT TOP (5) [Project1].[HomeAddress] AS [HomeAddress], [Project1].[City] AS [City], [Project1].[Region] AS [Region], [Project1].[PostalCode] AS [PostalCode], [Project1].[Country] AS [Country], [Project1].[C1] AS [C1] + FROM ( SELECT + [Extent1].[CustomerID] AS [CustomerID], + [Extent1].[HomeAddress] AS [HomeAddress], + [Extent1].[City] AS [City], + [Extent1].[Region] AS [Region], + [Extent1].[PostalCode] AS [PostalCode], + [Extent1].[Country] AS [Country], + 1 AS [C1] + FROM [dbo].[Customers] AS [Extent1] + ) AS [Project1] + ORDER BY [Project1].[CustomerID] ASC +) AS [Limit1] +ORDER BY [Limit1].[City] ASC"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Function_taking_collection_of_scalars_as_argument_and_returns_collection_of_entities() + { + var query = + "SELECT top(5) et FROM ProductModel.F_In_ColST_Ret_ColET(SELECT VALUE c.CustomerID from ProductContainer.Customers as c) as et"; + + var expectedSql = + @"SELECT TOP (5) +[Project1].[C1] AS [C1], +[Project1].[CustomerID] AS [CustomerID], +[Project1].[HomeAddress] AS [HomeAddress], +[Project1].[City] AS [City], +[Project1].[Region] AS [Region], +[Project1].[PostalCode] AS [PostalCode], +[Project1].[Country] AS [Country] +FROM ( SELECT + [Extent1].[CustomerID] AS [CustomerID], + [Extent1].[HomeAddress] AS [HomeAddress], + [Extent1].[City] AS [City], + [Extent1].[Region] AS [Region], + [Extent1].[PostalCode] AS [PostalCode], + [Extent1].[Country] AS [Country], + 1 AS [C1] + FROM [dbo].[Customers] AS [Extent1] +) AS [Project1] +WHERE EXISTS (SELECT + 1 AS [C1] + FROM [dbo].[Customers] AS [Extent2] + WHERE [Project1].[CustomerID] = [Extent2].[CustomerID] +)"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Function_taking_collection_of_complex_types_as_argument_and_returns_a_scalar() + { + var query = "ProductModel.F_In_ColCT_Ret_ST(select value c.Address from ProductContainer.Customers as c)"; + + var expectedSql = + @"SELECT +[GroupBy1].[A1] AS [C1] +FROM ( SELECT + MIN([Extent1].[City]) AS [A1] + FROM [dbo].[Customers] AS [Extent1] + WHERE [Extent1].[Country] = 'Mexico' +) AS [GroupBy1]"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Function_taking_collection_of_entities_as_argument_and_returns_collection_of_entities() + { + var query = "select top(5) et FROM ProductModel.F_In_ColET_Ret_ColET(select value c from ProductContainer.Customers as c) as et"; + + var expectedSql = + @"SELECT +[Limit1].[C1] AS [C1], +[Limit1].[CustomerID] AS [CustomerID], +[Limit1].[HomeAddress] AS [HomeAddress], +[Limit1].[City] AS [City], +[Limit1].[Region] AS [Region], +[Limit1].[PostalCode] AS [PostalCode], +[Limit1].[Country] AS [Country] +FROM ( SELECT TOP (5) + [Extent1].[CustomerID] AS [CustomerID], + [Extent1].[HomeAddress] AS [HomeAddress], + [Extent1].[City] AS [City], + [Extent1].[Region] AS [Region], + [Extent1].[PostalCode] AS [PostalCode], + [Extent1].[Country] AS [Country], + 1 AS [C1] + FROM [dbo].[Customers] AS [Extent1] + WHERE [Extent1].[Country] = 'Mexico' +) AS [Limit1]"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Function_taking_collection_of_complex_types_as_argument_and_returns_collection_of_complex_types() + { + var query = + "SELECT TOP(5) ct FROM ProductModel.F_In_ColCT_Ret_ColCT(select value c.Address from ProductContainer.Customers as c) as ct"; + + var expectedSql = + @"SELECT +[Limit1].[C1] AS [C1], +[Limit1].[HomeAddress] AS [HomeAddress], +[Limit1].[City] AS [City], +[Limit1].[Region] AS [Region], +[Limit1].[PostalCode] AS [PostalCode], +[Limit1].[Country] AS [Country] +FROM ( SELECT TOP (5) + [Extent1].[HomeAddress] AS [HomeAddress], + [Extent1].[City] AS [City], + [Extent1].[Region] AS [Region], + [Extent1].[PostalCode] AS [PostalCode], + [Extent1].[Country] AS [Country], + 1 AS [C1] + FROM [dbo].[Customers] AS [Extent1] + WHERE [Extent1].[Country] = 'Mexico' +) AS [Limit1]"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Function_taking_collection_of_scalars_as_argument_and_returns_collection_of_scalars() + { + var query = + "SELECT top(5) s FROM ProductModel.F_In_ColST_Ret_ColST(SELECT VALUE c.CustomerID from ProductContainer.Customers as c) as s"; + + var expectedSql = + @"SELECT TOP (5) +1 AS [C1], +[c].[CustomerID] AS [C2] +FROM (SELECT + [Extent1].[CustomerID] AS [CustomerID] + FROM [dbo].[Customers] AS [Extent1] +INTERSECT + SELECT + [UnionAll2].[C1] AS [C1] + FROM (SELECT + [UnionAll1].[C1] AS [C1] + FROM (SELECT + 'a' AS [C1] + FROM ( SELECT 1 AS X ) AS [SingleRowTable1] + UNION ALL + SELECT + 'b' AS [C1] + FROM ( SELECT 1 AS X ) AS [SingleRowTable2]) AS [UnionAll1] + UNION ALL + SELECT + 'c' AS [C1] + FROM ( SELECT 1 AS X ) AS [SingleRowTable3]) AS [UnionAll2]) AS [c]"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Function_taking_row_as_argument_and_returns_a_row() + { + var query = "SELECT TOP(5) ProductModel.F_In_RT_Ret_RT(c) as r FROM (SELECT cust FROM ProductContainer.Customers as cust) as c"; + + var expectedSql = + @"SELECT +[Limit1].[C1] AS [C1], +LEN([Limit1].[CustomerID]) AS [C2], +[Limit1].[City] AS [City], +[Limit1].[HomeAddress] AS [HomeAddress], +[Limit1].[Region] AS [Region], +[Limit1].[PostalCode] AS [PostalCode], +[Limit1].[Country] AS [Country] +FROM ( SELECT TOP (5) + [Extent1].[CustomerID] AS [CustomerID], + [Extent1].[HomeAddress] AS [HomeAddress], + [Extent1].[City] AS [City], + [Extent1].[Region] AS [Region], + [Extent1].[PostalCode] AS [PostalCode], + [Extent1].[Country] AS [Country], + 1 AS [C1] + FROM [dbo].[Customers] AS [Extent1] +) AS [Limit1]"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Function_taking_collection_of_rows_as_argument_and_returns_collection_of_rows() + { + var query = "SELECT TOP(5) r FROM ProductModel.F_In_ColRT_Ret_ColRT(SELECT c FROM ProductContainer.Customers as c) as r"; + + var expectedSql = + @"SELECT +[Limit1].[C1] AS [C1], +[Limit1].[C2] AS [C2], +[Limit1].[City] AS [City], +[Limit1].[HomeAddress] AS [HomeAddress], +[Limit1].[Region] AS [Region], +[Limit1].[PostalCode] AS [PostalCode], +[Limit1].[Country] AS [Country] +FROM ( SELECT TOP (5) + [Extent1].[HomeAddress] AS [HomeAddress], + [Extent1].[City] AS [City], + [Extent1].[Region] AS [Region], + [Extent1].[PostalCode] AS [PostalCode], + [Extent1].[Country] AS [Country], + 1 AS [C1], + LEN([Extent1].[CustomerID]) AS [C2] + FROM [dbo].[Customers] AS [Extent1] +) AS [Limit1]"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Row_field_names_are_ignored_during_function_resolution() + { + var query = + @"select r.A as W, r.B as V from +ProductModel.F_RowFieldNamessIgnored( +{ + row(1 as z, '1' as y), + row(4 as r, '4' as q) +}) as r +order by W"; + + var expectedSql = + @"SELECT +[Project3].[C1] AS [C1], +[Project3].[C2] AS [C2], +[Project3].[C3] AS [C3] +FROM ( SELECT + [UnionAll1].[C1] AS [C1], + (CASE WHEN ([UnionAll1].[C1] = 0) THEN 1 ELSE 4 END) + 1 AS [C2], + CASE WHEN ([UnionAll1].[C1] = 0) THEN '1' ELSE '4' END + '1' AS [C3] + FROM (SELECT + 0 AS [C1] + FROM ( SELECT 1 AS X ) AS [SingleRowTable1] + WHERE ((CASE WHEN (0 = 0) THEN 1 ELSE 4 END) = 1) AND ((CASE WHEN (0 = 0) THEN '1' ELSE '4' END) = '1') + UNION ALL + SELECT + 1 AS [C1] + FROM ( SELECT 1 AS X ) AS [SingleRowTable2] + WHERE ((CASE WHEN (1 = 0) THEN 1 ELSE 4 END) = 1) AND ((CASE WHEN (1 = 0) THEN '1' ELSE '4' END) = '1')) AS [UnionAll1] +) AS [Project3] +ORDER BY [Project3].[C2] ASC"; + + QueryTestHelpers.VerifyQuery(query, workspace, expectedSql); + } + + [Fact] + public void Overload_resolution_for_function_taking_integer_as_argument() + { + var query1 = "ProductModel.F_In_Number(CAST(1 as Byte))"; + var expectedSql1 = "SELECT '16' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); + + var query2 = "ProductModel.F_In_Number(CAST(1 as Int32))"; + var expectedSql2 = "SELECT '32' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); + + var query3 = "ProductModel.F_In_Number(CAST(1 as Int64))"; + var expectedSql3 = "SELECT 'Decimal' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query3, workspace, expectedSql3); + } + + [Fact] + public void Overload_resolution_for_function_taking_two_integers_as_arguments() + { + var query1 = "ProductModel.F_In_ST_1(CAST(1 as Int16), CAST(1 AS Single))"; + var expectedSql1 = "SELECT 1 AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); + + var query2 = "ProductModel.F_In_ST_1(CAST(1 as Int32), CAST(1 AS Int32))"; + var expectedSql2 = "SELECT 2 AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); + + var query3 = "ProductModel.F_In_ST_1(CAST(1 as Single), CAST(1 AS Int16))"; + var expectedSql3 = "SELECT 3 AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query3, workspace, expectedSql3); + + var query4 = "ProductModel.F_In_ST_2(CAST(1 as Byte), CAST(1 AS Int32))"; + var expectedSql4 = "SELECT 1 AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query4, workspace, expectedSql4); + + var query5 = "ProductModel.F_In_ST_2(CAST(1 as Int16), CAST(1 AS Int32))"; + var expectedSql5 = "SELECT 2 AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query5, workspace, expectedSql5); + } + + [Fact] + public void Overload_resolution_for_function_taking_two_integers_as_arguments_negative() + { + var query1 = "ProductModel.F_In_ST_1(CAST(1 as Int16), CAST(1 AS Int32))"; + var expectedExceptionMessage1 = Strings.AmbiguousFunctionArguments + + " Near function 'ProductModel.F_In_ST_1()', line 1, column 14."; + QueryTestHelpers.VerifyThrows(query1, workspace, expectedExceptionMessage1); + + var query2 = "ProductModel.F_In_ST_1(CAST(1 as Int16), CAST(1 AS Int16))"; + var expectedExceptionMessage2 = Strings.AmbiguousFunctionArguments + + " Near function 'ProductModel.F_In_ST_1()', line 1, column 14."; + QueryTestHelpers.VerifyThrows(query2, workspace, expectedExceptionMessage2); + + var query3 = "ProductModel.F_In_ST_1(CAST(1 as Int64), CAST(1 AS Int16))"; + var expectedExceptionMessage3 = Strings.AmbiguousFunctionArguments + + " Near function 'ProductModel.F_In_ST_1()', line 1, column 14."; + QueryTestHelpers.VerifyThrows(query3, workspace, expectedExceptionMessage3); + + var query4 = "ProductModel.F_In_ST_1(CAST(1 as Double), CAST(1 AS Double))"; + var expectedExceptionMessage4 = Strings.NoFunctionOverloadMatch( + "ProductModel", "F_In_ST_1", "F_In_ST_1(Edm.Double, Edm.Double)") + " Near function 'F_In_ST_1()', line 1, column 14."; + + QueryTestHelpers.VerifyThrows(query4, workspace, expectedExceptionMessage4); + } + + [Fact] + public void Overload_resolution_for_function_taking_entity_as_argument() + { + var query1 = "ProductModel.F_In_Entity(anyelement(ProductContainer.Products))"; + var expectedSql1 = "SELECT 'Product' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); + + var query2 = + "ProductModel.F_In_Entity(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p))"; + var expectedSql2 = "SELECT 'DiscontinuedProduct' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); + + var query3 = + "ProductModel.F_In_Entity2(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p))"; + var expectedSql3 = "SELECT 'Product' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query3, workspace, expectedSql3); + } + + [Fact] + public void Overload_resolution_for_function_taking_entity_and_integer_as_arguments() + { + var query1 = "ProductModel.F_In_ProdNumber(anyelement(ProductContainer.Products), CAST(1 as Int32))"; + var expectedSql1 = "SELECT 'Prod-32' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); + + var query2 = "ProductModel.F_In_ProdNumber(anyelement(ProductContainer.Products), CAST(1 as Int16))"; + var expectedSql2 = "SELECT 'Prod-32' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); + + var query3 = + "ProductModel.F_In_ProdNumber(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p), CAST(1 as Int32))"; + var expectedSql3 = "SELECT 'Prod-32' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query3, workspace, expectedSql3); + + var query4 = + "ProductModel.F_In_ProdNumber(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p), CAST(1 as Int16))"; + var expectedSql4 = "SELECT 'DiscProd-16' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query4, workspace, expectedSql4); + + var query5 = + "ProductModel.F_In_ProdNumber2(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p), CAST(1 as Int64))"; + var expectedSql5 = "SELECT 'DiscProd-Decimal' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query5, workspace, expectedSql5); + } + + [Fact] + public void Overload_resolution_for_function_taking_entity_and_integer_as_arguments_negative() + { + var query1 = + "ProductModel.F_In_ProdNumber2(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p), CAST(1 as Int32))"; + var expectedExceptionMessage1 = Strings.AmbiguousFunctionArguments + + " Near function 'ProductModel.F_In_ProdNumber2()', line 1, column 14."; + QueryTestHelpers.VerifyThrows(query1, workspace, expectedExceptionMessage1); + + var query2 = "ProductModel.F_In_ProdNumber2(anyelement(ProductContainer.Products), CAST(1 as Decimal))"; + var expectedExceptionMessage2 = Strings.NoFunctionOverloadMatch( + "ProductModel", "F_In_ProdNumber2", "F_In_ProdNumber2(ProductModel.Product, Edm.Decimal)") + + " Near function 'F_In_ProdNumber2()', line 1, column 14."; + QueryTestHelpers.VerifyThrows(query2, workspace, expectedExceptionMessage2); + } + + [Fact] + public void Overload_resolution_for_function_taking_entity_reference_as_argument() + { + var query1 = "ProductModel.F_In_Ref(REF(anyelement(ProductContainer.Products)))"; + var expectedSql1 = "SELECT 'Ref(Product)' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); + + var query2 = + "ProductModel.F_In_Ref(REF(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p)))"; + var expectedSql2 = "SELECT 'Ref(DiscontinuedProduct)' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); + + var query3 = + "ProductModel.F_In_Ref2(REF(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p)))"; + var expectedSql3 = "SELECT 'Ref(Product)' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query3, workspace, expectedSql3); + } + + [Fact] + public void Overload_resolution_for_function_taking_row_as_argument() + { + var query1 = + "ProductModel.F_In_Row(Row(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p) as x, CAST(1 as Int64) as y))"; + var expectedSql1 = "SELECT 'Row(DiscProd,Decimal)' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); + + var query2 = "ProductModel.F_In_Row(Row(anyelement(ProductContainer.Products) as x, CAST(1 as Int16) as y))"; + var expectedSql2 = "SELECT 'Row(Prod,32)' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); + } + + [Fact] + public void Overload_resolution_for_function_taking_row_as_argument_negative() + { + var query1 = + "ProductModel.F_In_Row(Row(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p) as x, CAST(1 as Int32) as y))"; + var expectedExceptionMessage1 = Strings.AmbiguousFunctionArguments + + " Near function 'ProductModel.F_In_Row()', line 1, column 14."; + QueryTestHelpers.VerifyThrows(query1, workspace, expectedExceptionMessage1); + + var query2 = "ProductModel.F_In_Row(Row(anyelement(ProductContainer.Products) as x, CAST(1 as Decimal) as y))"; + var expectedExceptionMessage2 = Strings.NoFunctionOverloadMatch( + "ProductModel", "F_In_Row", + "F_In_Row(Transient.rowtype[(x,ProductModel.Product(Nullable=True,DefaultValue=)),(y,Edm.Decimal(Nullable=True,DefaultValue=,Precision=,Scale=))])") + + " Near function 'F_In_Row()', line 1, column 14."; + QueryTestHelpers.VerifyThrows(query2, workspace, expectedExceptionMessage2); + } + + [Fact] + public void Overload_resolution_for_function_taking_collection_of_rows_as_argument() + { + var query1 = + "ProductModel.F_In_ColRow({Row(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p) as x, CAST(1 as Int64) as y)})"; + var expectedSql1 = "SELECT 'Col(Row(DiscProd,Decimal))' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); + + var query2 = "ProductModel.F_In_ColRow({Row(anyelement(ProductContainer.Products) as x, CAST(1 as Int16) as y)})"; + var expectedSql2 = "SELECT 'Col(Row(Prod,32))' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); + } + + [Fact] + public void Overload_resolution_for_function_taking_collection_of_rows_as_argument_negative() + { + var query1 = + "ProductModel.F_In_ColRow({Row(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p) as x, CAST(1 as Int32) as y)})"; + var expectedExceptionMessage1 = Strings.AmbiguousFunctionArguments + + " Near function 'ProductModel.F_In_ColRow()', line 1, column 14."; + QueryTestHelpers.VerifyThrows(query1, workspace, expectedExceptionMessage1); + + var query2 = "ProductModel.F_In_ColRow({Row(anyelement(ProductContainer.Products) as x, CAST(1 as Decimal) as y)})"; + var expectedExceptionMessage2 = Strings.NoFunctionOverloadMatch( + "ProductModel", "F_In_ColRow", + "F_In_ColRow(Transient.collection[Transient.rowtype[(x,ProductModel.Product(Nullable=True,DefaultValue=)),(y,Edm.Decimal(Nullable=True,DefaultValue=,Precision=,Scale=))](Nullable=True,DefaultValue=)])") + + " Near function 'F_In_ColRow()', line 1, column 14."; + QueryTestHelpers.VerifyThrows(query2, workspace, expectedExceptionMessage2); + } + + [Fact] + public void Overload_resolution_for_functions_with_nulls_as_arguments() + { + var query1 = "ProductModel.F_In_ProdNumber2(null, CAST(1 as Int64))"; + var expectedSql1 = "SELECT 'DiscProd-Decimal' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query1, workspace, expectedSql1); + + var query2 = + "ProductModel.F_In_ProdNumber3(anyelement(select value treat(p as ProductModel.DiscontinuedProduct) from ProductContainer.Products as p), null)"; + var expectedSql2 = "SELECT 'Prod-32' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query2, workspace, expectedSql2); + + var query3 = "ProductModel.F_In_Row2(CAST(1 as Int16), null, CAST(1 as Int64))"; + var expectedSql3 = "SELECT 'Decimal-r-Decimal' AS [C1] FROM ( SELECT 1 AS X ) AS [SingleRowTable1]"; + QueryTestHelpers.VerifyQuery(query3, workspace, expectedSql3); + } + + [Fact] + public void Overload_resolution_for_functions_with_nulls_as_arguments_negative() + { + var query1 = "ProductModel.F_In_Number(null)"; + var expectedExceptionMessage1 = Strings.AmbiguousFunctionArguments + + " Near function 'ProductModel.F_In_Number()', line 1, column 14."; + QueryTestHelpers.VerifyThrows(query1, workspace, expectedExceptionMessage1); + + var query2 = "ProductModel.F_In_ColRow2(CAST(1 as Int16), null, CAST(1 as Int64))"; + var expectedExceptionMessage2 = Strings.NoFunctionOverloadMatch( + "ProductModel", "F_In_ColRow2", "F_In_ColRow2(Edm.Int16, NULL, Edm.Int64)") + + " Near function 'F_In_ColRow2()', line 1, column 14."; + QueryTestHelpers.VerifyThrows(query2, workspace, expectedExceptionMessage2); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/Query/ProductModel.cs b/test/EntityFramework/FunctionalTests.Transitional/Query/ProductModel.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/Query/ProductModel.cs rename to test/EntityFramework/FunctionalTests.Transitional/Query/ProductModel.cs index 6c8f32d1..0bd7c619 100644 --- a/test/EntityFramework/FunctionalTests/Query/ProductModel.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/Query/ProductModel.cs @@ -1,695 +1,695 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Query -{ - public static class ProductModel - { - public static readonly string ssdl = - @" - - - - - - - - - - - - - - - - - - - - - - - - - - - -"; - - public static readonly string msl = - @" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"; - - private static readonly string csdlTemplate = - @" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - count(select value 1 from products) - - - {0} -"; - - private static readonly string modelDefinedFunctions = - @" - - - using ProductModel; - F_B() - F_C() - - - - - - using ProductModel; - function F_B() as (1) - function F_A() as (F_B()) - F_A() - - - - - - using ProductModel; - F_B() + 2 - - - - - - using ProductModel; - F_D() + 1 - - - - - - using ProductModel; - F_F() - F_C() - - - - - - using ProductModel; - F_E() + 1 - - - - - - using ProductModel; - F_H() + 1 - - - - - - - CAST(p AS Int16) - - - - - - - p - - - - - - using ProductModel; - Count(select value 3 from ProductContainer.Products as p) - - - - - - using ProductModel; - select value p.ProductID - 3 from ProductContainer.Products as p - - - - - - using ProductModel; - anyelement(select value top(1) p from ProductContainer.Products as p order by p.ProductID) - - - - - - using ProductModel; - select value top(5) p from ProductContainer.Products as p order by p.ProductID - - - - - - - using ProductModel; - Prod - - - - - - - using ProductModel; - Prod - - - - - - using ProductModel; - anyelement(select value top(1) c.Address from ProductContainer.Customers as c order by c.CustomerID) - - - - - - using ProductModel; - select value top(5) c.Address from ProductContainer.Customers as c order by c.CustomerID - - - - - - - using ProductModel; - select value c from ProductContainer.Customers as c where c.CustomerID in IDs - - - - - - - using ProductModel; - select value c.Address from pCustomers as c where c.CustomerID = 'BONAP' - - - - - - - using ProductModel; - Min(select value a.City from pAddresses as a where a.Country = 'Mexico') - - - - - - - using ProductModel; - select value a.City from pAddresses as a where a.Country = 'Mexico' - - - - - - - using ProductModel; - select value c from pCustomers as c where c.Address.Country = 'Mexico' - - - - - - - using ProductModel; - select value p from pAddresses as p where p.Country = 'Mexico' - - - - - - - using ProductModel; - pStrings intersect {'a', 'b', 'c'} - - - - - - - using ProductModel; - pStrings - - - - - - - - - - - - - - - - - - using ProductModel; - row(Length(pRow.Cust.CustomerID) as X, pRow.Cust.Address.City as Y, pRow.Cust.Address as AA) - - - - - - - - - - - - - using ProductModel; - row(p + 3 as X, 'alltypes' as Y) - - - - - - - - - - - - using ProductModel; - pRow.X - - - - - - - - - - - - using ProductModel; - pRow.Y+3 - - - - - - - - - - - - - - - - - - - - - - using ProductModel; - select LENGTH(row.Cust.CustomerID) as X, row.Cust.Address.City as Y, row.Cust.Address as AA - from pRows as row - - - - - - - - - - using ProductModel; - REF(productArg) - - - - - - - - - - using ProductModel; - REF(custArg) - - - - - - - - - - - - - - - - using ProductModel; - select value r from customerRefs as r - - - - - - - - - - - - - - - - - - - - - - select - r.E + 1 as k, - r.F + '1' as l - from pRows as r - where - r.E = 1 and - r.F = '1' - - - - - - - '16' - - - - - - '32' - - - - - - 'Decimal' - - - - - - - - 1 - - - - - - - - 2 - - - - - - - - 3 - - - - - - - 1 - - - - - - - - 2 - - - - - - - 'Product' - - - - - - 'DiscontinuedProduct' - - - - - - 'Product' - - - - - - - - 'Prod-32' - - - - - - - 'DiscProd-16' - - - - - - - 'DiscProd-Decimal' - - - - - - - 'Prod-32' - - - - - - - 'Prod-32' - - - - - - - - - 'Ref(Product)' - - - - - - - - 'Ref(DiscontinuedProduct)' - - - - - - - - 'Ref(Product)' - - - - - - - - - - - - 'Row(DiscProd,Decimal)' - - - - - - - - - - - 'Row(Prod,32)' - - - - - - - - - - - - - '32-r-32' - - - - - - - - - - - - - 'Decimal-r-Decimal' - - - - - - - - - - - - - - 'Col(Row(DiscProd,Decimal))' - - - - - - - - - - - - - 'Col(Row(Prod,32))' - - - - - - - - - - - - - - - 'Decimal-c(r)-Decimal' - - - - - - 20]]> - - "; - - public static readonly string csdl = string.Format(csdlTemplate, ""); - - public static readonly string csdlWithFunctions = string.Format(csdlTemplate, modelDefinedFunctions); - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity.Query +{ + public static class ProductModel + { + public static readonly string ssdl = + @" + + + + + + + + + + + + + + + + + + + + + + + + + + + +"; + + public static readonly string msl = + @" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"; + + private static readonly string csdlTemplate = + @" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + count(select value 1 from products) + + + {0} +"; + + private static readonly string modelDefinedFunctions = + @" + + + using ProductModel; + F_B() - F_C() + + + + + + using ProductModel; + function F_B() as (1) + function F_A() as (F_B()) + F_A() + + + + + + using ProductModel; + F_B() + 2 + + + + + + using ProductModel; + F_D() + 1 + + + + + + using ProductModel; + F_F() - F_C() + + + + + + using ProductModel; + F_E() + 1 + + + + + + using ProductModel; + F_H() + 1 + + + + + + + CAST(p AS Int16) + + + + + + + p + + + + + + using ProductModel; + Count(select value 3 from ProductContainer.Products as p) + + + + + + using ProductModel; + select value p.ProductID - 3 from ProductContainer.Products as p + + + + + + using ProductModel; + anyelement(select value top(1) p from ProductContainer.Products as p order by p.ProductID) + + + + + + using ProductModel; + select value top(5) p from ProductContainer.Products as p order by p.ProductID + + + + + + + using ProductModel; + Prod + + + + + + + using ProductModel; + Prod + + + + + + using ProductModel; + anyelement(select value top(1) c.Address from ProductContainer.Customers as c order by c.CustomerID) + + + + + + using ProductModel; + select value top(5) c.Address from ProductContainer.Customers as c order by c.CustomerID + + + + + + + using ProductModel; + select value c from ProductContainer.Customers as c where c.CustomerID in IDs + + + + + + + using ProductModel; + select value c.Address from pCustomers as c where c.CustomerID = 'BONAP' + + + + + + + using ProductModel; + Min(select value a.City from pAddresses as a where a.Country = 'Mexico') + + + + + + + using ProductModel; + select value a.City from pAddresses as a where a.Country = 'Mexico' + + + + + + + using ProductModel; + select value c from pCustomers as c where c.Address.Country = 'Mexico' + + + + + + + using ProductModel; + select value p from pAddresses as p where p.Country = 'Mexico' + + + + + + + using ProductModel; + pStrings intersect {'a', 'b', 'c'} + + + + + + + using ProductModel; + pStrings + + + + + + + + + + + + + + + + + + using ProductModel; + row(Length(pRow.Cust.CustomerID) as X, pRow.Cust.Address.City as Y, pRow.Cust.Address as AA) + + + + + + + + + + + + + using ProductModel; + row(p + 3 as X, 'alltypes' as Y) + + + + + + + + + + + + using ProductModel; + pRow.X + + + + + + + + + + + + using ProductModel; + pRow.Y+3 + + + + + + + + + + + + + + + + + + + + + + using ProductModel; + select LENGTH(row.Cust.CustomerID) as X, row.Cust.Address.City as Y, row.Cust.Address as AA + from pRows as row + + + + + + + + + + using ProductModel; + REF(productArg) + + + + + + + + + + using ProductModel; + REF(custArg) + + + + + + + + + + + + + + + + using ProductModel; + select value r from customerRefs as r + + + + + + + + + + + + + + + + + + + + + + select + r.E + 1 as k, + r.F + '1' as l + from pRows as r + where + r.E = 1 and + r.F = '1' + + + + + + + '16' + + + + + + '32' + + + + + + 'Decimal' + + + + + + + + 1 + + + + + + + + 2 + + + + + + + + 3 + + + + + + + 1 + + + + + + + + 2 + + + + + + + 'Product' + + + + + + 'DiscontinuedProduct' + + + + + + 'Product' + + + + + + + + 'Prod-32' + + + + + + + 'DiscProd-16' + + + + + + + 'DiscProd-Decimal' + + + + + + + 'Prod-32' + + + + + + + 'Prod-32' + + + + + + + + + 'Ref(Product)' + + + + + + + + 'Ref(DiscontinuedProduct)' + + + + + + + + 'Ref(Product)' + + + + + + + + + + + + 'Row(DiscProd,Decimal)' + + + + + + + + + + + 'Row(Prod,32)' + + + + + + + + + + + + + '32-r-32' + + + + + + + + + + + + + 'Decimal-r-Decimal' + + + + + + + + + + + + + + 'Col(Row(DiscProd,Decimal))' + + + + + + + + + + + + + 'Col(Row(Prod,32))' + + + + + + + + + + + + + + + 'Decimal-c(r)-Decimal' + + + + + + 20]]> + + "; + + public static readonly string csdl = string.Format(csdlTemplate, ""); + + public static readonly string csdlWithFunctions = string.Format(csdlTemplate, modelDefinedFunctions); + } +} diff --git a/test/EntityFramework/FunctionalTests/Query/QueryTestHelpers.cs b/test/EntityFramework/FunctionalTests.Transitional/Query/QueryTestHelpers.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/Query/QueryTestHelpers.cs rename to test/EntityFramework/FunctionalTests.Transitional/Query/QueryTestHelpers.cs diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/AdventureWorksModelBuilder.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/AdventureWorksModelBuilder.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/AdventureWorksModelBuilder.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/AdventureWorksModelBuilder.cs index de94ecff..bfacbe8f 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/AdventureWorksModelBuilder.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/AdventureWorksModelBuilder.cs @@ -1,46 +1,46 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.Infrastructure; - using System.Linq; - using System.Reflection; - - public sealed class AdventureWorksModelBuilder : DbModelBuilder - { - internal DbDatabaseMapping BuildAndValidate(DbProviderInfo providerInfo, params Type[] unignoredTypes) - { - return BuildAndValidate(providerInfo, false, unignoredTypes); - } - - internal void IgnoreAll(params Type[] unignoredTypes) - { - Ignore( - Assembly.GetExecutingAssembly().GetTypes() - .Where( - t => !string.IsNullOrWhiteSpace(t.Namespace) - && t.Namespace.Contains("Model")).Except( - Configurations.GetConfiguredTypes().Union(unignoredTypes))); - } - - internal DbDatabaseMapping BuildAndValidate(DbProviderInfo providerInfo, bool throwOnError, params Type[] unignoredTypes) - { - IgnoreAll(unignoredTypes); - - // Build and clone multiple times to check for idempotency issues. - - Build(providerInfo); - - var cloned = Clone(); - - var databaseMapping = cloned.Build(providerInfo).DatabaseMapping; - - //databaseMapping.ShellEdmx(); - - databaseMapping.AssertValid(throwOnError); - - return databaseMapping; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.Infrastructure; + using System.Linq; + using System.Reflection; + + public sealed class AdventureWorksModelBuilder : DbModelBuilder + { + internal DbDatabaseMapping BuildAndValidate(DbProviderInfo providerInfo, params Type[] unignoredTypes) + { + return BuildAndValidate(providerInfo, false, unignoredTypes); + } + + internal void IgnoreAll(params Type[] unignoredTypes) + { + Ignore( + Assembly.GetExecutingAssembly().GetTypes() + .Where( + t => !string.IsNullOrWhiteSpace(t.Namespace) + && t.Namespace.Contains("Model")).Except( + Configurations.GetConfiguredTypes().Union(unignoredTypes))); + } + + internal DbDatabaseMapping BuildAndValidate(DbProviderInfo providerInfo, bool throwOnError, params Type[] unignoredTypes) + { + IgnoreAll(unignoredTypes); + + // Build and clone multiple times to check for idempotency issues. + + Build(providerInfo); + + var cloned = Clone(); + + var databaseMapping = cloned.Build(providerInfo).DatabaseMapping; + + //databaseMapping.ShellEdmx(); + + databaseMapping.AssertValid(throwOnError); + + return databaseMapping; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/AssemblyResourceLookup.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/AssemblyResourceLookup.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/AssemblyResourceLookup.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/AssemblyResourceLookup.cs index d857b1f8..f07d7ecf 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/AssemblyResourceLookup.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/AssemblyResourceLookup.cs @@ -1,65 +1,65 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Globalization; - using System.Reflection; - using System.Resources; - - /// - /// Locates localized resources for an assembly - /// - public class AssemblyResourceLookup - { - private readonly Assembly _assembly; - private readonly ResourceManager _resourceManager; - - /// - /// Initializes a new instance of the AssemblyResourceLookup class. - /// - /// Assembly that resources belong to - public AssemblyResourceLookup(Assembly assembly) - : this(assembly, ResourceUtilities.BuildResourceManager(assembly)) - { - } - - /// - /// Initializes a new instance of the AssemblyResourceLookup class. - /// - /// Assembly that resources belong to - /// Resource table to lookup strings in - public AssemblyResourceLookup(Assembly assembly, string resourceTable) - : this(assembly, new ResourceManager(resourceTable, assembly)) - { - } - - private AssemblyResourceLookup(Assembly assembly, ResourceManager manager) - { - ExceptionHelpers.CheckArgumentNotNull(assembly, "assembly"); - _assembly = assembly; - _resourceManager = manager; - } - - /// - /// Finds a specific string resource - /// - /// Key of the resource to be located - /// The localized resource value - public string LookupString(string resourceKey) - { - var messageFromResources = _resourceManager.GetString(resourceKey); - if (messageFromResources == null) - { - throw new ArgumentException( - string.Format( - CultureInfo.InvariantCulture, - "No string with key {0} was found in resource table {1} in assembly {2}.", - resourceKey, - _resourceManager.BaseName, - _assembly.FullName)); - } - - return messageFromResources; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Globalization; + using System.Reflection; + using System.Resources; + + /// + /// Locates localized resources for an assembly + /// + public class AssemblyResourceLookup + { + private readonly Assembly _assembly; + private readonly ResourceManager _resourceManager; + + /// + /// Initializes a new instance of the AssemblyResourceLookup class. + /// + /// Assembly that resources belong to + public AssemblyResourceLookup(Assembly assembly) + : this(assembly, ResourceUtilities.BuildResourceManager(assembly)) + { + } + + /// + /// Initializes a new instance of the AssemblyResourceLookup class. + /// + /// Assembly that resources belong to + /// Resource table to lookup strings in + public AssemblyResourceLookup(Assembly assembly, string resourceTable) + : this(assembly, new ResourceManager(resourceTable, assembly)) + { + } + + private AssemblyResourceLookup(Assembly assembly, ResourceManager manager) + { + ExceptionHelpers.CheckArgumentNotNull(assembly, "assembly"); + _assembly = assembly; + _resourceManager = manager; + } + + /// + /// Finds a specific string resource + /// + /// Key of the resource to be located + /// The localized resource value + public string LookupString(string resourceKey) + { + var messageFromResources = _resourceManager.GetString(resourceKey); + if (messageFromResources == null) + { + throw new ArgumentException( + string.Format( + CultureInfo.InvariantCulture, + "No string with key {0} was found in resource table {1} in assembly {2}.", + resourceKey, + _resourceManager.BaseName, + _assembly.FullName)); + } + + return messageFromResources; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/ConnectionEventsTracker.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ConnectionEventsTracker.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestHelpers/ConnectionEventsTracker.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ConnectionEventsTracker.cs index 1611757f..57aae40d 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/ConnectionEventsTracker.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ConnectionEventsTracker.cs @@ -1,87 +1,87 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Data.Common; - using Xunit; - - public class ConnectionEventsTracker - { - private int countOpenClose; - private int countCloseOpen; - private int countOtherConnectionStates; - - public ConnectionEventsTracker(DbConnection connection) - { - if (connection == null) - { - throw new ArgumentException("Cannot track events for a null connection!"); - } - - connection.StateChange += OnStateChange; - } - - /// - /// Verifies the no connection events were fired. - /// - public void VerifyNoConnectionEventsWereFired() - { - Assert.True(countOpenClose == 0); - Assert.True(countCloseOpen == 0); - Assert.True(countOtherConnectionStates == 0); - } - - /// - /// Verifies the connection open and close events were fired. - /// - public void VerifyConnectionOpenCloseEventsWereFired() - { - Assert.True(countCloseOpen == 1); - Assert.True(countOpenClose == 1); - Assert.True(countOtherConnectionStates == 0); - } - - /// - /// Verifies the connection opened event was fired. - /// - public void VerifyConnectionOpenedEventWasFired() - { - Assert.True(countCloseOpen == 1); - Assert.True(countOpenClose == 0); - Assert.True(countOtherConnectionStates == 0); - } - - /// - /// Verifies the connection closed event was fired. - /// - public void VerifyConnectionClosedEventWasFired() - { - Assert.True(countOpenClose == 1); - Assert.True(countCloseOpen == 0); - Assert.True(countOtherConnectionStates == 0); - } - - public void ResetEventCounters() - { - countOpenClose = countCloseOpen = countOtherConnectionStates = 0; - } - - private void OnStateChange(object sender, StateChangeEventArgs args) - { - if (args.OriginalState == ConnectionState.Closed - && args.CurrentState == ConnectionState.Open) - { - countCloseOpen++; - } - else if (args.OriginalState == ConnectionState.Open - && args.CurrentState == ConnectionState.Closed) - { - countOpenClose++; - } - else - { - countOtherConnectionStates++; - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Data.Common; + using Xunit; + + public class ConnectionEventsTracker + { + private int countOpenClose; + private int countCloseOpen; + private int countOtherConnectionStates; + + public ConnectionEventsTracker(DbConnection connection) + { + if (connection == null) + { + throw new ArgumentException("Cannot track events for a null connection!"); + } + + connection.StateChange += OnStateChange; + } + + /// + /// Verifies the no connection events were fired. + /// + public void VerifyNoConnectionEventsWereFired() + { + Assert.True(countOpenClose == 0); + Assert.True(countCloseOpen == 0); + Assert.True(countOtherConnectionStates == 0); + } + + /// + /// Verifies the connection open and close events were fired. + /// + public void VerifyConnectionOpenCloseEventsWereFired() + { + Assert.True(countCloseOpen == 1); + Assert.True(countOpenClose == 1); + Assert.True(countOtherConnectionStates == 0); + } + + /// + /// Verifies the connection opened event was fired. + /// + public void VerifyConnectionOpenedEventWasFired() + { + Assert.True(countCloseOpen == 1); + Assert.True(countOpenClose == 0); + Assert.True(countOtherConnectionStates == 0); + } + + /// + /// Verifies the connection closed event was fired. + /// + public void VerifyConnectionClosedEventWasFired() + { + Assert.True(countOpenClose == 1); + Assert.True(countCloseOpen == 0); + Assert.True(countOtherConnectionStates == 0); + } + + public void ResetEventCounters() + { + countOpenClose = countCloseOpen = countOtherConnectionStates = 0; + } + + private void OnStateChange(object sender, StateChangeEventArgs args) + { + if (args.OriginalState == ConnectionState.Closed + && args.CurrentState == ConnectionState.Open) + { + countCloseOpen++; + } + else if (args.OriginalState == ConnectionState.Open + && args.CurrentState == ConnectionState.Closed) + { + countOpenClose++; + } + else + { + countOtherConnectionStates++; + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/ConstructionStrategies.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ConstructionStrategies.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestHelpers/ConstructionStrategies.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ConstructionStrategies.cs index f4f91f75..3072603f 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/ConstructionStrategies.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ConstructionStrategies.cs @@ -1,103 +1,103 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - /// - /// Describes the format of connection strings used for DbContext construction - /// that takes a connection string - /// - public enum ConnectionStringFormat - { - /// - /// Describes the string passed in to be the Database Name - /// - DatabaseName, - - /// - /// Describes the string passed in to be a Named Connection String - /// - NamedConnectionString, - - /// - /// Describes the string passed in to be a Provider Connection String - /// - ProviderConnectionString - }; - - /// - /// Describes the ways of DbContext construction - /// - public enum DbContextConstructorArgumentType - { - /// - /// DbContext constructed via DbContext Parameterless constructor - /// - Parameterless, - - /// - /// DbContext constructed via DbContext constructor that takes a DbCompiledModel parameter - /// - DbCompiledModel, - - /// - /// DbContext constructed via DbContext constructor that takes a DbConnection parameter - /// - Connection, - - /// - /// DbContext constructed via DbContext constructor that takes a ConnectionString parameter - /// - ConnectionString, - - /// - /// DbContext constructed via DbContext constructor that takes Connection and DbCompiledModel parameters - /// - ConnectionAndDbCompiledModel, - - /// - /// DbContext constructed via DbContext constructor that takes Connection String and DbCompiledModel parameters - /// - ConnectionStringAndDbCompiledModel, - - /// - /// DbContext constructed via DbContext constructor that takes an ObjectContext parameter - /// - ObjectContext, - }; - - /// - /// Enumeration to denote the different types of DbCompiledModel that could be constructed - /// - public enum DbCompiledModelContents - { - /// - /// Empty DbCompiledModel - /// - IsEmpty, - - /// - /// Null DbCompiledModel - /// - IsNull, - - /// - /// DbCompiledModel that defines entities which are a subset of those defined on DbContext - /// - IsSubset, - - /// - /// DbCompiledModel that defines entities which are a superset of those defined on DbContext - /// - IsSuperset, - - /// - /// DbCompiledModel that defines the same entities as those defined on DbContext - /// - Match, - - /// - /// DbCompiledModel that defines entities which are not defined on DbContext - /// - DontMatch, - }; -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + /// + /// Describes the format of connection strings used for DbContext construction + /// that takes a connection string + /// + public enum ConnectionStringFormat + { + /// + /// Describes the string passed in to be the Database Name + /// + DatabaseName, + + /// + /// Describes the string passed in to be a Named Connection String + /// + NamedConnectionString, + + /// + /// Describes the string passed in to be a Provider Connection String + /// + ProviderConnectionString + }; + + /// + /// Describes the ways of DbContext construction + /// + public enum DbContextConstructorArgumentType + { + /// + /// DbContext constructed via DbContext Parameterless constructor + /// + Parameterless, + + /// + /// DbContext constructed via DbContext constructor that takes a DbCompiledModel parameter + /// + DbCompiledModel, + + /// + /// DbContext constructed via DbContext constructor that takes a DbConnection parameter + /// + Connection, + + /// + /// DbContext constructed via DbContext constructor that takes a ConnectionString parameter + /// + ConnectionString, + + /// + /// DbContext constructed via DbContext constructor that takes Connection and DbCompiledModel parameters + /// + ConnectionAndDbCompiledModel, + + /// + /// DbContext constructed via DbContext constructor that takes Connection String and DbCompiledModel parameters + /// + ConnectionStringAndDbCompiledModel, + + /// + /// DbContext constructed via DbContext constructor that takes an ObjectContext parameter + /// + ObjectContext, + }; + + /// + /// Enumeration to denote the different types of DbCompiledModel that could be constructed + /// + public enum DbCompiledModelContents + { + /// + /// Empty DbCompiledModel + /// + IsEmpty, + + /// + /// Null DbCompiledModel + /// + IsNull, + + /// + /// DbCompiledModel that defines entities which are a subset of those defined on DbContext + /// + IsSubset, + + /// + /// DbCompiledModel that defines entities which are a superset of those defined on DbContext + /// + IsSuperset, + + /// + /// DbCompiledModel that defines the same entities as those defined on DbContext + /// + Match, + + /// + /// DbCompiledModel that defines entities which are not defined on DbContext + /// + DontMatch, + }; +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/CsdlToClrAssemblyConverter.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/CsdlToClrAssemblyConverter.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/CsdlToClrAssemblyConverter.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/CsdlToClrAssemblyConverter.cs index 9431c163..ab587ff8 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/CsdlToClrAssemblyConverter.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/CsdlToClrAssemblyConverter.cs @@ -1,433 +1,433 @@ -namespace System.Data.Entity.TestHelpers -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using System.Threading.Tasks; - using System.Data.Entity.Core.Objects.DataClasses; - using System.Diagnostics; - using System.Reflection; - using System.Reflection.Emit; - using System.Xml.Linq; - using System.Data.Entity.Core.Metadata.Edm; - - internal class CsdlToClrAssemblyConverter - { - private static readonly XNamespace _csdlNs = "http://schemas.microsoft.com/ado/2009/11/edm"; - private static readonly XNamespace _csdlMappingTestExtNs = "MappingTestExtension"; - - private static readonly Dictionary _primitiveTypes = new Dictionary() - { - { "Binary", typeof(Byte[]) }, - { "Boolean", typeof(bool) }, - { "Byte", typeof(Byte) }, - { "DateTime", typeof(DateTime) }, - { "DateTimeOffset", typeof(DateTimeOffset) }, - { "Decimal", typeof(Decimal) }, - { "Double", typeof(Double) }, - { "Guid", typeof(Guid) }, - { "Int16", typeof(Int16) }, - { "Int32", typeof(Int32) }, - { "Int64", typeof(Int64) }, - { "SByte", typeof(SByte) }, - { "Single", typeof(Single) }, - { "String", typeof(String) }, - { "Time", typeof(TimeSpan) }, - - // Not valid EDM primitive types but having them is useful for negative OC Mapping tests - { "UInt32", typeof(UInt32) }, - }; - - private static readonly IList _createdAssemblies = new List(); - - static CsdlToClrAssemblyConverter() - { - // This enables resolving types used in the EdmRelationshipAttribute. - // Dynamic, in-memory assemblies are not considered for assembly load. - AppDomain.CurrentDomain.AssemblyResolve += (o, e) => - { - return e.Name == e.RequestingAssembly.FullName ? - e.RequestingAssembly : - _createdAssemblies.SingleOrDefault(a => a.FullName == e.Name); - }; - } - - private readonly XDocument[] _csdlArtifacts; - private readonly bool _isPOCO; - private DynamicAssembly _assembly; - - public CsdlToClrAssemblyConverter(bool isPOCO, params XDocument[] csdlArtifacts) - { - _csdlArtifacts = csdlArtifacts; - _isPOCO = isPOCO; - } - - public Assembly BuildAssembly(string assemblyName) - { - _assembly = new DynamicAssembly(); - - AddSchemaAttribute(); - - foreach (var csdl in _csdlArtifacts) - { - BuildTypes(csdl); - } - - var assemblyBuilder = _assembly.Compile(new AssemblyName(assemblyName)); - - // add the assembly to the list for assembly resolution - _createdAssemblies.Add(assemblyBuilder); - - // EdmRelationshipAttributes require real Clr types so it adds these - // attributes using CustomAttributeBuilder on already created assembly - foreach (var csdl in _csdlArtifacts) - { - AddRelationshipAttributes(csdl, (AssemblyBuilder)assemblyBuilder); - } - - return assemblyBuilder; - } - - private void BuildTypes(XDocument csdl) - { - foreach (var enumTypeDefinition in csdl.Descendants(_csdlNs + "EnumType")) - { - BuildEnumType(enumTypeDefinition); - } - - BuildStructuralTypes( - csdl.Descendants(_csdlNs + "ComplexType") - .Concat(csdl.Descendants(_csdlNs + "EntityType"))); - } - - private void BuildEnumType(XElement enumTypeDefinition) - { - var dynamicEnumType = _assembly.DynamicEnumType(GetFullTypeName(enumTypeDefinition)); - dynamicEnumType.HasUnderlyingType( - _primitiveTypes[(string)enumTypeDefinition.Attribute("UnderlyingType") ?? "Int32"]); - - if (!((bool?)enumTypeDefinition.Attribute(_csdlMappingTestExtNs + "SuppressEdmTypeAttribute") ?? false)) - { - AddEdmTypeAttribute(enumTypeDefinition, dynamicEnumType); - } - - long memberValue = -1; - foreach (var enumMember in enumTypeDefinition.Elements(_csdlNs + "Member")) - { - var definedMemberValue = (int?)enumMember.Attribute("Value"); - memberValue = definedMemberValue.HasValue ? definedMemberValue.Value : memberValue + 1; - dynamicEnumType.HasMember( - (string)enumMember.Attribute("Name"), - Convert.ChangeType(memberValue, dynamicEnumType.UnderlyingType)); - } - } - - private void BuildStructuralTypes(IEnumerable structuralTypeDefinitions) - { - foreach (var structuralTypeDefinition in structuralTypeDefinitions) - { - BuildStructuralType(structuralTypeDefinition); - } - - // properties are built after all types have been registered to - // make navigation properties work - foreach (var structuralTypeDefinition in structuralTypeDefinitions) - { - BuildNavigationProperties(structuralTypeDefinition); - } - } - - private void BuildStructuralType(XElement structuralTypeDefinition) - { - var fullTypeName = GetFullTypeName(structuralTypeDefinition); - - if (_assembly.DynamicTypes.All(t => t.Name != fullTypeName)) - { - var newType = _assembly.DynamicStructuralType(fullTypeName); - - var baseTypeName = (string)structuralTypeDefinition.Attribute("BaseType"); - - if (baseTypeName != null) - { - BuildStructuralType( - structuralTypeDefinition - .Parent - .Elements(_csdlNs + "EntityType") - .Single( - e => (string)e.Attribute("Name") == baseTypeName.Split('.').Last())); - - newType.HasBaseClass(_assembly.DynamicTypes.Single(t => t.Name == baseTypeName)); - } - - if (structuralTypeDefinition.Name.LocalName == "EntityType") - { - AddEdmTypeAttribute(structuralTypeDefinition, newType); - } - else - { - AddEdmTypeAttribute(structuralTypeDefinition, newType); - } - - foreach (var propertyDefinition in structuralTypeDefinition.Elements(_csdlNs + "Property")) - { - var propertyName = (string)propertyDefinition.Attribute("Name"); - var propertyTypeName = (string)propertyDefinition.Attribute("Type"); - var propertyIsNullable = ((bool?)propertyDefinition.Attribute("Nullable") ?? false); - var property = newType.Property(propertyName); - - if ((bool?)propertyDefinition.Attribute(_csdlMappingTestExtNs + "SuppressGetter") ?? false) - { - property.HasGetterAccess(MemberAccess.None); - } - - if ((bool?)propertyDefinition.Attribute(_csdlMappingTestExtNs + "SuppressSetter") ?? false) - { - property.HasSetterAccess(MemberAccess.None); - } - - Type primitiveType; - if(_primitiveTypes.TryGetValue(propertyTypeName, out primitiveType)) - { - if (primitiveType.IsValueType && propertyIsNullable) - { - primitiveType = typeof(Nullable<>).MakeGenericType(primitiveType); - } - - property.HasType(primitiveType); - AddScalarPropertyAttribute(propertyDefinition, property); - } - else - { - var type = ResolveType(propertyTypeName); - - var dynamicEnumType = type as DynamicEnumType; - if(dynamicEnumType != null) - { - property.HasEnumType(dynamicEnumType, propertyIsNullable); - AddScalarPropertyAttribute(propertyDefinition, property); - } - else - { - var dynamicStructuralType = type as DynamicStructuralType; - if (dynamicStructuralType != null) - { - property.HasReferenceType((DynamicStructuralType)dynamicStructuralType); - AddComplexPropertyAttribute(property); - } - else - { - Debug.Assert(type.GetType() is Type); - - var clrType = (Type)type; - property.HasType(clrType); - - if (clrType.IsEnum) - { - AddScalarPropertyAttribute(propertyDefinition, property); - } - else - { - AddComplexPropertyAttribute(property); - } - } - } - } - } - } - } - - private void BuildNavigationProperties(XElement structuralTypeDefinition) - { - foreach (var navigationPropertyDefinition in structuralTypeDefinition.Elements(_csdlNs + "NavigationProperty")) - { - var property = _assembly - .DynamicTypes.OfType() - .Single(t => t.Name == GetFullTypeName(structuralTypeDefinition)) - .Property((string)navigationPropertyDefinition.Attribute("Name")); - - var correspondingAssociationType = - navigationPropertyDefinition - .Document - .Root - .Elements(_csdlNs + "Association") - .Single(at => GetFullTypeName(at) == (string)navigationPropertyDefinition.Attribute("Relationship")); - - var targetEnd = - correspondingAssociationType - .Elements(_csdlNs + "End") - .Single(e => (string)e.Attribute("Role") == (string)navigationPropertyDefinition.Attribute("ToRole")); - - var propertyType = - _assembly - .DynamicTypes.OfType() - .Single(t => t.Name == (string)targetEnd.Attribute("Type")); - - if ((string)targetEnd.Attribute("Multiplicity") == "*") - { - property.HasCollectionType( - _isPOCO ? typeof(ICollection<>) : typeof(EntityCollection<>), - propertyType); - } - else - { - property.HasReferenceType(propertyType); - } - - AddNavigationPropertyAttribute(navigationPropertyDefinition, property); - } - } - - private void AddRelationshipAttributes(XDocument csdl, AssemblyBuilder assemblyBuilder) - { - if (!_isPOCO) - { - var relationshipNamespaceName = GetModelNamespace(csdl.Root); - - foreach (var associationDefinition in csdl.Descendants(_csdlNs + "Association")) - { - var relationshipName = (string)associationDefinition.Attribute("Name"); - string end1Name, end2Name; - Type end1Type, end2Type; - RelationshipMultiplicity end1Multiplicity, end2Multiplicity; - - GetEndDetails( - assemblyBuilder, associationDefinition.Elements(_csdlNs + "End").First(), out end1Name, out end1Multiplicity, - out end1Type); - GetEndDetails( - assemblyBuilder, associationDefinition.Elements(_csdlNs + "End").Last(), out end2Name, out end2Multiplicity, - out end2Type); - - assemblyBuilder.SetCustomAttribute( - new CustomAttributeBuilder( - typeof(EdmRelationshipAttribute).GetConstructors().Single(ci => ci.GetParameters().Length == 8), - new object[] - { - relationshipNamespaceName, relationshipName, end1Name, end1Multiplicity, end1Type, end2Name, - end2Multiplicity, end2Type - })); - } - } - } - - private void GetEndDetails(AssemblyBuilder assemblyBuilder, XElement end, out string endRole, out RelationshipMultiplicity endMultiplicity, out Type endType) - { - Debug.Assert(assemblyBuilder != null, "assemblyBuilder != null"); - Debug.Assert(end != null, "end != null"); - Debug.Assert(end.Name == _csdlNs + "End", "End element expected"); - - endRole = (string)end.Attribute("Role"); - - var multiplicity = (string)end.Attribute("Multiplicity"); - Debug.Assert(multiplicity == "*" || multiplicity == "0..1" || multiplicity == "1"); - endMultiplicity = multiplicity == "*" ? RelationshipMultiplicity.Many : - multiplicity == "1" ? RelationshipMultiplicity.One : - RelationshipMultiplicity.ZeroOrOne; - - endType = assemblyBuilder.GetType((string)end.Attribute("Type")); - } - - private void AddSchemaAttribute() - { - if (!_isPOCO) - { - _assembly.Attributes.Add(new EdmSchemaAttribute()); - } - } - - private void AddEdmTypeAttribute(XElement typeDefinition, DynamicType dynamicType) - where T: EdmTypeAttribute, new() - { - if (!_isPOCO) - { - string typeName, typeNamespace; - GetModelTypeNameAndNamespace(typeDefinition, out typeName, out typeNamespace); - dynamicType.Attributes.Add( - new T() - { - Name = typeName, - NamespaceName = typeNamespace - }); - } - } - - private void AddScalarPropertyAttribute(XElement propertyDefinition, DynamicProperty property) - { - if (!_isPOCO) - { - property.HasAttribute( - new EdmScalarPropertyAttribute() - { - IsNullable = ((bool?)propertyDefinition.Attribute("Nullable") ?? false), - EntityKeyProperty = - propertyDefinition.Parent.Descendants(_csdlNs + "PropertyRef") - .Any( - e => - e.Parent.Name == _csdlNs + "Key" - && (string)e.Attribute("Name") == property.PropertyName) - }); - } - } - - private void AddComplexPropertyAttribute(DynamicProperty property) - { - if (!_isPOCO) - { - property.HasAttribute(new EdmComplexPropertyAttribute()); - } - } - - private void AddNavigationPropertyAttribute(XElement propertyDefinition, DynamicProperty property) - { - if (!_isPOCO) - { - string[] relationship = propertyDefinition.Attribute("Relationship").Value.Split('.'); - - property.HasAttribute( - new EdmRelationshipNavigationPropertyAttribute( - relationship[0], - relationship[1], - (string)propertyDefinition.Attribute("ToRole"))); - } - } - - - private static string GetFullTypeName(XElement typeDefinition) - { - return string.Format( - "{0}.{1}", - (string)GetModelNamespace(typeDefinition), - (string)typeDefinition.Attribute("Name")); - } - - private static string GetModelNamespace(XElement csdlElement) - { - return csdlElement.Document.Root.Attribute("Namespace").Value; - } - - private static void GetModelTypeNameAndNamespace(XElement typeElement, out string typeName, out string typeNamespace) - { - typeName = - (string)typeElement.Attribute(_csdlMappingTestExtNs + "OSpaceTypeName") ?? - (string)typeElement.Attribute("Name"); - - typeNamespace = - (string)typeElement.Attribute(_csdlMappingTestExtNs + "OSpaceTypeNamespace") ?? - GetModelNamespace(typeElement); - } - - private object ResolveType(string typeName) - { - object type; - if((type = _assembly.DynamicTypes.SingleOrDefault(t => t.Name == typeName)) == null) - { - if ((type = _createdAssemblies.SelectMany(a => a.GetTypes()).SingleOrDefault(t => t.FullName == typeName)) == null) - { - throw new InvalidOperationException(string.Format("Cannot resolve type {0}", typeName)); - } - } - - return type; - } - } -} +namespace System.Data.Entity.TestHelpers +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + using System.Data.Entity.Core.Objects.DataClasses; + using System.Diagnostics; + using System.Reflection; + using System.Reflection.Emit; + using System.Xml.Linq; + using System.Data.Entity.Core.Metadata.Edm; + + internal class CsdlToClrAssemblyConverter + { + private static readonly XNamespace _csdlNs = "http://schemas.microsoft.com/ado/2009/11/edm"; + private static readonly XNamespace _csdlMappingTestExtNs = "MappingTestExtension"; + + private static readonly Dictionary _primitiveTypes = new Dictionary() + { + { "Binary", typeof(Byte[]) }, + { "Boolean", typeof(bool) }, + { "Byte", typeof(Byte) }, + { "DateTime", typeof(DateTime) }, + { "DateTimeOffset", typeof(DateTimeOffset) }, + { "Decimal", typeof(Decimal) }, + { "Double", typeof(Double) }, + { "Guid", typeof(Guid) }, + { "Int16", typeof(Int16) }, + { "Int32", typeof(Int32) }, + { "Int64", typeof(Int64) }, + { "SByte", typeof(SByte) }, + { "Single", typeof(Single) }, + { "String", typeof(String) }, + { "Time", typeof(TimeSpan) }, + + // Not valid EDM primitive types but having them is useful for negative OC Mapping tests + { "UInt32", typeof(UInt32) }, + }; + + private static readonly IList _createdAssemblies = new List(); + + static CsdlToClrAssemblyConverter() + { + // This enables resolving types used in the EdmRelationshipAttribute. + // Dynamic, in-memory assemblies are not considered for assembly load. + AppDomain.CurrentDomain.AssemblyResolve += (o, e) => + { + return e.Name == e.RequestingAssembly.FullName ? + e.RequestingAssembly : + _createdAssemblies.SingleOrDefault(a => a.FullName == e.Name); + }; + } + + private readonly XDocument[] _csdlArtifacts; + private readonly bool _isPOCO; + private DynamicAssembly _assembly; + + public CsdlToClrAssemblyConverter(bool isPOCO, params XDocument[] csdlArtifacts) + { + _csdlArtifacts = csdlArtifacts; + _isPOCO = isPOCO; + } + + public Assembly BuildAssembly(string assemblyName) + { + _assembly = new DynamicAssembly(); + + AddSchemaAttribute(); + + foreach (var csdl in _csdlArtifacts) + { + BuildTypes(csdl); + } + + var assemblyBuilder = _assembly.Compile(new AssemblyName(assemblyName)); + + // add the assembly to the list for assembly resolution + _createdAssemblies.Add(assemblyBuilder); + + // EdmRelationshipAttributes require real Clr types so it adds these + // attributes using CustomAttributeBuilder on already created assembly + foreach (var csdl in _csdlArtifacts) + { + AddRelationshipAttributes(csdl, (AssemblyBuilder)assemblyBuilder); + } + + return assemblyBuilder; + } + + private void BuildTypes(XDocument csdl) + { + foreach (var enumTypeDefinition in csdl.Descendants(_csdlNs + "EnumType")) + { + BuildEnumType(enumTypeDefinition); + } + + BuildStructuralTypes( + csdl.Descendants(_csdlNs + "ComplexType") + .Concat(csdl.Descendants(_csdlNs + "EntityType"))); + } + + private void BuildEnumType(XElement enumTypeDefinition) + { + var dynamicEnumType = _assembly.DynamicEnumType(GetFullTypeName(enumTypeDefinition)); + dynamicEnumType.HasUnderlyingType( + _primitiveTypes[(string)enumTypeDefinition.Attribute("UnderlyingType") ?? "Int32"]); + + if (!((bool?)enumTypeDefinition.Attribute(_csdlMappingTestExtNs + "SuppressEdmTypeAttribute") ?? false)) + { + AddEdmTypeAttribute(enumTypeDefinition, dynamicEnumType); + } + + long memberValue = -1; + foreach (var enumMember in enumTypeDefinition.Elements(_csdlNs + "Member")) + { + var definedMemberValue = (int?)enumMember.Attribute("Value"); + memberValue = definedMemberValue.HasValue ? definedMemberValue.Value : memberValue + 1; + dynamicEnumType.HasMember( + (string)enumMember.Attribute("Name"), + Convert.ChangeType(memberValue, dynamicEnumType.UnderlyingType)); + } + } + + private void BuildStructuralTypes(IEnumerable structuralTypeDefinitions) + { + foreach (var structuralTypeDefinition in structuralTypeDefinitions) + { + BuildStructuralType(structuralTypeDefinition); + } + + // properties are built after all types have been registered to + // make navigation properties work + foreach (var structuralTypeDefinition in structuralTypeDefinitions) + { + BuildNavigationProperties(structuralTypeDefinition); + } + } + + private void BuildStructuralType(XElement structuralTypeDefinition) + { + var fullTypeName = GetFullTypeName(structuralTypeDefinition); + + if (_assembly.DynamicTypes.All(t => t.Name != fullTypeName)) + { + var newType = _assembly.DynamicStructuralType(fullTypeName); + + var baseTypeName = (string)structuralTypeDefinition.Attribute("BaseType"); + + if (baseTypeName != null) + { + BuildStructuralType( + structuralTypeDefinition + .Parent + .Elements(_csdlNs + "EntityType") + .Single( + e => (string)e.Attribute("Name") == baseTypeName.Split('.').Last())); + + newType.HasBaseClass(_assembly.DynamicTypes.Single(t => t.Name == baseTypeName)); + } + + if (structuralTypeDefinition.Name.LocalName == "EntityType") + { + AddEdmTypeAttribute(structuralTypeDefinition, newType); + } + else + { + AddEdmTypeAttribute(structuralTypeDefinition, newType); + } + + foreach (var propertyDefinition in structuralTypeDefinition.Elements(_csdlNs + "Property")) + { + var propertyName = (string)propertyDefinition.Attribute("Name"); + var propertyTypeName = (string)propertyDefinition.Attribute("Type"); + var propertyIsNullable = ((bool?)propertyDefinition.Attribute("Nullable") ?? false); + var property = newType.Property(propertyName); + + if ((bool?)propertyDefinition.Attribute(_csdlMappingTestExtNs + "SuppressGetter") ?? false) + { + property.HasGetterAccess(MemberAccess.None); + } + + if ((bool?)propertyDefinition.Attribute(_csdlMappingTestExtNs + "SuppressSetter") ?? false) + { + property.HasSetterAccess(MemberAccess.None); + } + + Type primitiveType; + if(_primitiveTypes.TryGetValue(propertyTypeName, out primitiveType)) + { + if (primitiveType.IsValueType && propertyIsNullable) + { + primitiveType = typeof(Nullable<>).MakeGenericType(primitiveType); + } + + property.HasType(primitiveType); + AddScalarPropertyAttribute(propertyDefinition, property); + } + else + { + var type = ResolveType(propertyTypeName); + + var dynamicEnumType = type as DynamicEnumType; + if(dynamicEnumType != null) + { + property.HasEnumType(dynamicEnumType, propertyIsNullable); + AddScalarPropertyAttribute(propertyDefinition, property); + } + else + { + var dynamicStructuralType = type as DynamicStructuralType; + if (dynamicStructuralType != null) + { + property.HasReferenceType((DynamicStructuralType)dynamicStructuralType); + AddComplexPropertyAttribute(property); + } + else + { + Debug.Assert(type.GetType() is Type); + + var clrType = (Type)type; + property.HasType(clrType); + + if (clrType.IsEnum) + { + AddScalarPropertyAttribute(propertyDefinition, property); + } + else + { + AddComplexPropertyAttribute(property); + } + } + } + } + } + } + } + + private void BuildNavigationProperties(XElement structuralTypeDefinition) + { + foreach (var navigationPropertyDefinition in structuralTypeDefinition.Elements(_csdlNs + "NavigationProperty")) + { + var property = _assembly + .DynamicTypes.OfType() + .Single(t => t.Name == GetFullTypeName(structuralTypeDefinition)) + .Property((string)navigationPropertyDefinition.Attribute("Name")); + + var correspondingAssociationType = + navigationPropertyDefinition + .Document + .Root + .Elements(_csdlNs + "Association") + .Single(at => GetFullTypeName(at) == (string)navigationPropertyDefinition.Attribute("Relationship")); + + var targetEnd = + correspondingAssociationType + .Elements(_csdlNs + "End") + .Single(e => (string)e.Attribute("Role") == (string)navigationPropertyDefinition.Attribute("ToRole")); + + var propertyType = + _assembly + .DynamicTypes.OfType() + .Single(t => t.Name == (string)targetEnd.Attribute("Type")); + + if ((string)targetEnd.Attribute("Multiplicity") == "*") + { + property.HasCollectionType( + _isPOCO ? typeof(ICollection<>) : typeof(EntityCollection<>), + propertyType); + } + else + { + property.HasReferenceType(propertyType); + } + + AddNavigationPropertyAttribute(navigationPropertyDefinition, property); + } + } + + private void AddRelationshipAttributes(XDocument csdl, AssemblyBuilder assemblyBuilder) + { + if (!_isPOCO) + { + var relationshipNamespaceName = GetModelNamespace(csdl.Root); + + foreach (var associationDefinition in csdl.Descendants(_csdlNs + "Association")) + { + var relationshipName = (string)associationDefinition.Attribute("Name"); + string end1Name, end2Name; + Type end1Type, end2Type; + RelationshipMultiplicity end1Multiplicity, end2Multiplicity; + + GetEndDetails( + assemblyBuilder, associationDefinition.Elements(_csdlNs + "End").First(), out end1Name, out end1Multiplicity, + out end1Type); + GetEndDetails( + assemblyBuilder, associationDefinition.Elements(_csdlNs + "End").Last(), out end2Name, out end2Multiplicity, + out end2Type); + + assemblyBuilder.SetCustomAttribute( + new CustomAttributeBuilder( + typeof(EdmRelationshipAttribute).GetConstructors().Single(ci => ci.GetParameters().Length == 8), + new object[] + { + relationshipNamespaceName, relationshipName, end1Name, end1Multiplicity, end1Type, end2Name, + end2Multiplicity, end2Type + })); + } + } + } + + private void GetEndDetails(AssemblyBuilder assemblyBuilder, XElement end, out string endRole, out RelationshipMultiplicity endMultiplicity, out Type endType) + { + Debug.Assert(assemblyBuilder != null, "assemblyBuilder != null"); + Debug.Assert(end != null, "end != null"); + Debug.Assert(end.Name == _csdlNs + "End", "End element expected"); + + endRole = (string)end.Attribute("Role"); + + var multiplicity = (string)end.Attribute("Multiplicity"); + Debug.Assert(multiplicity == "*" || multiplicity == "0..1" || multiplicity == "1"); + endMultiplicity = multiplicity == "*" ? RelationshipMultiplicity.Many : + multiplicity == "1" ? RelationshipMultiplicity.One : + RelationshipMultiplicity.ZeroOrOne; + + endType = assemblyBuilder.GetType((string)end.Attribute("Type")); + } + + private void AddSchemaAttribute() + { + if (!_isPOCO) + { + _assembly.Attributes.Add(new EdmSchemaAttribute()); + } + } + + private void AddEdmTypeAttribute(XElement typeDefinition, DynamicType dynamicType) + where T: EdmTypeAttribute, new() + { + if (!_isPOCO) + { + string typeName, typeNamespace; + GetModelTypeNameAndNamespace(typeDefinition, out typeName, out typeNamespace); + dynamicType.Attributes.Add( + new T() + { + Name = typeName, + NamespaceName = typeNamespace + }); + } + } + + private void AddScalarPropertyAttribute(XElement propertyDefinition, DynamicProperty property) + { + if (!_isPOCO) + { + property.HasAttribute( + new EdmScalarPropertyAttribute() + { + IsNullable = ((bool?)propertyDefinition.Attribute("Nullable") ?? false), + EntityKeyProperty = + propertyDefinition.Parent.Descendants(_csdlNs + "PropertyRef") + .Any( + e => + e.Parent.Name == _csdlNs + "Key" + && (string)e.Attribute("Name") == property.PropertyName) + }); + } + } + + private void AddComplexPropertyAttribute(DynamicProperty property) + { + if (!_isPOCO) + { + property.HasAttribute(new EdmComplexPropertyAttribute()); + } + } + + private void AddNavigationPropertyAttribute(XElement propertyDefinition, DynamicProperty property) + { + if (!_isPOCO) + { + string[] relationship = propertyDefinition.Attribute("Relationship").Value.Split('.'); + + property.HasAttribute( + new EdmRelationshipNavigationPropertyAttribute( + relationship[0], + relationship[1], + (string)propertyDefinition.Attribute("ToRole"))); + } + } + + + private static string GetFullTypeName(XElement typeDefinition) + { + return string.Format( + "{0}.{1}", + (string)GetModelNamespace(typeDefinition), + (string)typeDefinition.Attribute("Name")); + } + + private static string GetModelNamespace(XElement csdlElement) + { + return csdlElement.Document.Root.Attribute("Namespace").Value; + } + + private static void GetModelTypeNameAndNamespace(XElement typeElement, out string typeName, out string typeNamespace) + { + typeName = + (string)typeElement.Attribute(_csdlMappingTestExtNs + "OSpaceTypeName") ?? + (string)typeElement.Attribute("Name"); + + typeNamespace = + (string)typeElement.Attribute(_csdlMappingTestExtNs + "OSpaceTypeNamespace") ?? + GetModelNamespace(typeElement); + } + + private object ResolveType(string typeName) + { + object type; + if((type = _assembly.DynamicTypes.SingleOrDefault(t => t.Name == typeName)) == null) + { + if ((type = _createdAssemblies.SelectMany(a => a.GetTypes()).SingleOrDefault(t => t.FullName == typeName)) == null) + { + throw new InvalidOperationException(string.Format("Cannot resolve type {0}", typeName)); + } + } + + return type; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/DbContextExtensions.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DbContextExtensions.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/DbContextExtensions.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DbContextExtensions.cs index 1e1e57df..1b811d26 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/DbContextExtensions.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DbContextExtensions.cs @@ -1,25 +1,25 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Data.Entity.Migrations; - using System.Data.SqlServerCe; - - public static class DbContextExtensions - { - public static TypeAssertion Assert(this DbContext context) - where TStructuralType : class - { - return new TypeAssertion(context); - } - - public static void IgnoreSpatialTypesOnSqlCe(this DbContext context, DbModelBuilder modelBuilder) - { - if (context.Database.Connection is SqlCeConnection) - { - modelBuilder.Entity().Ignore(e => e.Location); - modelBuilder.Entity().Ignore(e => e.FloorPlan); - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Data.Entity.Migrations; + using System.Data.SqlServerCe; + + public static class DbContextExtensions + { + public static TypeAssertion Assert(this DbContext context) + where TStructuralType : class + { + return new TypeAssertion(context); + } + + public static void IgnoreSpatialTypesOnSqlCe(this DbContext context, DbModelBuilder modelBuilder) + { + if (context.Database.Connection is SqlCeConnection) + { + modelBuilder.Entity().Ignore(e => e.Location); + modelBuilder.Entity().Ignore(e => e.FloorPlan); + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/DbDatabaseMappingExtensions.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DbDatabaseMappingExtensions.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/DbDatabaseMappingExtensions.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DbDatabaseMappingExtensions.cs index e76241ad..b683e841 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/DbDatabaseMappingExtensions.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DbDatabaseMappingExtensions.cs @@ -1,95 +1,95 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Collections.Generic; - using System.Data.Entity.Core; - using System.Data.Entity.Core.Mapping; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.ModelConfiguration.Edm; - using System.Data.Entity.ModelConfiguration.Edm.Serialization; - using System.Data.Entity.Utilities; - using System.Diagnostics; - using System.IO; - using System.Linq; - using System.Text; - using System.Xml; - using Xunit; - - public static class DbDatabaseMappingExtensions - { - internal static void ShellEdmx(this DbDatabaseMapping databaseMapping, string fileName = "Dump.edmx") - { - new EdmxSerializer().Serialize( - databaseMapping, databaseMapping.Database.ProviderInfo, - XmlWriter.Create( - File.CreateText(fileName), - new XmlWriterSettings - { - Indent = true - })); - - Process.Start(fileName); - } - - internal static bool EdmxIsEqualTo( - this DbDatabaseMapping databaseMapping, - DbDatabaseMapping otherDatabaseMapping) - { - return SerializeToString(databaseMapping) == SerializeToString(otherDatabaseMapping); - } - - internal static string SerializeToString(DbDatabaseMapping databaseMapping) - { - var edmx = new StringBuilder(); - new EdmxSerializer().Serialize( - databaseMapping, databaseMapping.Database.ProviderInfo, - XmlWriter.Create( - edmx, new XmlWriterSettings - { - Indent = true - })); - return edmx.ToString(); - } - - internal static void AssertValid(this DbDatabaseMapping databaseMapping) - { - AssertValid(databaseMapping, false); - } - - internal static void AssertValid(this DbDatabaseMapping databaseMapping, bool shouldThrow) - { - var storageItemMappingCollection = databaseMapping.ToStorageMappingItemCollection(); - IList errors; - - storageItemMappingCollection.GenerateEntitySetViews(out errors); - - if (errors.Any()) - { - var errorMessage = new StringBuilder(); - errorMessage.AppendLine(); - - foreach (var error in errors) - { - errorMessage.AppendLine(error.ToString()); - } - - if (shouldThrow) - { - throw new MappingException(errorMessage.ToString()); - } - - Assert.True(false, errorMessage.ToString()); - } - } - - internal static StorageMappingItemCollection ToStorageMappingItemCollection(this DbDatabaseMapping databaseMapping) - { - DebugCheck.NotNull(databaseMapping); - - return databaseMapping.ToStorageMappingItemCollection( - new EdmItemCollection(databaseMapping.Model), - new StoreItemCollection(databaseMapping.Database)); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Collections.Generic; + using System.Data.Entity.Core; + using System.Data.Entity.Core.Mapping; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.ModelConfiguration.Edm; + using System.Data.Entity.ModelConfiguration.Edm.Serialization; + using System.Data.Entity.Utilities; + using System.Diagnostics; + using System.IO; + using System.Linq; + using System.Text; + using System.Xml; + using Xunit; + + public static class DbDatabaseMappingExtensions + { + internal static void ShellEdmx(this DbDatabaseMapping databaseMapping, string fileName = "Dump.edmx") + { + new EdmxSerializer().Serialize( + databaseMapping, databaseMapping.Database.ProviderInfo, + XmlWriter.Create( + File.CreateText(fileName), + new XmlWriterSettings + { + Indent = true + })); + + Process.Start(fileName); + } + + internal static bool EdmxIsEqualTo( + this DbDatabaseMapping databaseMapping, + DbDatabaseMapping otherDatabaseMapping) + { + return SerializeToString(databaseMapping) == SerializeToString(otherDatabaseMapping); + } + + internal static string SerializeToString(DbDatabaseMapping databaseMapping) + { + var edmx = new StringBuilder(); + new EdmxSerializer().Serialize( + databaseMapping, databaseMapping.Database.ProviderInfo, + XmlWriter.Create( + edmx, new XmlWriterSettings + { + Indent = true + })); + return edmx.ToString(); + } + + internal static void AssertValid(this DbDatabaseMapping databaseMapping) + { + AssertValid(databaseMapping, false); + } + + internal static void AssertValid(this DbDatabaseMapping databaseMapping, bool shouldThrow) + { + var storageItemMappingCollection = databaseMapping.ToStorageMappingItemCollection(); + IList errors; + + storageItemMappingCollection.GenerateEntitySetViews(out errors); + + if (errors.Any()) + { + var errorMessage = new StringBuilder(); + errorMessage.AppendLine(); + + foreach (var error in errors) + { + errorMessage.AppendLine(error.ToString()); + } + + if (shouldThrow) + { + throw new MappingException(errorMessage.ToString()); + } + + Assert.True(false, errorMessage.ToString()); + } + } + + internal static StorageMappingItemCollection ToStorageMappingItemCollection(this DbDatabaseMapping databaseMapping) + { + DebugCheck.NotNull(databaseMapping); + + return databaseMapping.ToStorageMappingItemCollection( + new EdmItemCollection(databaseMapping.Model), + new StoreItemCollection(databaseMapping.Database)); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/DefaultConnectionFactoryResolver.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DefaultConnectionFactoryResolver.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestHelpers/DefaultConnectionFactoryResolver.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DefaultConnectionFactoryResolver.cs index 94e8377a..55fe2c6c 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/DefaultConnectionFactoryResolver.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DefaultConnectionFactoryResolver.cs @@ -1,36 +1,36 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.TestHelpers -{ - using System; - using System.Data.Entity; - using System.Data.Entity.Config; - using System.Data.Entity.Infrastructure; - - public class DefaultConnectionFactoryResolver : IDbDependencyResolver - { - private static readonly DefaultConnectionFactoryResolver _instance = new DefaultConnectionFactoryResolver(); - private volatile IDbConnectionFactory _connectionFactory = new SqlConnectionFactory(ModelHelpers.BaseConnectionString); - - public static DefaultConnectionFactoryResolver Instance - { - get { return _instance; } - } - - public IDbConnectionFactory ConnectionFactory - { - get { return _connectionFactory; } - set { _connectionFactory = value; } - } - - public object GetService(Type type, object key) - { - if (type == typeof(IDbConnectionFactory)) - { - return ConnectionFactory; - } - - return null; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.TestHelpers +{ + using System; + using System.Data.Entity; + using System.Data.Entity.Config; + using System.Data.Entity.Infrastructure; + + public class DefaultConnectionFactoryResolver : IDbDependencyResolver + { + private static readonly DefaultConnectionFactoryResolver _instance = new DefaultConnectionFactoryResolver(); + private volatile IDbConnectionFactory _connectionFactory = new SqlConnectionFactory(ModelHelpers.BaseConnectionString); + + public static DefaultConnectionFactoryResolver Instance + { + get { return _instance; } + } + + public IDbConnectionFactory ConnectionFactory + { + get { return _connectionFactory; } + set { _connectionFactory = value; } + } + + public object GetService(Type type, object key) + { + if (type == typeof(IDbConnectionFactory)) + { + return ConnectionFactory; + } + + return null; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/DefaultFunctionalTestsConnectionFactory.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DefaultFunctionalTestsConnectionFactory.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/DefaultFunctionalTestsConnectionFactory.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DefaultFunctionalTestsConnectionFactory.cs index ab23e0b8..4c21de36 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/DefaultFunctionalTestsConnectionFactory.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DefaultFunctionalTestsConnectionFactory.cs @@ -1,21 +1,21 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.TestHelpers -{ - using System; - using System.Data.Common; - using System.Data.Entity.Infrastructure; - - /// - /// This connection factory is set in the functional tests app.config, but is then replaced by - /// the OnLockingConfiguration event handler of . - /// - public class DefaultFunctionalTestsConnectionFactory : IDbConnectionFactory - { - public DbConnection CreateConnection(string nameOrConnectionString) - { - throw new NotImplementedException( - "This connection factory should never be used because it is overriden in the OnLockingConfiguration event."); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.TestHelpers +{ + using System; + using System.Data.Common; + using System.Data.Entity.Infrastructure; + + /// + /// This connection factory is set in the functional tests app.config, but is then replaced by + /// the OnLockingConfiguration event handler of . + /// + public class DefaultFunctionalTestsConnectionFactory : IDbConnectionFactory + { + public DbConnection CreateConnection(string nameOrConnectionString) + { + throw new NotImplementedException( + "This connection factory should never be used because it is overriden in the OnLockingConfiguration event."); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/DefaultPluralizationServiceResolver.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DefaultPluralizationServiceResolver.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestHelpers/DefaultPluralizationServiceResolver.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DefaultPluralizationServiceResolver.cs diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/DefaultUnitTestsConnectionFactory.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DefaultUnitTestsConnectionFactory.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/DefaultUnitTestsConnectionFactory.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DefaultUnitTestsConnectionFactory.cs index a1b670b4..53a96975 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/DefaultUnitTestsConnectionFactory.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DefaultUnitTestsConnectionFactory.cs @@ -1,12 +1,12 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.TestHelpers -{ - /// - /// This connection factory is set in the but is then - /// replaced in the OnLockingConfiguration event handler of that class. - /// - public class DefaultUnitTestsConnectionFactory : DefaultFunctionalTestsConnectionFactory - { - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.TestHelpers +{ + /// + /// This connection factory is set in the but is then + /// replaced in the OnLockingConfiguration event handler of that class. + /// + public class DefaultUnitTestsConnectionFactory : DefaultFunctionalTestsConnectionFactory + { + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/DynamicAssembly.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DynamicAssembly.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestHelpers/DynamicAssembly.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DynamicAssembly.cs index 870b80e4..e50a90d8 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/DynamicAssembly.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DynamicAssembly.cs @@ -1,836 +1,836 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Collections.Generic; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; - using System.Data.Entity.Core.Objects.DataClasses; - using System.Linq; - using System.Reflection; - using System.Reflection.Emit; - using System.Runtime.Serialization; - - public class DynamicAssembly - { - private readonly Dictionary> _typeBuilders = - new Dictionary>(); - - private readonly Dictionary _dynamicTypes = new Dictionary(); - private readonly Dictionary _types = new Dictionary(); - private readonly List _attributes = new List(); - - private static int _assemblyCount = 1; - - public IEnumerable DynamicTypes - { - get { return _dynamicTypes.Values; } - } - - public IEnumerable Types - { - get { return _types.Values; } - } - - public DynamicStructuralType DynamicStructuralType(string typeName) - { - return GetDynamicType(typeName); - } - - public DynamicEnumType DynamicEnumType(string typeName) - { - var dynamicEnumType = GetDynamicType(typeName); - - return dynamicEnumType ?? - new DynamicEnumType() - { - Name = typeName - }; - } - - private T GetDynamicType(string typeName) - where T : DynamicType, new() - { - DynamicType dynamicType; - - if (!_dynamicTypes.TryGetValue(typeName, out dynamicType)) - { - dynamicType = - new T() - { - Name = typeName - }; - - _dynamicTypes.Add(typeName, dynamicType); - } - - return (T)dynamicType; - } - - public DynamicAssembly HasAttribute(Attribute a) - { - _attributes.Add(a); - return this; - } - - public List Attributes - { - get { return _attributes; } - } - - //private static MethodInfo s_RegisterSet = typeof(DbModelBuilder).GetMethod("RegisterSet", BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null); - private static readonly MethodInfo s_Entity = typeof(DbModelBuilder).GetMethod( - "Entity", - BindingFlags.Public | - BindingFlags.Instance, null, - Type.EmptyTypes, null); - - public DbModelBuilder ToBuilder() - { - if (Types.Count() == 0) - { - Compile(); - } - var builder = new DbModelBuilder(); - foreach (var t in Types) - { - var entityMethod = s_Entity.MakeGenericMethod(t); - entityMethod.Invoke(builder, null); - } - return builder; - } - - public Assembly Compile() - { - return Compile(new AssemblyName(string.Format("DynamicEntities{0}", _assemblyCount))); - } - - public Assembly Compile(AssemblyName assemblyName) - { - var assemblyBuilder = - AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); - - foreach (var attribute in Attributes) - { - assemblyBuilder.SetCustomAttribute(AnnotationAttributeBuilder.Create(attribute)); - } - - var moduleName = string.Format("DynamicEntitiesModule{0}.dll", _assemblyCount); - var module = assemblyBuilder.DefineDynamicModule(moduleName); - _assemblyCount++; - - foreach (var enumTypeInfo in DynamicTypes.OfType()) - { - _types.Add(enumTypeInfo.Name, DefineEnumType(module, enumTypeInfo)); - } - - foreach (var typeInfo in DynamicTypes.OfType()) - { - DefineStructuralType(module, typeInfo); - } - - foreach (var typeInfo in DynamicTypes.OfType()) - { - var typeBuilder = _typeBuilders[typeInfo.Name]; - - foreach (var fieldInfo in typeInfo.Fields) - { - DefineField(typeBuilder.Item1, typeBuilder.Item2, fieldInfo); - } - - foreach (var propertyInfo in typeInfo.Properties) - { - DefineProperty(typeBuilder.Item1, propertyInfo); - } - } - - foreach (var t in _typeBuilders) - { - _types.Add(t.Key, t.Value.Item1.CreateType()); - } - - return assemblyBuilder; - } - - public Type GetType(string typeName) - { - return _types[typeName]; - } - - public bool TryGetType(string typeName, out Type type) - { - return _types.TryGetValue(typeName, out type); - } - - private void DefineStructuralType(ModuleBuilder module, DynamicStructuralType typeInfo) - { - var typeAttributes = TypeAttributes.Class | GetTypeAccess(typeInfo.TypeAccess); - - if (typeInfo.IsAbstract) - { - typeAttributes |= TypeAttributes.Abstract; - } - if (typeInfo.IsSealed) - { - typeAttributes |= TypeAttributes.Sealed; - } - - Type baseClass = null; - if (typeInfo.BaseClass is Type) - { - baseClass = typeInfo.BaseClass as Type; - } - else if (typeInfo.BaseClass is DynamicStructuralType) - { - baseClass = _typeBuilders[((DynamicStructuralType)typeInfo.BaseClass).Name].Item1; - } - - var typeBuilder = module.DefineType(typeInfo.Name, typeAttributes, baseClass); - foreach (var a in typeInfo.Attributes) - { - typeBuilder.SetCustomAttribute(AnnotationAttributeBuilder.Create(a)); - } - - // Define the Ctor - var constructorBuilder = typeInfo.CtorAccess == MemberAccess.None - ? null - : typeBuilder.DefineDefaultConstructor(GetMethodAttributes(false, typeInfo.CtorAccess)); - - _typeBuilders.Add(typeInfo.Name, Tuple.Create(typeBuilder, constructorBuilder)); - } - - private void DefineField(TypeBuilder typeBuilder, ConstructorBuilder constructorBuilder, DynamicField fieldInfo) - { - var fieldAttributes = FieldAttributes.Public; - if (fieldInfo.Static) - { - fieldAttributes |= FieldAttributes.Static; - } - - var fieldType = _typeBuilders[fieldInfo.FieldType.Name].Item1; - var fieldBuilder = typeBuilder.DefineField(fieldInfo.FieldName, fieldType, fieldAttributes); - - if (fieldInfo.SetInstancePattern) - { - var staticConstructorBuilder = typeBuilder.DefineConstructor( - MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes); - var generator = staticConstructorBuilder.GetILGenerator(); - - generator.Emit(OpCodes.Newobj, constructorBuilder); - generator.Emit(OpCodes.Stsfld, fieldBuilder); - generator.Emit(OpCodes.Ret); - } - } - - private void DefineProperty(TypeBuilder typeBuilder, DynamicProperty propertyInfo) - { - var getterAccess = propertyInfo.GetterAccess; - var setterAccess = propertyInfo.SetterAccess; - - Type propertyType; - if (propertyInfo.EnumType != null) - { - propertyType = _types[propertyInfo.EnumType.Item1.Name]; - - if (propertyInfo.EnumType.Item2) - { - propertyType = typeof(Nullable<>).MakeGenericType(propertyType); - } - } - else if (propertyInfo.CollectionType != null) - { - if (propertyInfo.ReferenceType != null) - { - propertyType = - propertyInfo.CollectionType.MakeGenericType(_typeBuilders[propertyInfo.ReferenceType.Name].Item1); - } - else - { - propertyType = propertyInfo.CollectionType.MakeGenericType(propertyInfo.PropertyType); - } - } - else if (propertyInfo.ReferenceType != null) - { - propertyType = _typeBuilders[propertyInfo.ReferenceType.Name].Item1; - switch (_dynamicTypes[propertyInfo.ReferenceType.Name].TypeAccess) - { - case MemberAccess.Private: - getterAccess = MemberAccess.Private; - setterAccess = MemberAccess.Private; - break; - case MemberAccess.Internal: - getterAccess = MemberAccess.Internal; - setterAccess = MemberAccess.Internal; - break; - } - if (propertyInfo.PropertyType != null - && propertyInfo.PropertyType.IsGenericTypeDefinition) - { - propertyType = propertyInfo.PropertyType.MakeGenericType(propertyType); - } - } - else - { - propertyType = propertyInfo.PropertyType; - } - - var fieldBuilder = typeBuilder.DefineField( - "_" + propertyInfo.PropertyName, propertyType, - FieldAttributes.Private); - - var propertyBuilder = typeBuilder.DefineProperty( - propertyInfo.PropertyName, - PropertyAttributes.None, - propertyType, Type.EmptyTypes); - - foreach (var a in propertyInfo.Attributes) - { - propertyBuilder.SetCustomAttribute(AnnotationAttributeBuilder.Create(a)); - } - - if (propertyInfo.GetterAccess - != MemberAccess.None) - { - var getter = typeBuilder.DefineMethod( - "get_" + propertyInfo.PropertyName, - GetMethodAttributes(propertyInfo.IsVirtual, getterAccess), - propertyType, - Type.EmptyTypes); - var generator = getter.GetILGenerator(); - generator.Emit(OpCodes.Ldarg_0); - generator.Emit(OpCodes.Ldfld, fieldBuilder); - generator.Emit(OpCodes.Ret); - propertyBuilder.SetGetMethod(getter); - } - - if (propertyInfo.SetterAccess - != MemberAccess.None) - { - var setter = typeBuilder.DefineMethod( - "set_" + propertyInfo.PropertyName, - GetMethodAttributes(propertyInfo.IsVirtual, setterAccess), - null, - new[] { propertyType }); - var generator = setter.GetILGenerator(); - generator.Emit(OpCodes.Ldarg_0); - generator.Emit(OpCodes.Ldarg_1); - generator.Emit(OpCodes.Stfld, fieldBuilder); - generator.Emit(OpCodes.Ret); - propertyBuilder.SetSetMethod(setter); - } - } - - private Type DefineEnumType(ModuleBuilder module, DynamicEnumType enumTypeInfo) - { - var enumBuilder = - module.DefineEnum( - enumTypeInfo.Name, - GetTypeAccess(enumTypeInfo.TypeAccess), - enumTypeInfo.UnderlyingType); - - foreach (var a in enumTypeInfo.Attributes) - { - enumBuilder.SetCustomAttribute(AnnotationAttributeBuilder.Create(a)); - } - - foreach (var enumMember in enumTypeInfo.Members) - { - enumBuilder.DefineLiteral( - enumMember.Key, - Convert.ChangeType(enumMember.Value, enumTypeInfo.UnderlyingType)); - } - - return enumBuilder.CreateType(); - } - - private static TypeAttributes GetTypeAccess(MemberAccess typeAccess) - { - TypeAttributes typeAttributes = 0; - switch (typeAccess) - { - case MemberAccess.Public: - typeAttributes |= TypeAttributes.Public; - break; - case MemberAccess.Private: - case MemberAccess.Internal: - typeAttributes |= TypeAttributes.NotPublic; - break; - } - return typeAttributes; - } - - private static MethodAttributes GetMethodAttributes(bool isVirtual, MemberAccess memberAccess) - { - var attributes = MethodAttributes.HideBySig | MethodAttributes.SpecialName; - if (isVirtual) - { - attributes |= MethodAttributes.Virtual; - } - switch (memberAccess) - { - case MemberAccess.Public: - attributes |= MethodAttributes.Public | MethodAttributes.NewSlot; - break; - case MemberAccess.Private: - attributes |= MethodAttributes.Private; - break; - case MemberAccess.Internal: - attributes |= MethodAttributes.Assembly | MethodAttributes.NewSlot; - break; - case MemberAccess.Protected: - attributes |= MethodAttributes.Family | MethodAttributes.NewSlot; - break; - case MemberAccess.ProtectedInternal: - attributes |= MethodAttributes.FamORAssem | MethodAttributes.NewSlot; - break; - } - return attributes; - } - } - - public class AnnotationAttributeBuilder - { - public static CustomAttributeBuilder Create(dynamic attribute) - { - CustomAttributeBuilder builder = CreateCustom(attribute); - if (builder == null) - { - object[] args = GetArgs(attribute); - return - new CustomAttributeBuilder( - attribute.GetType().GetConstructor(args.Select(x => x.GetType()).ToArray()), args); - } - return builder; - } - - public static CustomAttributeBuilder CreateCustom(dynamic attribute) - { - return null; - } - - public static CustomAttributeBuilder CreateCustom(DataMemberAttribute attribute) - { - if (attribute.Order - == -1) - { - return new CustomAttributeBuilder( - typeof(DataMemberAttribute).GetConstructor(Type.EmptyTypes), - new object[] { }, - new PropertyInfo[] { }, - new object[] { }); - } - else - { - return new CustomAttributeBuilder( - typeof(DataMemberAttribute).GetConstructor(Type.EmptyTypes), - new object[] { }, - new[] { typeof(DataMemberAttribute).GetProperty("Order") }, - new object[] { attribute.Order }); - } - } - - public static CustomAttributeBuilder CreateCustom(EdmTypeAttribute attribute) - { - return new CustomAttributeBuilder( - attribute.GetType().GetConstructor(Type.EmptyTypes), - new object[0], - new PropertyInfo[] - { - typeof(EdmTypeAttribute).GetProperty("Name"), - typeof(EdmTypeAttribute).GetProperty("NamespaceName") - }, - new object[] - { - attribute.Name, - attribute.NamespaceName - }); - } - - public static CustomAttributeBuilder CreateCustom(EdmScalarPropertyAttribute attribute) - { - return new CustomAttributeBuilder( - attribute.GetType().GetConstructor(Type.EmptyTypes), - new object[0], - new PropertyInfo[] - { - typeof(EdmScalarPropertyAttribute).GetProperty("EntityKeyProperty"), - typeof(EdmScalarPropertyAttribute).GetProperty("IsNullable") - }, - new object[] - { - attribute.EntityKeyProperty, - attribute.IsNullable - }); - } - - private static object[] GetArgs(dynamic attribute) - { - return GetArgs(attribute); - } - - private static object[] GetArgs(KeyAttribute attribute) - { - return new object[] { }; - } - - private static object[] GetArgs(RequiredAttribute attribute) - { - return new object[] { }; - } - - private static object[] GetArgs(TimestampAttribute attribute) - { - return new object[] { }; - } - - private static object[] GetArgs(ConcurrencyCheckAttribute attribute) - { - return new object[] { }; - } - - private static object[] GetArgs(StringLengthAttribute attribute) - { - return new object[] { attribute.MaximumLength }; - } - - private static object[] GetArgs(MaxLengthAttribute attribute) - { - return new object[] { attribute.Length }; - } - - private static object[] GetArgs(DatabaseGeneratedAttribute attribute) - { - return new object[] { attribute.DatabaseGeneratedOption }; - } - - private static object[] GetArgs(EdmEntityTypeAttribute attribute) - { - return new object[] { }; - } - - private static object[] GetArgs(EdmSchemaAttribute attribute) - { - return new object[] { }; - } - - private static object[] GetArgs(EdmRelationshipNavigationPropertyAttribute attribute) - { - return new object[] - { - attribute.RelationshipNamespaceName, - attribute.RelationshipName, - attribute.TargetRoleName - }; - } - - private static object[] GetArgs(EdmComplexPropertyAttribute attribute) - { - return new object[0]; - } - } - - public enum MemberAccess - { - None, - Public, - Private, - Internal, - Protected, - ProtectedInternal - } - - public class DynamicProperty - { - private MemberAccess _getterAccess = MemberAccess.Public; - private MemberAccess _setterAccess = MemberAccess.Public; - private bool _isVirtual = true; - private readonly List _attributes = new List(); - - public Type PropertyType { get; set; } - - public DynamicProperty HasType(Type propertyType) - { - PropertyType = propertyType; - return this; - } - - public DynamicProperty HasType() - { - PropertyType = typeof(T); - return this; - } - - public Tuple EnumType { get; set; } - - public Tuple HasEnumType(DynamicEnumType enumType, bool nullable) - { - EnumType = new Tuple(enumType, nullable); - return EnumType; - } - - public DynamicStructuralType ReferenceType { get; set; } - - public DynamicProperty HasReferenceType(DynamicStructuralType referenceType) - { - ReferenceType = referenceType; - return this; - } - - public Type CollectionType { get; set; } - - public DynamicProperty HasCollectionType(Type collectionType, DynamicStructuralType referenceType) - { - CollectionType = collectionType; - ReferenceType = referenceType; - return this; - } - - public List Attributes - { - get { return _attributes; } - } - - public DynamicProperty HasAttribute(Attribute a) - { - _attributes.Add(a); - return this; - } - - public string PropertyName { get; set; } - - public DynamicProperty HasName(string propertyName) - { - PropertyName = propertyName; - return this; - } - - public MemberAccess GetterAccess - { - get { return _getterAccess; } - set { _getterAccess = value; } - } - - public DynamicProperty HasGetterAccess(MemberAccess access) - { - GetterAccess = access; - return this; - } - - public MemberAccess SetterAccess - { - get { return _setterAccess; } - set { _setterAccess = value; } - } - - public DynamicProperty HasSetterAccess(MemberAccess access) - { - SetterAccess = access; - return this; - } - - public bool IsVirtual - { - get { return _isVirtual; } - set { _isVirtual = value; } - } - - public DynamicProperty HasVirtual(bool isVirtual) - { - IsVirtual = isVirtual; - return this; - } - } - - public class DynamicField - { - public DynamicStructuralType FieldType { get; set; } - public string FieldName { get; set; } - public bool Static { get; set; } - public bool SetInstancePattern { get; set; } - - public DynamicField HasType(DynamicStructuralType propertyType) - { - FieldType = propertyType; - return this; - } - - public DynamicField HasName(string propertyName) - { - FieldName = propertyName; - return this; - } - - public DynamicField IsStatic() - { - Static = true; - return this; - } - - /// - /// Sets the field up to match the Instance singleton pattern required by ADO.NET. - /// - public DynamicField IsInstance() - { - SetInstancePattern = true; - return this; - } - } - - public abstract class DynamicType - { - private readonly List _attributes = new List(); - - public string Name { get; set; } - - public List Attributes - { - get { return _attributes; } - } - - private MemberAccess _typeAccess = MemberAccess.Public; - - public MemberAccess TypeAccess - { - get { return _typeAccess; } - set { _typeAccess = value; } - } - } - - public class DynamicStructuralType : DynamicType - { - private readonly Dictionary _properties = new Dictionary(); - private readonly Dictionary _fields = new Dictionary(); - private MemberAccess _ctorAccess = MemberAccess.None; - - public DynamicStructuralType HasName(string name) - { - Name = name; - return this; - } - - public bool IsSealed { get; set; } - - public DynamicStructuralType HasSealed(bool isSealed) - { - IsSealed = isSealed; - return this; - } - - public bool IsAbstract { get; set; } - - public DynamicStructuralType HasAbstract(bool isAbstract) - { - IsAbstract = isAbstract; - return this; - } - - public DynamicStructuralType HasAttribute(Attribute a) - { - Attributes.Add(a); - return this; - } - - public DynamicStructuralType HasClassAccess(MemberAccess access) - { - TypeAccess = access; - return this; - } - - public MemberAccess CtorAccess - { - get { return _ctorAccess; } - set { _ctorAccess = value; } - } - - public DynamicProperty Property(string propertyName) - { - DynamicProperty property; - if (!_properties.TryGetValue(propertyName, out property)) - { - property = new DynamicProperty(); - property.PropertyName = propertyName; - _properties.Add(propertyName, property); - } - return property; - } - - public DynamicField Field(string fieldName) - { - DynamicField field; - if (!_fields.TryGetValue(fieldName, out field)) - { - field = new DynamicField - { - FieldName = fieldName - }; - _fields.Add(fieldName, field); - } - return field; - } - - public object BaseClass { get; set; } - - public DynamicStructuralType HasBaseClass(object baseClass) - { - BaseClass = baseClass; - return this; - } - - public IEnumerable Properties - { - get { return _properties.Values; } - } - - public IEnumerable Fields - { - get { return _fields.Values; } - } - } - - public class DynamicEnumType : DynamicType - { - private readonly Dictionary _members = new Dictionary(); - - public DynamicEnumType HasName(string name) - { - Name = name; - return this; - } - - public DynamicEnumType() - { - UnderlyingType = typeof(int); - } - - public DynamicEnumType HasClassAccess(MemberAccess access) - { - TypeAccess = access; - return this; - } - - public Type UnderlyingType { get; set; } - - public DynamicEnumType HasUnderlyingType(Type type) - { - UnderlyingType = type; - return this; - } - - public DynamicEnumType HasAttribute(Attribute a) - { - Attributes.Add(a); - return this; - } - - public IEnumerable> Members - { - get { return _members; } - } - - public DynamicEnumType HasMember(string name, object value) - { - _members[name] = value; - return this; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + using System.ComponentModel.DataAnnotations.Schema; + using System.Data.Entity.Core.Objects.DataClasses; + using System.Linq; + using System.Reflection; + using System.Reflection.Emit; + using System.Runtime.Serialization; + + public class DynamicAssembly + { + private readonly Dictionary> _typeBuilders = + new Dictionary>(); + + private readonly Dictionary _dynamicTypes = new Dictionary(); + private readonly Dictionary _types = new Dictionary(); + private readonly List _attributes = new List(); + + private static int _assemblyCount = 1; + + public IEnumerable DynamicTypes + { + get { return _dynamicTypes.Values; } + } + + public IEnumerable Types + { + get { return _types.Values; } + } + + public DynamicStructuralType DynamicStructuralType(string typeName) + { + return GetDynamicType(typeName); + } + + public DynamicEnumType DynamicEnumType(string typeName) + { + var dynamicEnumType = GetDynamicType(typeName); + + return dynamicEnumType ?? + new DynamicEnumType() + { + Name = typeName + }; + } + + private T GetDynamicType(string typeName) + where T : DynamicType, new() + { + DynamicType dynamicType; + + if (!_dynamicTypes.TryGetValue(typeName, out dynamicType)) + { + dynamicType = + new T() + { + Name = typeName + }; + + _dynamicTypes.Add(typeName, dynamicType); + } + + return (T)dynamicType; + } + + public DynamicAssembly HasAttribute(Attribute a) + { + _attributes.Add(a); + return this; + } + + public List Attributes + { + get { return _attributes; } + } + + //private static MethodInfo s_RegisterSet = typeof(DbModelBuilder).GetMethod("RegisterSet", BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null); + private static readonly MethodInfo s_Entity = typeof(DbModelBuilder).GetMethod( + "Entity", + BindingFlags.Public | + BindingFlags.Instance, null, + Type.EmptyTypes, null); + + public DbModelBuilder ToBuilder() + { + if (Types.Count() == 0) + { + Compile(); + } + var builder = new DbModelBuilder(); + foreach (var t in Types) + { + var entityMethod = s_Entity.MakeGenericMethod(t); + entityMethod.Invoke(builder, null); + } + return builder; + } + + public Assembly Compile() + { + return Compile(new AssemblyName(string.Format("DynamicEntities{0}", _assemblyCount))); + } + + public Assembly Compile(AssemblyName assemblyName) + { + var assemblyBuilder = + AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); + + foreach (var attribute in Attributes) + { + assemblyBuilder.SetCustomAttribute(AnnotationAttributeBuilder.Create(attribute)); + } + + var moduleName = string.Format("DynamicEntitiesModule{0}.dll", _assemblyCount); + var module = assemblyBuilder.DefineDynamicModule(moduleName); + _assemblyCount++; + + foreach (var enumTypeInfo in DynamicTypes.OfType()) + { + _types.Add(enumTypeInfo.Name, DefineEnumType(module, enumTypeInfo)); + } + + foreach (var typeInfo in DynamicTypes.OfType()) + { + DefineStructuralType(module, typeInfo); + } + + foreach (var typeInfo in DynamicTypes.OfType()) + { + var typeBuilder = _typeBuilders[typeInfo.Name]; + + foreach (var fieldInfo in typeInfo.Fields) + { + DefineField(typeBuilder.Item1, typeBuilder.Item2, fieldInfo); + } + + foreach (var propertyInfo in typeInfo.Properties) + { + DefineProperty(typeBuilder.Item1, propertyInfo); + } + } + + foreach (var t in _typeBuilders) + { + _types.Add(t.Key, t.Value.Item1.CreateType()); + } + + return assemblyBuilder; + } + + public Type GetType(string typeName) + { + return _types[typeName]; + } + + public bool TryGetType(string typeName, out Type type) + { + return _types.TryGetValue(typeName, out type); + } + + private void DefineStructuralType(ModuleBuilder module, DynamicStructuralType typeInfo) + { + var typeAttributes = TypeAttributes.Class | GetTypeAccess(typeInfo.TypeAccess); + + if (typeInfo.IsAbstract) + { + typeAttributes |= TypeAttributes.Abstract; + } + if (typeInfo.IsSealed) + { + typeAttributes |= TypeAttributes.Sealed; + } + + Type baseClass = null; + if (typeInfo.BaseClass is Type) + { + baseClass = typeInfo.BaseClass as Type; + } + else if (typeInfo.BaseClass is DynamicStructuralType) + { + baseClass = _typeBuilders[((DynamicStructuralType)typeInfo.BaseClass).Name].Item1; + } + + var typeBuilder = module.DefineType(typeInfo.Name, typeAttributes, baseClass); + foreach (var a in typeInfo.Attributes) + { + typeBuilder.SetCustomAttribute(AnnotationAttributeBuilder.Create(a)); + } + + // Define the Ctor + var constructorBuilder = typeInfo.CtorAccess == MemberAccess.None + ? null + : typeBuilder.DefineDefaultConstructor(GetMethodAttributes(false, typeInfo.CtorAccess)); + + _typeBuilders.Add(typeInfo.Name, Tuple.Create(typeBuilder, constructorBuilder)); + } + + private void DefineField(TypeBuilder typeBuilder, ConstructorBuilder constructorBuilder, DynamicField fieldInfo) + { + var fieldAttributes = FieldAttributes.Public; + if (fieldInfo.Static) + { + fieldAttributes |= FieldAttributes.Static; + } + + var fieldType = _typeBuilders[fieldInfo.FieldType.Name].Item1; + var fieldBuilder = typeBuilder.DefineField(fieldInfo.FieldName, fieldType, fieldAttributes); + + if (fieldInfo.SetInstancePattern) + { + var staticConstructorBuilder = typeBuilder.DefineConstructor( + MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes); + var generator = staticConstructorBuilder.GetILGenerator(); + + generator.Emit(OpCodes.Newobj, constructorBuilder); + generator.Emit(OpCodes.Stsfld, fieldBuilder); + generator.Emit(OpCodes.Ret); + } + } + + private void DefineProperty(TypeBuilder typeBuilder, DynamicProperty propertyInfo) + { + var getterAccess = propertyInfo.GetterAccess; + var setterAccess = propertyInfo.SetterAccess; + + Type propertyType; + if (propertyInfo.EnumType != null) + { + propertyType = _types[propertyInfo.EnumType.Item1.Name]; + + if (propertyInfo.EnumType.Item2) + { + propertyType = typeof(Nullable<>).MakeGenericType(propertyType); + } + } + else if (propertyInfo.CollectionType != null) + { + if (propertyInfo.ReferenceType != null) + { + propertyType = + propertyInfo.CollectionType.MakeGenericType(_typeBuilders[propertyInfo.ReferenceType.Name].Item1); + } + else + { + propertyType = propertyInfo.CollectionType.MakeGenericType(propertyInfo.PropertyType); + } + } + else if (propertyInfo.ReferenceType != null) + { + propertyType = _typeBuilders[propertyInfo.ReferenceType.Name].Item1; + switch (_dynamicTypes[propertyInfo.ReferenceType.Name].TypeAccess) + { + case MemberAccess.Private: + getterAccess = MemberAccess.Private; + setterAccess = MemberAccess.Private; + break; + case MemberAccess.Internal: + getterAccess = MemberAccess.Internal; + setterAccess = MemberAccess.Internal; + break; + } + if (propertyInfo.PropertyType != null + && propertyInfo.PropertyType.IsGenericTypeDefinition) + { + propertyType = propertyInfo.PropertyType.MakeGenericType(propertyType); + } + } + else + { + propertyType = propertyInfo.PropertyType; + } + + var fieldBuilder = typeBuilder.DefineField( + "_" + propertyInfo.PropertyName, propertyType, + FieldAttributes.Private); + + var propertyBuilder = typeBuilder.DefineProperty( + propertyInfo.PropertyName, + PropertyAttributes.None, + propertyType, Type.EmptyTypes); + + foreach (var a in propertyInfo.Attributes) + { + propertyBuilder.SetCustomAttribute(AnnotationAttributeBuilder.Create(a)); + } + + if (propertyInfo.GetterAccess + != MemberAccess.None) + { + var getter = typeBuilder.DefineMethod( + "get_" + propertyInfo.PropertyName, + GetMethodAttributes(propertyInfo.IsVirtual, getterAccess), + propertyType, + Type.EmptyTypes); + var generator = getter.GetILGenerator(); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldfld, fieldBuilder); + generator.Emit(OpCodes.Ret); + propertyBuilder.SetGetMethod(getter); + } + + if (propertyInfo.SetterAccess + != MemberAccess.None) + { + var setter = typeBuilder.DefineMethod( + "set_" + propertyInfo.PropertyName, + GetMethodAttributes(propertyInfo.IsVirtual, setterAccess), + null, + new[] { propertyType }); + var generator = setter.GetILGenerator(); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldarg_1); + generator.Emit(OpCodes.Stfld, fieldBuilder); + generator.Emit(OpCodes.Ret); + propertyBuilder.SetSetMethod(setter); + } + } + + private Type DefineEnumType(ModuleBuilder module, DynamicEnumType enumTypeInfo) + { + var enumBuilder = + module.DefineEnum( + enumTypeInfo.Name, + GetTypeAccess(enumTypeInfo.TypeAccess), + enumTypeInfo.UnderlyingType); + + foreach (var a in enumTypeInfo.Attributes) + { + enumBuilder.SetCustomAttribute(AnnotationAttributeBuilder.Create(a)); + } + + foreach (var enumMember in enumTypeInfo.Members) + { + enumBuilder.DefineLiteral( + enumMember.Key, + Convert.ChangeType(enumMember.Value, enumTypeInfo.UnderlyingType)); + } + + return enumBuilder.CreateType(); + } + + private static TypeAttributes GetTypeAccess(MemberAccess typeAccess) + { + TypeAttributes typeAttributes = 0; + switch (typeAccess) + { + case MemberAccess.Public: + typeAttributes |= TypeAttributes.Public; + break; + case MemberAccess.Private: + case MemberAccess.Internal: + typeAttributes |= TypeAttributes.NotPublic; + break; + } + return typeAttributes; + } + + private static MethodAttributes GetMethodAttributes(bool isVirtual, MemberAccess memberAccess) + { + var attributes = MethodAttributes.HideBySig | MethodAttributes.SpecialName; + if (isVirtual) + { + attributes |= MethodAttributes.Virtual; + } + switch (memberAccess) + { + case MemberAccess.Public: + attributes |= MethodAttributes.Public | MethodAttributes.NewSlot; + break; + case MemberAccess.Private: + attributes |= MethodAttributes.Private; + break; + case MemberAccess.Internal: + attributes |= MethodAttributes.Assembly | MethodAttributes.NewSlot; + break; + case MemberAccess.Protected: + attributes |= MethodAttributes.Family | MethodAttributes.NewSlot; + break; + case MemberAccess.ProtectedInternal: + attributes |= MethodAttributes.FamORAssem | MethodAttributes.NewSlot; + break; + } + return attributes; + } + } + + public class AnnotationAttributeBuilder + { + public static CustomAttributeBuilder Create(dynamic attribute) + { + CustomAttributeBuilder builder = CreateCustom(attribute); + if (builder == null) + { + object[] args = GetArgs(attribute); + return + new CustomAttributeBuilder( + attribute.GetType().GetConstructor(args.Select(x => x.GetType()).ToArray()), args); + } + return builder; + } + + public static CustomAttributeBuilder CreateCustom(dynamic attribute) + { + return null; + } + + public static CustomAttributeBuilder CreateCustom(DataMemberAttribute attribute) + { + if (attribute.Order + == -1) + { + return new CustomAttributeBuilder( + typeof(DataMemberAttribute).GetConstructor(Type.EmptyTypes), + new object[] { }, + new PropertyInfo[] { }, + new object[] { }); + } + else + { + return new CustomAttributeBuilder( + typeof(DataMemberAttribute).GetConstructor(Type.EmptyTypes), + new object[] { }, + new[] { typeof(DataMemberAttribute).GetProperty("Order") }, + new object[] { attribute.Order }); + } + } + + public static CustomAttributeBuilder CreateCustom(EdmTypeAttribute attribute) + { + return new CustomAttributeBuilder( + attribute.GetType().GetConstructor(Type.EmptyTypes), + new object[0], + new PropertyInfo[] + { + typeof(EdmTypeAttribute).GetProperty("Name"), + typeof(EdmTypeAttribute).GetProperty("NamespaceName") + }, + new object[] + { + attribute.Name, + attribute.NamespaceName + }); + } + + public static CustomAttributeBuilder CreateCustom(EdmScalarPropertyAttribute attribute) + { + return new CustomAttributeBuilder( + attribute.GetType().GetConstructor(Type.EmptyTypes), + new object[0], + new PropertyInfo[] + { + typeof(EdmScalarPropertyAttribute).GetProperty("EntityKeyProperty"), + typeof(EdmScalarPropertyAttribute).GetProperty("IsNullable") + }, + new object[] + { + attribute.EntityKeyProperty, + attribute.IsNullable + }); + } + + private static object[] GetArgs(dynamic attribute) + { + return GetArgs(attribute); + } + + private static object[] GetArgs(KeyAttribute attribute) + { + return new object[] { }; + } + + private static object[] GetArgs(RequiredAttribute attribute) + { + return new object[] { }; + } + + private static object[] GetArgs(TimestampAttribute attribute) + { + return new object[] { }; + } + + private static object[] GetArgs(ConcurrencyCheckAttribute attribute) + { + return new object[] { }; + } + + private static object[] GetArgs(StringLengthAttribute attribute) + { + return new object[] { attribute.MaximumLength }; + } + + private static object[] GetArgs(MaxLengthAttribute attribute) + { + return new object[] { attribute.Length }; + } + + private static object[] GetArgs(DatabaseGeneratedAttribute attribute) + { + return new object[] { attribute.DatabaseGeneratedOption }; + } + + private static object[] GetArgs(EdmEntityTypeAttribute attribute) + { + return new object[] { }; + } + + private static object[] GetArgs(EdmSchemaAttribute attribute) + { + return new object[] { }; + } + + private static object[] GetArgs(EdmRelationshipNavigationPropertyAttribute attribute) + { + return new object[] + { + attribute.RelationshipNamespaceName, + attribute.RelationshipName, + attribute.TargetRoleName + }; + } + + private static object[] GetArgs(EdmComplexPropertyAttribute attribute) + { + return new object[0]; + } + } + + public enum MemberAccess + { + None, + Public, + Private, + Internal, + Protected, + ProtectedInternal + } + + public class DynamicProperty + { + private MemberAccess _getterAccess = MemberAccess.Public; + private MemberAccess _setterAccess = MemberAccess.Public; + private bool _isVirtual = true; + private readonly List _attributes = new List(); + + public Type PropertyType { get; set; } + + public DynamicProperty HasType(Type propertyType) + { + PropertyType = propertyType; + return this; + } + + public DynamicProperty HasType() + { + PropertyType = typeof(T); + return this; + } + + public Tuple EnumType { get; set; } + + public Tuple HasEnumType(DynamicEnumType enumType, bool nullable) + { + EnumType = new Tuple(enumType, nullable); + return EnumType; + } + + public DynamicStructuralType ReferenceType { get; set; } + + public DynamicProperty HasReferenceType(DynamicStructuralType referenceType) + { + ReferenceType = referenceType; + return this; + } + + public Type CollectionType { get; set; } + + public DynamicProperty HasCollectionType(Type collectionType, DynamicStructuralType referenceType) + { + CollectionType = collectionType; + ReferenceType = referenceType; + return this; + } + + public List Attributes + { + get { return _attributes; } + } + + public DynamicProperty HasAttribute(Attribute a) + { + _attributes.Add(a); + return this; + } + + public string PropertyName { get; set; } + + public DynamicProperty HasName(string propertyName) + { + PropertyName = propertyName; + return this; + } + + public MemberAccess GetterAccess + { + get { return _getterAccess; } + set { _getterAccess = value; } + } + + public DynamicProperty HasGetterAccess(MemberAccess access) + { + GetterAccess = access; + return this; + } + + public MemberAccess SetterAccess + { + get { return _setterAccess; } + set { _setterAccess = value; } + } + + public DynamicProperty HasSetterAccess(MemberAccess access) + { + SetterAccess = access; + return this; + } + + public bool IsVirtual + { + get { return _isVirtual; } + set { _isVirtual = value; } + } + + public DynamicProperty HasVirtual(bool isVirtual) + { + IsVirtual = isVirtual; + return this; + } + } + + public class DynamicField + { + public DynamicStructuralType FieldType { get; set; } + public string FieldName { get; set; } + public bool Static { get; set; } + public bool SetInstancePattern { get; set; } + + public DynamicField HasType(DynamicStructuralType propertyType) + { + FieldType = propertyType; + return this; + } + + public DynamicField HasName(string propertyName) + { + FieldName = propertyName; + return this; + } + + public DynamicField IsStatic() + { + Static = true; + return this; + } + + /// + /// Sets the field up to match the Instance singleton pattern required by ADO.NET. + /// + public DynamicField IsInstance() + { + SetInstancePattern = true; + return this; + } + } + + public abstract class DynamicType + { + private readonly List _attributes = new List(); + + public string Name { get; set; } + + public List Attributes + { + get { return _attributes; } + } + + private MemberAccess _typeAccess = MemberAccess.Public; + + public MemberAccess TypeAccess + { + get { return _typeAccess; } + set { _typeAccess = value; } + } + } + + public class DynamicStructuralType : DynamicType + { + private readonly Dictionary _properties = new Dictionary(); + private readonly Dictionary _fields = new Dictionary(); + private MemberAccess _ctorAccess = MemberAccess.None; + + public DynamicStructuralType HasName(string name) + { + Name = name; + return this; + } + + public bool IsSealed { get; set; } + + public DynamicStructuralType HasSealed(bool isSealed) + { + IsSealed = isSealed; + return this; + } + + public bool IsAbstract { get; set; } + + public DynamicStructuralType HasAbstract(bool isAbstract) + { + IsAbstract = isAbstract; + return this; + } + + public DynamicStructuralType HasAttribute(Attribute a) + { + Attributes.Add(a); + return this; + } + + public DynamicStructuralType HasClassAccess(MemberAccess access) + { + TypeAccess = access; + return this; + } + + public MemberAccess CtorAccess + { + get { return _ctorAccess; } + set { _ctorAccess = value; } + } + + public DynamicProperty Property(string propertyName) + { + DynamicProperty property; + if (!_properties.TryGetValue(propertyName, out property)) + { + property = new DynamicProperty(); + property.PropertyName = propertyName; + _properties.Add(propertyName, property); + } + return property; + } + + public DynamicField Field(string fieldName) + { + DynamicField field; + if (!_fields.TryGetValue(fieldName, out field)) + { + field = new DynamicField + { + FieldName = fieldName + }; + _fields.Add(fieldName, field); + } + return field; + } + + public object BaseClass { get; set; } + + public DynamicStructuralType HasBaseClass(object baseClass) + { + BaseClass = baseClass; + return this; + } + + public IEnumerable Properties + { + get { return _properties.Values; } + } + + public IEnumerable Fields + { + get { return _fields.Values; } + } + } + + public class DynamicEnumType : DynamicType + { + private readonly Dictionary _members = new Dictionary(); + + public DynamicEnumType HasName(string name) + { + Name = name; + return this; + } + + public DynamicEnumType() + { + UnderlyingType = typeof(int); + } + + public DynamicEnumType HasClassAccess(MemberAccess access) + { + TypeAccess = access; + return this; + } + + public Type UnderlyingType { get; set; } + + public DynamicEnumType HasUnderlyingType(Type type) + { + UnderlyingType = type; + return this; + } + + public DynamicEnumType HasAttribute(Attribute a) + { + Attributes.Add(a); + return this; + } + + public IEnumerable> Members + { + get { return _members; } + } + + public DynamicEnumType HasMember(string name, object value) + { + _members[name] = value; + return this; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/DynamicTypeDescriptor.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DynamicTypeDescriptor.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/DynamicTypeDescriptor.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DynamicTypeDescriptor.cs index 91a11b90..5d870869 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/DynamicTypeDescriptor.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/DynamicTypeDescriptor.cs @@ -1,131 +1,131 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Collections.Generic; - using System.ComponentModel; - using System.Data.Entity.Utilities; - using System.Diagnostics; - using System.Diagnostics.Contracts; - using System.Linq; - using System.Linq.Expressions; - - internal class DynamicTypeDescriptionProvider : TypeDescriptionProvider - { - private readonly DynamicTypeDescriptionConfiguration _configuration; - - public DynamicTypeDescriptionProvider(TypeDescriptionProvider parent, DynamicTypeDescriptionConfiguration configuration) - : base(parent) - { - _configuration = configuration; - } - - public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) - { - var defaultDescriptor = base.GetTypeDescriptor(objectType, instance); - - return new DynamicTypeDescriptor(defaultDescriptor, _configuration); - } - } - - internal class DynamicTypeDescriptor : CustomTypeDescriptor - { - private readonly DynamicTypeDescriptionConfiguration _configuration; - - public DynamicTypeDescriptor(ICustomTypeDescriptor parent, DynamicTypeDescriptionConfiguration configuration) - : base(parent) - { - _configuration = configuration; - } - - public override AttributeCollection GetAttributes() - { - var newAttributes = new List(_configuration.TypeAttributes); - - if (!_configuration.IgnoreBase) - { - newAttributes.AddRange(base.GetAttributes().Cast()); - } - - return new AttributeCollection(newAttributes.ToArray()); - } - - public override PropertyDescriptorCollection GetProperties() - { - return AddAttributes(base.GetProperties()); - } - - public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) - { - return AddAttributes(base.GetProperties(attributes)); - } - - private PropertyDescriptorCollection AddAttributes(PropertyDescriptorCollection originalProperties) - { - var newProperties = new PropertyDescriptor[originalProperties.Count]; - for (var i = 0; i < originalProperties.Count; i++) - { - Attribute[] attributes; - if (_configuration.PropertyAttributes.TryGetValue(originalProperties[i].Name, out attributes)) - { - var newAttributes = new List(attributes); - - if (!_configuration.IgnoreBase) - { - newAttributes.AddRange(originalProperties[i].Attributes.Cast()); - } - newProperties[i] = TypeDescriptor.CreateProperty( - originalProperties[i].ComponentType, originalProperties[i], newAttributes.ToArray()); - } - else - { - newProperties[i] = originalProperties[i]; - } - } - return new PropertyDescriptorCollection(newProperties); - } - } - - internal class DynamicTypeDescriptionConfiguration : IDisposable - { - private readonly DynamicTypeDescriptionProvider _dynamicTypeDescriptionProvider; - private readonly Dictionary _propertyAttributes; - - public DynamicTypeDescriptionConfiguration() - { - _propertyAttributes = new Dictionary(); - TypeAttributes = new Attribute[0]; - - var provider = TypeDescriptor.GetProvider(typeof(T)); - if (!(provider is DynamicTypeDescriptionProvider)) - { - _dynamicTypeDescriptionProvider = new DynamicTypeDescriptionProvider(provider, this); - TypeDescriptor.AddProvider(_dynamicTypeDescriptionProvider, typeof(T)); - } - } - - public Attribute[] TypeAttributes { get; set; } - - public Dictionary PropertyAttributes - { - get { return _propertyAttributes; } - } - - /// - /// If set to true will not return attributes defined on the type at compile time - /// - public bool IgnoreBase { get; set; } - - public void Dispose() - { - TypeDescriptor.RemoveProvider(_dynamicTypeDescriptionProvider, typeof(T)); - } - - public void SetPropertyAttributes(Expression> property, params Attribute[] attributes) - { - Debug.Assert(property != null); - - PropertyAttributes[property.GetSimplePropertyAccess().Single().Name] = attributes; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Collections.Generic; + using System.ComponentModel; + using System.Data.Entity.Utilities; + using System.Diagnostics; + using System.Diagnostics.Contracts; + using System.Linq; + using System.Linq.Expressions; + + internal class DynamicTypeDescriptionProvider : TypeDescriptionProvider + { + private readonly DynamicTypeDescriptionConfiguration _configuration; + + public DynamicTypeDescriptionProvider(TypeDescriptionProvider parent, DynamicTypeDescriptionConfiguration configuration) + : base(parent) + { + _configuration = configuration; + } + + public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) + { + var defaultDescriptor = base.GetTypeDescriptor(objectType, instance); + + return new DynamicTypeDescriptor(defaultDescriptor, _configuration); + } + } + + internal class DynamicTypeDescriptor : CustomTypeDescriptor + { + private readonly DynamicTypeDescriptionConfiguration _configuration; + + public DynamicTypeDescriptor(ICustomTypeDescriptor parent, DynamicTypeDescriptionConfiguration configuration) + : base(parent) + { + _configuration = configuration; + } + + public override AttributeCollection GetAttributes() + { + var newAttributes = new List(_configuration.TypeAttributes); + + if (!_configuration.IgnoreBase) + { + newAttributes.AddRange(base.GetAttributes().Cast()); + } + + return new AttributeCollection(newAttributes.ToArray()); + } + + public override PropertyDescriptorCollection GetProperties() + { + return AddAttributes(base.GetProperties()); + } + + public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) + { + return AddAttributes(base.GetProperties(attributes)); + } + + private PropertyDescriptorCollection AddAttributes(PropertyDescriptorCollection originalProperties) + { + var newProperties = new PropertyDescriptor[originalProperties.Count]; + for (var i = 0; i < originalProperties.Count; i++) + { + Attribute[] attributes; + if (_configuration.PropertyAttributes.TryGetValue(originalProperties[i].Name, out attributes)) + { + var newAttributes = new List(attributes); + + if (!_configuration.IgnoreBase) + { + newAttributes.AddRange(originalProperties[i].Attributes.Cast()); + } + newProperties[i] = TypeDescriptor.CreateProperty( + originalProperties[i].ComponentType, originalProperties[i], newAttributes.ToArray()); + } + else + { + newProperties[i] = originalProperties[i]; + } + } + return new PropertyDescriptorCollection(newProperties); + } + } + + internal class DynamicTypeDescriptionConfiguration : IDisposable + { + private readonly DynamicTypeDescriptionProvider _dynamicTypeDescriptionProvider; + private readonly Dictionary _propertyAttributes; + + public DynamicTypeDescriptionConfiguration() + { + _propertyAttributes = new Dictionary(); + TypeAttributes = new Attribute[0]; + + var provider = TypeDescriptor.GetProvider(typeof(T)); + if (!(provider is DynamicTypeDescriptionProvider)) + { + _dynamicTypeDescriptionProvider = new DynamicTypeDescriptionProvider(provider, this); + TypeDescriptor.AddProvider(_dynamicTypeDescriptionProvider, typeof(T)); + } + } + + public Attribute[] TypeAttributes { get; set; } + + public Dictionary PropertyAttributes + { + get { return _propertyAttributes; } + } + + /// + /// If set to true will not return attributes defined on the type at compile time + /// + public bool IgnoreBase { get; set; } + + public void Dispose() + { + TypeDescriptor.RemoveProvider(_dynamicTypeDescriptionProvider, typeof(T)); + } + + public void SetPropertyAttributes(Expression> property, params Attribute[] attributes) + { + Debug.Assert(property != null); + + PropertyAttributes[property.GetSimplePropertyAccess().Single().Name] = attributes; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/ExceptionHelpers.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ExceptionHelpers.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestHelpers/ExceptionHelpers.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ExceptionHelpers.cs diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/ExceptionTestExtensions.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ExceptionTestExtensions.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/ExceptionTestExtensions.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ExceptionTestExtensions.cs index 880d0c01..5c83d211 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/ExceptionTestExtensions.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ExceptionTestExtensions.cs @@ -1,63 +1,63 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Diagnostics; - using System.Diagnostics.Contracts; - using System.Linq; - using System.Reflection; - using Xunit; - - public static class ExceptionTestExtensions - { - public static void ValidateMessage( - this Exception exception, - string expectedResourceKey, - params object[] parameters) - { - Debug.Assert(exception != null); - Debug.Assert(expectedResourceKey != null); - - ValidateMessage(exception, TestBase.EntityFrameworkAssembly, expectedResourceKey, null, parameters); - } - - public static void ValidateMessage( - this Exception exception, - Assembly resourceAssembly, - string expectedResourceKey, - string resourceTable = null, - params object[] parameters) - { - Debug.Assert(exception != null); - Debug.Assert(resourceAssembly != null); - Debug.Assert(expectedResourceKey != null); - - if (resourceTable == null - && resourceAssembly == TestBase.EntityFrameworkAssembly) - { - resourceTable = "System.Data.Entity.Properties.Resources"; - } - - var actualMessage = exception.Message; - var argException = exception as ArgumentException; - if (argException != null) - { - var paramPartIndex = argException.Message.LastIndexOf("\r\n"); - if (paramPartIndex != -1) - { - actualMessage = argException.Message.Substring(0, paramPartIndex); - Assert.True(parameters.Length >= 1, "Expected first parameter to be param for ArgumentException."); - Assert.Equal(parameters[0], argException.ParamName); - parameters = parameters.Skip(1).ToArray(); - } - } - var assemblyResourceLookup - = resourceTable == null - ? new AssemblyResourceLookup(resourceAssembly) - : new AssemblyResourceLookup(resourceAssembly, resourceTable); - - new StringResourceVerifier(assemblyResourceLookup) - .VerifyMatch(expectedResourceKey, actualMessage, parameters); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Diagnostics; + using System.Diagnostics.Contracts; + using System.Linq; + using System.Reflection; + using Xunit; + + public static class ExceptionTestExtensions + { + public static void ValidateMessage( + this Exception exception, + string expectedResourceKey, + params object[] parameters) + { + Debug.Assert(exception != null); + Debug.Assert(expectedResourceKey != null); + + ValidateMessage(exception, TestBase.EntityFrameworkAssembly, expectedResourceKey, null, parameters); + } + + public static void ValidateMessage( + this Exception exception, + Assembly resourceAssembly, + string expectedResourceKey, + string resourceTable = null, + params object[] parameters) + { + Debug.Assert(exception != null); + Debug.Assert(resourceAssembly != null); + Debug.Assert(expectedResourceKey != null); + + if (resourceTable == null + && resourceAssembly == TestBase.EntityFrameworkAssembly) + { + resourceTable = "System.Data.Entity.Properties.Resources"; + } + + var actualMessage = exception.Message; + var argException = exception as ArgumentException; + if (argException != null) + { + var paramPartIndex = argException.Message.LastIndexOf("\r\n"); + if (paramPartIndex != -1) + { + actualMessage = argException.Message.Substring(0, paramPartIndex); + Assert.True(parameters.Length >= 1, "Expected first parameter to be param for ArgumentException."); + Assert.Equal(parameters[0], argException.ParamName); + parameters = parameters.Skip(1).ToArray(); + } + } + var assemblyResourceLookup + = resourceTable == null + ? new AssemblyResourceLookup(resourceAssembly) + : new AssemblyResourceLookup(resourceAssembly, resourceTable); + + new StringResourceVerifier(assemblyResourceLookup) + .VerifyMatch(expectedResourceKey, actualMessage, parameters); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/FakePluralizationService.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/FakePluralizationService.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestHelpers/FakePluralizationService.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/FakePluralizationService.cs index cec73f08..7e80e1e0 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/FakePluralizationService.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/FakePluralizationService.cs @@ -1,24 +1,24 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.TestHelpers -{ - using System; - using System.Data.Entity.Infrastructure.Pluralization; - - public class FakePluralizationService : IPluralizationService - { - public string Pluralize(string word) - { - if (!word.EndsWith("z")) - { - return string.Format("{0}z", word); - } - return word; - } - - public string Singularize(string word) - { - return word; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.TestHelpers +{ + using System; + using System.Data.Entity.Infrastructure.Pluralization; + + public class FakePluralizationService : IPluralizationService + { + public string Pluralize(string word) + { + if (!word.EndsWith("z")) + { + return string.Format("{0}z", word); + } + return word; + } + + public string Singularize(string word) + { + return word; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/FunctionalTestBase.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/FunctionalTestBase.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/FunctionalTestBase.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/FunctionalTestBase.cs index 03a3488a..b2282028 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/FunctionalTestBase.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/FunctionalTestBase.cs @@ -1,323 +1,323 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Data.Common; - using System.Data.Entity.Infrastructure; - using System.Globalization; - using System.IO; - using FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns; - using FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel; - using ProductivityApiTests; - using SimpleModel; - using Xunit; - - /// - /// Base class for Productivity API tests that sets up a simple model and some data. - /// Call ClassInitializeBase from the ClassInitialize method of your test class to ensure - /// that the test data is configured. - /// - public class FunctionalTestBase : TestBase - { - #region Test database setup - - protected int AdvancedModelOfficeCount - { - get { return 4; } - } - - protected int AdvancedModelBuildingCount - { - get { return 2; } - } - - protected int AdvancedModelWhiteboardCount - { - get { return 3; } - } - - /// - /// Ensures the database for the context is created and seeded. This is typically used - /// when a test is going to use a transaction to ensure that the DDL happens outside of - /// the transaction. - /// - /// A func to create the context. - protected static void EnsureDatabaseInitialized(Func createContext) - { - using (var context = createContext()) - { - context.Database.Initialize(force: false); - } - } - - /// - /// Drops the database that would be used for the context. Usually used to avoid errors during initialization. - /// - /// A func to create the context. - protected static void DropDatabase(Func createContext) - { - using (var context = createContext()) - { - context.Database.Delete(); - } - } - - /// - /// Drops and then initializes the database that will be used for the context. - /// - /// A func to create the context. - protected static void ResetDatabase(Func createContext) - { - DropDatabase(createContext); - EnsureDatabaseInitialized(createContext); - } - - /// - /// Initializes the metadata files and creates databases for existing CSDL/EDMX files. - /// - protected static void InitializeModelFirstDatabases() - { - const string prefix = "FunctionalTests.ProductivityApi.TemplateModels.Schemas."; - ResourceUtilities.CopyEmbeddedResourcesToCurrentDir( - typeof(TemplateTests).Assembly, - prefix, - /*overwrite*/ true, - "AdvancedPatterns.edmx", - "MonsterModel.csdl", - "MonsterModel.msl", - "MonsterModel.ssdl"); - - // Extract the csdl, msl, and ssdl from the edmx so that they can be referenced in the connection string. - ModelHelpers.WriteMetadataFiles(File.ReadAllText(@".\AdvancedPatterns.edmx"), @".\AdvancedPatterns"); - - using (var context = new AdvancedPatternsModelFirstContext()) - { - context.Database.Initialize(force: false); - } - - using (var context = new MonsterModel()) - { - Database.SetInitializer(new DropCreateDatabaseAlways()); - context.Database.Initialize(force: false); - } - } - - private static bool _metadataForSimpleModelCreated; - - /// - /// Creates the metadata files (CSDL/SSDL/MSL) for the SimpleModelContext. - /// - protected static void CreateMetadataFilesForSimpleModel() - { - if (!_metadataForSimpleModelCreated) - { - var builder = SimpleModelContext.CreateBuilder(); - ModelHelpers.WriteMetadataFiles(builder, @".\SimpleModel"); - - using (var connection = SimpleConnection()) - { - new SimpleModelContext(connection, builder.Build(connection).Compile()).Database.Initialize(false); - } - - _metadataForSimpleModelCreated = true; - } - } - - private static string _simpleModelEntityConnectionString; - - /// - /// An entity connection string for the SimpleModelContext. - /// - protected static string SimpleModelEntityConnectionString - { - get - { - const string baseConnectionString = - @"metadata=.\SimpleModel.csdl|.\SimpleModel.ssdl|.\SimpleModel.msl; - provider=System.Data.SqlClient;provider connection string='{0}'"; - return _simpleModelEntityConnectionString ?? - (_simpleModelEntityConnectionString = - String.Format( - CultureInfo.InvariantCulture, baseConnectionString, - SimpleConnectionString())); - } - } - - #endregion - - #region Construction helpers - - protected static TContext CreateContext( - DbContextConstructorArgumentType arguments, - string providerName = "System.Data.SqlClient") - where TContext : DbContext - { - DbConnection connection = null; - if (arguments == DbContextConstructorArgumentType.Connection - || - arguments == DbContextConstructorArgumentType.ConnectionAndDbCompiledModel) - { - if (providerName == "System.Data.SqlClient") - { - connection = SimpleConnection(); - } - else if (providerName == "System.Data.SqlServerCe.4.0") - { - connection = SimpleCeConnection(); - } - else - { - throw new ArgumentException("Invalid provider specified, " + providerName); - } - } - - string connectionString = null; - if (arguments == DbContextConstructorArgumentType.ConnectionString - || - arguments == DbContextConstructorArgumentType.ConnectionStringAndDbCompiledModel) - { - if (providerName == "System.Data.SqlClient") - { - connectionString = SimpleConnectionString(); - } - else if (providerName == "System.Data.SqlServerCe.4.0") - { - connectionString = SimpleCeConnectionString(); - } - else - { - throw new ArgumentException("Invalid provider specified, " + providerName); - } - } - - var providerInfo - = (providerName == "System.Data.SqlServerCe.4.0") - ? ProviderRegistry.SqlCe4_ProviderInfo - : ProviderRegistry.Sql2008_ProviderInfo; - - TContext context = null; - switch (arguments) - { - case DbContextConstructorArgumentType.Parameterless: - context = (TContext)Activator.CreateInstance(typeof(TContext)); - break; - case DbContextConstructorArgumentType.DbCompiledModel: - context = - (TContext) - Activator.CreateInstance( - typeof(TContext), - SimpleModelContext.CreateBuilder().Build(providerInfo).Compile()); - break; - case DbContextConstructorArgumentType.Connection: - context = (TContext)Activator.CreateInstance(typeof(TContext), connection, false); - break; - case DbContextConstructorArgumentType.ConnectionString: - context = (TContext)Activator.CreateInstance(typeof(TContext), connectionString); - break; - case DbContextConstructorArgumentType.ConnectionAndDbCompiledModel: - context = - (TContext) - Activator.CreateInstance( - typeof(TContext), connection, - SimpleModelContext.CreateBuilder().Build(connection).Compile(), false); - break; - case DbContextConstructorArgumentType.ConnectionStringAndDbCompiledModel: - context = - (TContext) - Activator.CreateInstance( - typeof(TContext), connectionString, - SimpleModelContext.CreateBuilder().Build(providerInfo).Compile()); - break; - default: - throw new ArgumentException("Invalid DbContext constructor arguments " + arguments); - } - - return context; - } - - protected void VerifySetsAreInitialized( - DbCompiledModelContents contents, - DbProviderInfo providerInfo = null) - where TContext : SimpleModelContextWithNoData - { - providerInfo = providerInfo ?? ProviderRegistry.Sql2008_ProviderInfo; - - // Arrange - // DbCompiledModel creation as appropriate for the various model content options - var builder = new DbModelBuilder(); - - switch (contents) - { - case DbCompiledModelContents.IsEmpty: - // Do nothing as builder has already been initialized - break; - case DbCompiledModelContents.IsSubset: - // Product is not defined here - builder.Entity(); - break; - case DbCompiledModelContents.IsSuperset: - builder.Entity(); - builder.Entity(); - builder.Entity(); - break; - case DbCompiledModelContents.Match: - builder.Entity(); - builder.Entity(); - break; - case DbCompiledModelContents.DontMatch: - builder.Entity(); - builder.Entity(); - break; - default: - throw new ArgumentException("Invalid DbCompiledModelContents Arguments passed in, " + contents); - } - - var model = builder.Build(providerInfo).Compile(); - - // Act - using (var context = (TContext)Activator.CreateInstance(typeof(TContext), model)) - { - // Verification as appropriate for the various model content options - switch (contents) - { - case DbCompiledModelContents.IsEmpty: - Assert.NotNull(context.Categories); - Assert.NotNull(context.Products); - context.Assert().IsNotInModel(); - context.Assert().IsNotInModel(); - break; - case DbCompiledModelContents.IsSubset: - Assert.NotNull(context.Categories); - Assert.NotNull(context.Products); - context.Assert().IsInModel(); - context.Assert().IsInModel(); // reachability - break; - case DbCompiledModelContents.IsSuperset: - Assert.NotNull(context.Categories); - Assert.NotNull(context.Products); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - break; - case DbCompiledModelContents.Match: - Assert.NotNull(context.Categories); - Assert.NotNull(context.Products); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - context.Assert().IsNotInModel(); - break; - case DbCompiledModelContents.DontMatch: - Assert.NotNull(context.Categories); - Assert.NotNull(context.Products); - context.Assert().IsInModel(); - context.Assert().IsInModel(); - break; - default: - throw new ArgumentException("Invalid DbCompiledModelContents Arguments passed in, " + contents); - } - } - } - - #endregion - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Data.Common; + using System.Data.Entity.Infrastructure; + using System.Globalization; + using System.IO; + using FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns; + using FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel; + using ProductivityApiTests; + using SimpleModel; + using Xunit; + + /// + /// Base class for Productivity API tests that sets up a simple model and some data. + /// Call ClassInitializeBase from the ClassInitialize method of your test class to ensure + /// that the test data is configured. + /// + public class FunctionalTestBase : TestBase + { + #region Test database setup + + protected int AdvancedModelOfficeCount + { + get { return 4; } + } + + protected int AdvancedModelBuildingCount + { + get { return 2; } + } + + protected int AdvancedModelWhiteboardCount + { + get { return 3; } + } + + /// + /// Ensures the database for the context is created and seeded. This is typically used + /// when a test is going to use a transaction to ensure that the DDL happens outside of + /// the transaction. + /// + /// A func to create the context. + protected static void EnsureDatabaseInitialized(Func createContext) + { + using (var context = createContext()) + { + context.Database.Initialize(force: false); + } + } + + /// + /// Drops the database that would be used for the context. Usually used to avoid errors during initialization. + /// + /// A func to create the context. + protected static void DropDatabase(Func createContext) + { + using (var context = createContext()) + { + context.Database.Delete(); + } + } + + /// + /// Drops and then initializes the database that will be used for the context. + /// + /// A func to create the context. + protected static void ResetDatabase(Func createContext) + { + DropDatabase(createContext); + EnsureDatabaseInitialized(createContext); + } + + /// + /// Initializes the metadata files and creates databases for existing CSDL/EDMX files. + /// + protected static void InitializeModelFirstDatabases() + { + const string prefix = "FunctionalTests.ProductivityApi.TemplateModels.Schemas."; + ResourceUtilities.CopyEmbeddedResourcesToCurrentDir( + typeof(TemplateTests).Assembly, + prefix, + /*overwrite*/ true, + "AdvancedPatterns.edmx", + "MonsterModel.csdl", + "MonsterModel.msl", + "MonsterModel.ssdl"); + + // Extract the csdl, msl, and ssdl from the edmx so that they can be referenced in the connection string. + ModelHelpers.WriteMetadataFiles(File.ReadAllText(@".\AdvancedPatterns.edmx"), @".\AdvancedPatterns"); + + using (var context = new AdvancedPatternsModelFirstContext()) + { + context.Database.Initialize(force: false); + } + + using (var context = new MonsterModel()) + { + Database.SetInitializer(new DropCreateDatabaseAlways()); + context.Database.Initialize(force: false); + } + } + + private static bool _metadataForSimpleModelCreated; + + /// + /// Creates the metadata files (CSDL/SSDL/MSL) for the SimpleModelContext. + /// + protected static void CreateMetadataFilesForSimpleModel() + { + if (!_metadataForSimpleModelCreated) + { + var builder = SimpleModelContext.CreateBuilder(); + ModelHelpers.WriteMetadataFiles(builder, @".\SimpleModel"); + + using (var connection = SimpleConnection()) + { + new SimpleModelContext(connection, builder.Build(connection).Compile()).Database.Initialize(false); + } + + _metadataForSimpleModelCreated = true; + } + } + + private static string _simpleModelEntityConnectionString; + + /// + /// An entity connection string for the SimpleModelContext. + /// + protected static string SimpleModelEntityConnectionString + { + get + { + const string baseConnectionString = + @"metadata=.\SimpleModel.csdl|.\SimpleModel.ssdl|.\SimpleModel.msl; + provider=System.Data.SqlClient;provider connection string='{0}'"; + return _simpleModelEntityConnectionString ?? + (_simpleModelEntityConnectionString = + String.Format( + CultureInfo.InvariantCulture, baseConnectionString, + SimpleConnectionString())); + } + } + + #endregion + + #region Construction helpers + + protected static TContext CreateContext( + DbContextConstructorArgumentType arguments, + string providerName = "System.Data.SqlClient") + where TContext : DbContext + { + DbConnection connection = null; + if (arguments == DbContextConstructorArgumentType.Connection + || + arguments == DbContextConstructorArgumentType.ConnectionAndDbCompiledModel) + { + if (providerName == "System.Data.SqlClient") + { + connection = SimpleConnection(); + } + else if (providerName == "System.Data.SqlServerCe.4.0") + { + connection = SimpleCeConnection(); + } + else + { + throw new ArgumentException("Invalid provider specified, " + providerName); + } + } + + string connectionString = null; + if (arguments == DbContextConstructorArgumentType.ConnectionString + || + arguments == DbContextConstructorArgumentType.ConnectionStringAndDbCompiledModel) + { + if (providerName == "System.Data.SqlClient") + { + connectionString = SimpleConnectionString(); + } + else if (providerName == "System.Data.SqlServerCe.4.0") + { + connectionString = SimpleCeConnectionString(); + } + else + { + throw new ArgumentException("Invalid provider specified, " + providerName); + } + } + + var providerInfo + = (providerName == "System.Data.SqlServerCe.4.0") + ? ProviderRegistry.SqlCe4_ProviderInfo + : ProviderRegistry.Sql2008_ProviderInfo; + + TContext context = null; + switch (arguments) + { + case DbContextConstructorArgumentType.Parameterless: + context = (TContext)Activator.CreateInstance(typeof(TContext)); + break; + case DbContextConstructorArgumentType.DbCompiledModel: + context = + (TContext) + Activator.CreateInstance( + typeof(TContext), + SimpleModelContext.CreateBuilder().Build(providerInfo).Compile()); + break; + case DbContextConstructorArgumentType.Connection: + context = (TContext)Activator.CreateInstance(typeof(TContext), connection, false); + break; + case DbContextConstructorArgumentType.ConnectionString: + context = (TContext)Activator.CreateInstance(typeof(TContext), connectionString); + break; + case DbContextConstructorArgumentType.ConnectionAndDbCompiledModel: + context = + (TContext) + Activator.CreateInstance( + typeof(TContext), connection, + SimpleModelContext.CreateBuilder().Build(connection).Compile(), false); + break; + case DbContextConstructorArgumentType.ConnectionStringAndDbCompiledModel: + context = + (TContext) + Activator.CreateInstance( + typeof(TContext), connectionString, + SimpleModelContext.CreateBuilder().Build(providerInfo).Compile()); + break; + default: + throw new ArgumentException("Invalid DbContext constructor arguments " + arguments); + } + + return context; + } + + protected void VerifySetsAreInitialized( + DbCompiledModelContents contents, + DbProviderInfo providerInfo = null) + where TContext : SimpleModelContextWithNoData + { + providerInfo = providerInfo ?? ProviderRegistry.Sql2008_ProviderInfo; + + // Arrange + // DbCompiledModel creation as appropriate for the various model content options + var builder = new DbModelBuilder(); + + switch (contents) + { + case DbCompiledModelContents.IsEmpty: + // Do nothing as builder has already been initialized + break; + case DbCompiledModelContents.IsSubset: + // Product is not defined here + builder.Entity(); + break; + case DbCompiledModelContents.IsSuperset: + builder.Entity(); + builder.Entity(); + builder.Entity(); + break; + case DbCompiledModelContents.Match: + builder.Entity(); + builder.Entity(); + break; + case DbCompiledModelContents.DontMatch: + builder.Entity(); + builder.Entity(); + break; + default: + throw new ArgumentException("Invalid DbCompiledModelContents Arguments passed in, " + contents); + } + + var model = builder.Build(providerInfo).Compile(); + + // Act + using (var context = (TContext)Activator.CreateInstance(typeof(TContext), model)) + { + // Verification as appropriate for the various model content options + switch (contents) + { + case DbCompiledModelContents.IsEmpty: + Assert.NotNull(context.Categories); + Assert.NotNull(context.Products); + context.Assert().IsNotInModel(); + context.Assert().IsNotInModel(); + break; + case DbCompiledModelContents.IsSubset: + Assert.NotNull(context.Categories); + Assert.NotNull(context.Products); + context.Assert().IsInModel(); + context.Assert().IsInModel(); // reachability + break; + case DbCompiledModelContents.IsSuperset: + Assert.NotNull(context.Categories); + Assert.NotNull(context.Products); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + break; + case DbCompiledModelContents.Match: + Assert.NotNull(context.Categories); + Assert.NotNull(context.Products); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + context.Assert().IsNotInModel(); + break; + case DbCompiledModelContents.DontMatch: + Assert.NotNull(context.Categories); + Assert.NotNull(context.Products); + context.Assert().IsInModel(); + context.Assert().IsInModel(); + break; + default: + throw new ArgumentException("Invalid DbCompiledModelContents Arguments passed in, " + contents); + } + } + } + + #endregion + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/FunctionalTestsConfiguration.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/FunctionalTestsConfiguration.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestHelpers/FunctionalTestsConfiguration.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/FunctionalTestsConfiguration.cs diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/FunctionalTestsManifestTokenService.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/FunctionalTestsManifestTokenService.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/FunctionalTestsManifestTokenService.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/FunctionalTestsManifestTokenService.cs index 88887896..431aae1f 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/FunctionalTestsManifestTokenService.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/FunctionalTestsManifestTokenService.cs @@ -1,21 +1,21 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.TestHelpers -{ - using System.Data.Common; - using System.Data.Entity.Infrastructure; - using System.Data.SqlClient; - - public class FunctionalTestsManifestTokenService : IManifestTokenService - { - private static readonly DefaultManifestTokenService _defaultManifestTokenService = new DefaultManifestTokenService(); - - public string GetProviderManifestToken(DbConnection connection) - { - return !string.IsNullOrWhiteSpace(connection.Database) // Some negative cases require the provider to fail - && connection is SqlConnection - ? "2008" - : _defaultManifestTokenService.GetProviderManifestToken(connection); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.TestHelpers +{ + using System.Data.Common; + using System.Data.Entity.Infrastructure; + using System.Data.SqlClient; + + public class FunctionalTestsManifestTokenService : IManifestTokenService + { + private static readonly DefaultManifestTokenService _defaultManifestTokenService = new DefaultManifestTokenService(); + + public string GetProviderManifestToken(DbConnection connection) + { + return !string.IsNullOrWhiteSpace(connection.Database) // Some negative cases require the provider to fail + && connection is SqlConnection + ? "2008" + : _defaultManifestTokenService.GetProviderManifestToken(connection); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/HashSetBasedDbSet.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/HashSetBasedDbSet.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestHelpers/HashSetBasedDbSet.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/HashSetBasedDbSet.cs index 4681ca55..26686220 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/HashSetBasedDbSet.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/HashSetBasedDbSet.cs @@ -1,109 +1,109 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Collections; - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.Linq; - using System.Linq.Expressions; - using System.Threading; - using System.Threading.Tasks; - - /// - /// In-memory implementation of IDbSet based on a - /// - /// Type of elements to be stored in the set - public class HashSetBasedDbSet : IDbSet - where T : class, new() - { - private readonly HashSet _data; - private readonly IQueryable _query; - private readonly Func, T> _findFunc; - - public HashSetBasedDbSet() - : this(null) - { - } - - public HashSetBasedDbSet(Func, T> findFunc) - { - _data = new HashSet(); - _query = _data.AsQueryable(); - _findFunc = findFunc; - } - - public T Find(params object[] keyValues) - { - if (_findFunc == null) - { - throw new NotSupportedException("If you want to call find then use the constructor that specifies a find func."); - } - - return _findFunc(_data); - } - - public Task FindAsync(CancellationToken cancellationToken, params object[] keyValues) - { - throw new NotImplementedException(); - } - - public T Add(T item) - { - _data.Add(item); - return item; - } - - public T Remove(T item) - { - _data.Remove(item); - return item; - } - - public T Attach(T item) - { - _data.Add(item); - return item; - } - - Type IQueryable.ElementType - { - get { return _query.ElementType; } - } - - Expression IQueryable.Expression - { - get { return _query.Expression; } - } - - IQueryProvider IQueryable.Provider - { - get { return _query.Provider; } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _data.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _data.GetEnumerator(); - } - - public ObservableCollection Local - { - get { return new ObservableCollection(_data); } - } - - public T Create() - { - return new T(); - } - - public TDerivedEntity Create() where TDerivedEntity : class, T - { - throw new NotImplementedException(); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Collections; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Linq; + using System.Linq.Expressions; + using System.Threading; + using System.Threading.Tasks; + + /// + /// In-memory implementation of IDbSet based on a + /// + /// Type of elements to be stored in the set + public class HashSetBasedDbSet : IDbSet + where T : class, new() + { + private readonly HashSet _data; + private readonly IQueryable _query; + private readonly Func, T> _findFunc; + + public HashSetBasedDbSet() + : this(null) + { + } + + public HashSetBasedDbSet(Func, T> findFunc) + { + _data = new HashSet(); + _query = _data.AsQueryable(); + _findFunc = findFunc; + } + + public T Find(params object[] keyValues) + { + if (_findFunc == null) + { + throw new NotSupportedException("If you want to call find then use the constructor that specifies a find func."); + } + + return _findFunc(_data); + } + + public Task FindAsync(CancellationToken cancellationToken, params object[] keyValues) + { + throw new NotImplementedException(); + } + + public T Add(T item) + { + _data.Add(item); + return item; + } + + public T Remove(T item) + { + _data.Remove(item); + return item; + } + + public T Attach(T item) + { + _data.Add(item); + return item; + } + + Type IQueryable.ElementType + { + get { return _query.ElementType; } + } + + Expression IQueryable.Expression + { + get { return _query.Expression; } + } + + IQueryProvider IQueryable.Provider + { + get { return _query.Provider; } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _data.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _data.GetEnumerator(); + } + + public ObservableCollection Local + { + get { return new ObservableCollection(_data); } + } + + public T Create() + { + return new T(); + } + + public TDerivedEntity Create() where TDerivedEntity : class, T + { + throw new NotImplementedException(); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/IOHelpers.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/IOHelpers.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/IOHelpers.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/IOHelpers.cs index 46f3bd78..0f5c055e 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/IOHelpers.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/IOHelpers.cs @@ -1,288 +1,288 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Reflection; - using System.Security; - using System.Security.Permissions; - using System.Threading; - - /// - /// This class provides utility methods for common I/O tasks not directly supported by .NET Framework BCL, - /// as well as I/O tasks that require elevated privileges. - /// - public static class IOHelpers - { - private const int DefaultCopyBufferSize = 65536; - -#if !SILVERLIGHT - /// - /// Safely determines whether the given path refers to an existing directory on disk. - /// - /// The path to test. - /// True if path refers to an existing directory; otherwise, false. - [SecuritySafeCritical] - // Calling Directory.Exists demands FileIOPermission (Read flag) for the specified path. - [PermissionSet(SecurityAction.Assert, Unrestricted = true)] - public static bool DirectoryExists(string path) - { - return Directory.Exists(path); - } - - /// - /// Creates the specified directory if it doesn't exist or removes all contents of an existing directory. - /// - /// Path to directory to create. - [SecuritySafeCritical] - // Calling Directory.Exists demands FileIOPermission (Read flag) for the specified path. - [PermissionSet(SecurityAction.Assert, Unrestricted = true)] - public static void EnsureDirectoryEmpty(string path) - { - if (Directory.Exists(path)) - { - SafeDeleteDirectory(path); - } - - EnsureDirectoryExists(path); - } - - /// - /// Creates the specified directory if it doesn't exist. - /// - /// Path to directory to create. - [SecuritySafeCritical] - // Calling Directory.Exists and Directory.CreateDirectory demands FileIOPermission (Read | Write) for the specified path. - [PermissionSet(SecurityAction.Assert, Unrestricted = true)] - public static void EnsureDirectoryExists(string path) - { - if (!Directory.Exists(path)) - { - Directory.CreateDirectory(path); - } - } - - /// - /// Safely determines whether the specified file exists. - /// - /// The file to check. - /// True if the caller has the required permissions and path contains the name of an existing file; otherwise, false. This method also returns false if path is null, an invalid path, or a zero-length string. If the caller does not have sufficient permissions to read the specified file, no exception is thrown and the method returns false regardless of the existence of path. - [SecuritySafeCritical] - // Calling File.Exists demands FileIOPermission (Read flag) for the specified path. - [PermissionSet(SecurityAction.Assert, Unrestricted = true)] - public static bool FileExists(string path) - { - return File.Exists(path); - } - - /// - /// Safely returns the absolute path for the specified path string. - /// - /// The file or directory for which to obtain absolute path information. - /// A string containing the fully qualified location of path, such as "C:\MyFile.txt". - [SecuritySafeCritical] - // Calling Path.GetFullPath demands FileIOPermission (PathDiscovery flag) for the specified path. - [PermissionSet(SecurityAction.Assert, Unrestricted = true)] - public static string GetFullPath(string path) - { - return Path.GetFullPath(path); - } - - /// - /// Safely deletes the file and ignores any access violation exceptions. - /// - /// The directory to delete. - [SecuritySafeCritical] - // Calling File.Delete demands FileIOPermission (Write flag) for the specified path. - [PermissionSet(SecurityAction.Assert, Unrestricted = true)] - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Need to catch everything here.")] - public static void SafeDeleteFile(string path) - { - try - { - File.Delete(path); - } - catch (Exception) - { - // ignore exceptions - } - } - - /// - /// Safely deletes the directory and ignores any access violation exceptions. - /// - /// The directory to delete. - [SecuritySafeCritical] - // Calling Directory.Delete demands FileIOPermission (Write flag) for the specified path. - [PermissionSet(SecurityAction.Assert, Unrestricted = true)] - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Need to catch everything here.")] - public static void SafeDeleteDirectory(string path) - { - // try different ways of contents of directory, fail after 3 attempts - for (var i = 0; i < 3; ++i) - { - try - { - Directory.Delete(path, true); - - return; - } - catch (Exception) - { - } - - Thread.Sleep(500); - - try - { - foreach (var file in Directory.GetFiles(path, "*", SearchOption.AllDirectories)) - { - SafeDeleteFile(file); - } - - return; - } - catch (Exception) - { - } - - Thread.Sleep(500); - } - } - - /// - /// Creates a uniquely named, empty temporary directory on disk and returns the - /// full path of that directory. - /// - /// A containing the full path of the temporary directory. - public static string GetTempDirName() - { - var tempDir = Path.GetTempFileName(); - File.Delete(tempDir); - Directory.CreateDirectory(tempDir); - - return tempDir; - } - - /// - /// Copies the specified source files to a given directory. - /// - /// The destination directory. - /// The source files. - [SecuritySafeCritical] - // Calling File.Copy demands FileIOPermission (Write flag) for the destination file path. - [PermissionSet(SecurityAction.Assert, Unrestricted = true)] - public static void CopyToDirectory(string destinationDirectory, params string[] sourceFiles) - { - foreach (var sourceFile in sourceFiles) - { - var baseName = Path.GetFileName(sourceFile); - var destinationFile = Path.Combine(destinationDirectory, baseName); - - if (new FileInfo(sourceFile).FullName - != new FileInfo(destinationFile).FullName) - { - File.Copy(sourceFile, destinationFile, true); - } - } - } -#endif - - public static void CopyToDir(string sourceFileName, string destDirName) - { - File.Copy( - sourceFileName, - Path.Combine( - destDirName, - Path.GetFileName(sourceFileName))); - } - - /// - /// Copies contents of one stream into another. - /// - /// Stream to read from. - /// Stream to write to. - /// The number of bytes copied from the source. - public static int CopyStream(Stream source, Stream destination) - { - return CopyStream(source, destination, new byte[DefaultCopyBufferSize]); - } - - /// - /// Copies contents of one stream into another. - /// - /// Stream to read from. - /// Stream to write to. - /// The copy buffer. - /// The number of bytes copied from the source. - public static int CopyStream(Stream source, Stream destination, byte[] copyBuffer) - { - ExceptionHelpers.CheckArgumentNotNull(source, "source"); - ExceptionHelpers.CheckArgumentNotNull(destination, "destination"); - ExceptionHelpers.CheckArgumentNotNull(copyBuffer, "copyBuffer"); - - var bytesCopied = 0; - int bytesRead; - - do - { - bytesRead = source.Read(copyBuffer, 0, copyBuffer.Length); - destination.Write(copyBuffer, 0, bytesRead); - bytesCopied += bytesRead; - } - while (bytesRead != 0); - - return bytesCopied; - } - - /// - /// Write an embedded resource to a local file - /// - /// Resource to be written - /// File to write resource to - /// Assembly to extract resource from -#if !SILVERLIGHT - [SecuritySafeCritical] - // Calling File.Open demands FileIOPermission (Append flag) for the destination file path. - [PermissionSet(SecurityAction.Assert, Unrestricted = true)] -#endif - public static void WriteResourceToFile(string resourceName, string fileName, Assembly assembly) - { - using (var resourceStream = assembly.GetManifestResourceStream(resourceName)) - { - if (resourceStream == null) - { - throw new IOException("Resource '" + resourceName + "' not found in '" + assembly.FullName + "'"); - } - - using (var fileStream = File.Open(fileName, FileMode.Append)) - { - CopyStream(resourceStream, fileStream); - } - } - } - -#if !SILVERLIGHT - /// - /// Adds the given set of file attributes to the file at the given path - /// - /// The name/path of the file - /// The bit-field of attributes to add - public static void AddFileAttributes(string fileName, FileAttributes toAdd) - { - File.SetAttributes(fileName, File.GetAttributes(fileName) | toAdd); - } - - /// - /// Removes the given set of file attributes from the file at the given path - /// - /// The name/path of the file - /// The bit-field of attributes to remove - public static void RemoveFileAttributes(string fileName, FileAttributes toRemove) - { - File.SetAttributes(fileName, File.GetAttributes(fileName) & ~toRemove); - } -#endif - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Diagnostics.CodeAnalysis; + using System.IO; + using System.Reflection; + using System.Security; + using System.Security.Permissions; + using System.Threading; + + /// + /// This class provides utility methods for common I/O tasks not directly supported by .NET Framework BCL, + /// as well as I/O tasks that require elevated privileges. + /// + public static class IOHelpers + { + private const int DefaultCopyBufferSize = 65536; + +#if !SILVERLIGHT + /// + /// Safely determines whether the given path refers to an existing directory on disk. + /// + /// The path to test. + /// True if path refers to an existing directory; otherwise, false. + [SecuritySafeCritical] + // Calling Directory.Exists demands FileIOPermission (Read flag) for the specified path. + [PermissionSet(SecurityAction.Assert, Unrestricted = true)] + public static bool DirectoryExists(string path) + { + return Directory.Exists(path); + } + + /// + /// Creates the specified directory if it doesn't exist or removes all contents of an existing directory. + /// + /// Path to directory to create. + [SecuritySafeCritical] + // Calling Directory.Exists demands FileIOPermission (Read flag) for the specified path. + [PermissionSet(SecurityAction.Assert, Unrestricted = true)] + public static void EnsureDirectoryEmpty(string path) + { + if (Directory.Exists(path)) + { + SafeDeleteDirectory(path); + } + + EnsureDirectoryExists(path); + } + + /// + /// Creates the specified directory if it doesn't exist. + /// + /// Path to directory to create. + [SecuritySafeCritical] + // Calling Directory.Exists and Directory.CreateDirectory demands FileIOPermission (Read | Write) for the specified path. + [PermissionSet(SecurityAction.Assert, Unrestricted = true)] + public static void EnsureDirectoryExists(string path) + { + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } + } + + /// + /// Safely determines whether the specified file exists. + /// + /// The file to check. + /// True if the caller has the required permissions and path contains the name of an existing file; otherwise, false. This method also returns false if path is null, an invalid path, or a zero-length string. If the caller does not have sufficient permissions to read the specified file, no exception is thrown and the method returns false regardless of the existence of path. + [SecuritySafeCritical] + // Calling File.Exists demands FileIOPermission (Read flag) for the specified path. + [PermissionSet(SecurityAction.Assert, Unrestricted = true)] + public static bool FileExists(string path) + { + return File.Exists(path); + } + + /// + /// Safely returns the absolute path for the specified path string. + /// + /// The file or directory for which to obtain absolute path information. + /// A string containing the fully qualified location of path, such as "C:\MyFile.txt". + [SecuritySafeCritical] + // Calling Path.GetFullPath demands FileIOPermission (PathDiscovery flag) for the specified path. + [PermissionSet(SecurityAction.Assert, Unrestricted = true)] + public static string GetFullPath(string path) + { + return Path.GetFullPath(path); + } + + /// + /// Safely deletes the file and ignores any access violation exceptions. + /// + /// The directory to delete. + [SecuritySafeCritical] + // Calling File.Delete demands FileIOPermission (Write flag) for the specified path. + [PermissionSet(SecurityAction.Assert, Unrestricted = true)] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Need to catch everything here.")] + public static void SafeDeleteFile(string path) + { + try + { + File.Delete(path); + } + catch (Exception) + { + // ignore exceptions + } + } + + /// + /// Safely deletes the directory and ignores any access violation exceptions. + /// + /// The directory to delete. + [SecuritySafeCritical] + // Calling Directory.Delete demands FileIOPermission (Write flag) for the specified path. + [PermissionSet(SecurityAction.Assert, Unrestricted = true)] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Need to catch everything here.")] + public static void SafeDeleteDirectory(string path) + { + // try different ways of contents of directory, fail after 3 attempts + for (var i = 0; i < 3; ++i) + { + try + { + Directory.Delete(path, true); + + return; + } + catch (Exception) + { + } + + Thread.Sleep(500); + + try + { + foreach (var file in Directory.GetFiles(path, "*", SearchOption.AllDirectories)) + { + SafeDeleteFile(file); + } + + return; + } + catch (Exception) + { + } + + Thread.Sleep(500); + } + } + + /// + /// Creates a uniquely named, empty temporary directory on disk and returns the + /// full path of that directory. + /// + /// A containing the full path of the temporary directory. + public static string GetTempDirName() + { + var tempDir = Path.GetTempFileName(); + File.Delete(tempDir); + Directory.CreateDirectory(tempDir); + + return tempDir; + } + + /// + /// Copies the specified source files to a given directory. + /// + /// The destination directory. + /// The source files. + [SecuritySafeCritical] + // Calling File.Copy demands FileIOPermission (Write flag) for the destination file path. + [PermissionSet(SecurityAction.Assert, Unrestricted = true)] + public static void CopyToDirectory(string destinationDirectory, params string[] sourceFiles) + { + foreach (var sourceFile in sourceFiles) + { + var baseName = Path.GetFileName(sourceFile); + var destinationFile = Path.Combine(destinationDirectory, baseName); + + if (new FileInfo(sourceFile).FullName + != new FileInfo(destinationFile).FullName) + { + File.Copy(sourceFile, destinationFile, true); + } + } + } +#endif + + public static void CopyToDir(string sourceFileName, string destDirName) + { + File.Copy( + sourceFileName, + Path.Combine( + destDirName, + Path.GetFileName(sourceFileName))); + } + + /// + /// Copies contents of one stream into another. + /// + /// Stream to read from. + /// Stream to write to. + /// The number of bytes copied from the source. + public static int CopyStream(Stream source, Stream destination) + { + return CopyStream(source, destination, new byte[DefaultCopyBufferSize]); + } + + /// + /// Copies contents of one stream into another. + /// + /// Stream to read from. + /// Stream to write to. + /// The copy buffer. + /// The number of bytes copied from the source. + public static int CopyStream(Stream source, Stream destination, byte[] copyBuffer) + { + ExceptionHelpers.CheckArgumentNotNull(source, "source"); + ExceptionHelpers.CheckArgumentNotNull(destination, "destination"); + ExceptionHelpers.CheckArgumentNotNull(copyBuffer, "copyBuffer"); + + var bytesCopied = 0; + int bytesRead; + + do + { + bytesRead = source.Read(copyBuffer, 0, copyBuffer.Length); + destination.Write(copyBuffer, 0, bytesRead); + bytesCopied += bytesRead; + } + while (bytesRead != 0); + + return bytesCopied; + } + + /// + /// Write an embedded resource to a local file + /// + /// Resource to be written + /// File to write resource to + /// Assembly to extract resource from +#if !SILVERLIGHT + [SecuritySafeCritical] + // Calling File.Open demands FileIOPermission (Append flag) for the destination file path. + [PermissionSet(SecurityAction.Assert, Unrestricted = true)] +#endif + public static void WriteResourceToFile(string resourceName, string fileName, Assembly assembly) + { + using (var resourceStream = assembly.GetManifestResourceStream(resourceName)) + { + if (resourceStream == null) + { + throw new IOException("Resource '" + resourceName + "' not found in '" + assembly.FullName + "'"); + } + + using (var fileStream = File.Open(fileName, FileMode.Append)) + { + CopyStream(resourceStream, fileStream); + } + } + } + +#if !SILVERLIGHT + /// + /// Adds the given set of file attributes to the file at the given path + /// + /// The name/path of the file + /// The bit-field of attributes to add + public static void AddFileAttributes(string fileName, FileAttributes toAdd) + { + File.SetAttributes(fileName, File.GetAttributes(fileName) | toAdd); + } + + /// + /// Removes the given set of file attributes from the file at the given path + /// + /// The name/path of the file + /// The bit-field of attributes to remove + public static void RemoveFileAttributes(string fileName, FileAttributes toRemove) + { + File.SetAttributes(fileName, File.GetAttributes(fileName) & ~toRemove); + } +#endif + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/ModelAssertions.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ModelAssertions.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/ModelAssertions.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ModelAssertions.cs index 0dc82ca2..da3c95ff 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/ModelAssertions.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ModelAssertions.cs @@ -1,447 +1,447 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Collections.Generic; - using System.Data.Entity.Core.Mapping; - using System.Data.Entity.Core.Metadata; - using System.Data.Entity.Core.Metadata.Edm; - - using System.Data.Entity.ModelConfiguration.Edm; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; - - internal static class ModelAssertions - { - internal static PropertyAssertions Assert( - this DbDatabaseMapping databaseMapping, Expression> propertyExpression) - { - var structuralType - = databaseMapping.Model.NamespaceItems - .OfType() - .Single( - i => i.Annotations.Any( - a => a.Name == "ClrType" - && (Type)a.Value == typeof(TStructuralType))); - - var property - = databaseMapping.Model.NamespaceItems.OfType() - .Where( - i => i.Annotations.Any( - a => a.Name == "ClrType" - && ((Type)a.Value).IsAssignableFrom(typeof(TStructuralType)))) - .SelectMany(th => th.Members.OfType()).Distinct().Single( - i => i.Annotations.Any( - a => a.Name == "ClrPropertyInfo" - && (PropertyInfo)a.Value == GetPropertyInfo(propertyExpression))); - - var columns - = databaseMapping.EntityContainerMappings.Single().EntitySetMappings - .SelectMany(esm => esm.EntityTypeMappings) - .Where(etm => !(structuralType is EntityType) || etm.EntityType == structuralType) - .SelectMany(etm => etm.MappingFragments) - .SelectMany(tmf => tmf.ColumnMappings) - .Where(pm => pm.PropertyPath.Contains(property)) - .Select(pm => pm.ColumnProperty); - - return new PropertyAssertions(property, columns.First()); - } - - internal static TypeAssertions Assert(this DbDatabaseMapping databaseMapping) - { - var structuralType - = databaseMapping.Model.NamespaceItems.OfType().Single( - i => i.Annotations.Any( - a => a.Name == "ClrType" - && (Type)a.Value == typeof(TStructuralType))); - - var table - = databaseMapping.EntityContainerMappings.Single().EntitySetMappings - .SelectMany(esm => esm.EntityTypeMappings) - .Where(etm => etm.EntityType == structuralType) - .SelectMany(etm => etm.MappingFragments) - .Select(tmf => tmf.Table) - .Distinct() - .Single(); - - return new TypeAssertions(table, databaseMapping.Database.GetEntitySet(table), databaseMapping.Database); - } - - internal static TypeAssertions Assert(this DbDatabaseMapping databaseMapping, string tableName) - { - var structuralType - = databaseMapping.Model.NamespaceItems.OfType() - .Single( - i => i.Annotations.Any( - a => a.Name == "ClrType" - && (Type)a.Value == typeof(TStructuralType))); - - var table - = databaseMapping.EntityContainerMappings.Single().EntitySetMappings - .SelectMany(esm => esm.EntityTypeMappings) - .Where(etm => etm.EntityType == structuralType) - .SelectMany(etm => etm.MappingFragments).First( - mf => databaseMapping.Database.GetEntitySet(mf.Table).Table == tableName) - .Table; - - return new TypeAssertions(table, databaseMapping.Database.GetEntitySet(table), databaseMapping.Database); - } - - internal static TypeAssertions Assert( - this DbDatabaseMapping databaseMapping, string tableName, string schemaName = null) - { - var entitySet - = databaseMapping.Database - .GetEntitySets() - .Single( - es => es.Table == tableName - && ((schemaName == null) || es.Schema == schemaName)); - - return new TypeAssertions(entitySet.ElementType, entitySet, databaseMapping.Database); - } - - internal static MappingFragmentAssertions AssertMapping( - this DbDatabaseMapping databaseMapping, - string tableName) - { - var structuralType - = databaseMapping.Model.NamespaceItems.OfType().Single( - i => i.Annotations.Any( - a => a.Name == "ClrType" - && (Type)a.Value == typeof(TStructuralType))); - - var fragments - = databaseMapping.EntityContainerMappings.Single().EntitySetMappings - .SelectMany(esm => esm.EntityTypeMappings) - .Where(etm => etm.EntityType == structuralType) - .SelectMany(etm => etm.MappingFragments) - .Where(mf => databaseMapping.Database.GetEntitySet(mf.Table).Table == tableName) - .ToList(); - - var fragment = fragments.First(); - - Xunit.Assert.True(fragments.All(f => f.Table == fragment.Table)); - - return new MappingFragmentAssertions(fragment); - } - - internal static MappingFragmentAssertions AssertMapping( - this DbDatabaseMapping databaseMapping, - string tableName, bool isTypeOfMapping) - { - var structuralType - = databaseMapping.Model.NamespaceItems.OfType().Single( - i => i.Annotations.Any( - a => a.Name == "ClrType" - && (Type)a.Value == typeof(TStructuralType))); - - var fragment - = databaseMapping.EntityContainerMappings.Single().EntitySetMappings - .SelectMany(esm => esm.EntityTypeMappings) - .Where(etm => etm.EntityType == structuralType && isTypeOfMapping == etm.IsHierarchyMapping) - .SelectMany(etm => etm.MappingFragments) - .Single(mf => databaseMapping.Database.GetEntitySet(mf.Table).Table == tableName); - - return new MappingFragmentAssertions(fragment); - } - - internal static void AssertNoMapping(this DbDatabaseMapping databaseMapping) - { - var structuralType - = databaseMapping.Model.NamespaceItems.OfType().Single( - i => i.Annotations.Any( - a => a.Name == "ClrType" - && (Type)a.Value == typeof(TStructuralType))); - - var fragments - = databaseMapping.EntityContainerMappings.Single().EntitySetMappings - .SelectMany(esm => esm.EntityTypeMappings) - .Where(etm => etm.EntityType == structuralType) - .SelectMany(etm => etm.MappingFragments); - - Xunit.Assert.Equal(0, fragments.Count()); - } - - private static PropertyInfo GetPropertyInfo(LambdaExpression propertyExpression) - { - return (PropertyInfo)((MemberExpression)propertyExpression.Body.RemoveConvert()).Member; - } - - internal class ColumnAssertions - { - private readonly EdmProperty _column; - - public ColumnAssertions(EdmProperty column) - { - _column = column; - } - - public ColumnAssertions DbEqual(object expected, Func facet) - { - Xunit.Assert.Equal(expected, facet(_column)); - - return this; - } - - public ColumnAssertions DbIsFalse(Func column) - { - Xunit.Assert.Equal(false, column(_column)); - - return this; - } - } - - internal class PropertyAssertions - { - private readonly EdmProperty _property; - private readonly EdmProperty _column; - - public PropertyAssertions(EdmProperty property, EdmProperty column) - { - _property = property; - _column = column; - } - - public PropertyAssertions IsTrue(Func facet) - { - Xunit.Assert.Equal(true, facet(_property.TypeUsage)); - - return this; - } - - public PropertyAssertions IsTrue(Func facet) - { - Xunit.Assert.Equal(true, facet(_property)); - - return this; - } - - public PropertyAssertions IsFalse(Func facet) - { - Xunit.Assert.Equal(false, facet(_property.TypeUsage)); - - return this; - } - - public PropertyAssertions IsFalse(Func facet) - { - Xunit.Assert.Equal(false, facet(_property)); - - return this; - } - - public PropertyAssertions DbEqual(object expected, Func facet) - { - Xunit.Assert.Equal(expected, facet(_column)); - - return this; - } - - public PropertyAssertions DbIsFalse(Func column) - { - Xunit.Assert.Equal(false, column(_column)); - - return this; - } - - public PropertyAssertions FacetEqual(object expected, Func facet) - { - Xunit.Assert.Equal(expected, facet(_property.TypeUsage)); - - return this; - } - - public PropertyAssertions FacetEqual(object expected, Func facet) - { - Xunit.Assert.Equal(expected, facet(_property)); - - return this; - } - - public PropertyAssertions MetadataPropertyEqual(object expected, string annotation) - { - Xunit.Assert.Equal( - expected, _property.MetadataProperties - .Single(a => a.Name.Equals(XmlConstants.AnnotationNamespace + ":" + annotation, StringComparison.Ordinal)) - .Value); - - return this; - } - - public PropertyAssertions AnnotationNull(string annotation) - { - Xunit.Assert.Null( - _property.Annotations.SingleOrDefault(a => a.Name.Equals(annotation, StringComparison.Ordinal))); - - return this; - } - } - - internal class TypeAssertions - { - private readonly EntityType _table; - private readonly EntitySet _entitySet; - private readonly EdmModel _database; - - public TypeAssertions(EntityType table, EntitySet entitySet, EdmModel database) - { - _table = table; - _entitySet = entitySet; - _database = database; - } - - public TypeAssertions DbEqual(T expected, Func attribute) - { - Xunit.Assert.Equal(expected, attribute(_table)); - - return this; - } - - public TypeAssertions DbEqual(T expected, Func attribute) - { - Xunit.Assert.Equal(expected, attribute(_entitySet)); - - return this; - } - - public TypeAssertions HasColumns(params string[] columns) - { - Xunit.Assert.True(_table.Properties.Select(c => c.Name).SequenceEqual(columns)); - - return this; - } - - public TypeAssertions HasColumn(string column) - { - Xunit.Assert.True(_table.Properties.Any(c => c.Name == column)); - - return this; - } - - public ColumnAssertions Column(string column) - { - return new ColumnAssertions(_table.Properties.Single(c => c.Name == column)); - } - - public TypeAssertions HasForeignKeyColumn(string column) - { - Xunit.Assert.Equal( - 1, - _table.ForeignKeyBuilders.Count(f => f.DependentColumns.Any(d => d.Name == column))); - - return this; - } - - public TypeAssertions HasForeignKey(IEnumerable columns, string toTable) - { - Xunit.Assert.Equal( - 1, - _table.ForeignKeyBuilders.Count( - f => _database.GetEntitySet(f.PrincipalTable).Table == toTable && - f.DependentColumns.Select(c => c.Name).SequenceEqual(columns))); - - return this; - } - - public TypeAssertions HasForeignKeyColumn(string column, string toTable) - { - Xunit.Assert.Equal( - 1, - _table.ForeignKeyBuilders.Count( - f => _database.GetEntitySet(f.PrincipalTable).Table == toTable && - f.DependentColumns.Any(d => d.Name == column))); - - return this; - } - - public TypeAssertions HasNoForeignKeyColumn(string column) - { - Xunit.Assert.Equal( - 0, - _table.ForeignKeyBuilders.Count(f => f.DependentColumns.Any(d => d.Name == column))); - - return this; - } - - public TypeAssertions HasNoForeignKeyColumns() - { - Xunit.Assert.Equal(0, _table.ForeignKeyBuilders.Count()); - - return this; - } - - public ColumnAssertions ForeignKeyColumn(string column) - { - return - new ColumnAssertions( - _table.ForeignKeyBuilders.SelectMany(f => f.DependentColumns).Single(c => c.Name == column)); - } - } - - internal class MappingFragmentAssertions - { - private readonly StorageMappingFragment _fragment; - - public MappingFragmentAssertions(StorageMappingFragment fragment) - { - _fragment = fragment; - } - - public MappingFragmentAssertions HasColumnCondition(string column, object value) - { - var con = - _fragment.ColumnConditions.Single( - cc => String.Equals(cc.ColumnProperty.Name, column, StringComparison.Ordinal)); - - Xunit.Assert.True(Equals(con.Value, value) && con.IsNull == null); - - return this; - } - - public MappingFragmentAssertions HasNullabilityColumnCondition(string column, bool isNull) - { - Xunit.Assert.True( - _fragment.ColumnConditions.Any( - cc => - String.Equals(cc.ColumnProperty.Name, column, StringComparison.Ordinal) && cc.Value == null && - cc.IsNull == isNull)); - - return this; - } - - public MappingFragmentAssertions HasNoColumnConditions() - { - Xunit.Assert.True(!_fragment.ColumnConditions.Any()); - - return this; - } - - public MappingFragmentAssertions HasNoColumnCondition(string column) - { - Xunit.Assert.True( - !_fragment.ColumnConditions.Any( - cc => String.Equals(cc.ColumnProperty.Name, column, StringComparison.Ordinal))); - - return this; - } - - public MappingFragmentAssertions HasNoPropertyConditions() - { - return this; - } - } - - private static Expression RemoveConvert(this Expression expression) - { - while ((expression != null) - && (expression.NodeType == ExpressionType.Convert - || expression.NodeType == ExpressionType.ConvertChecked)) - { - expression = RemoveConvert(((UnaryExpression)expression).Operand); - } - - return expression; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Collections.Generic; + using System.Data.Entity.Core.Mapping; + using System.Data.Entity.Core.Metadata; + using System.Data.Entity.Core.Metadata.Edm; + + using System.Data.Entity.ModelConfiguration.Edm; + using System.Linq; + using System.Linq.Expressions; + using System.Reflection; + + internal static class ModelAssertions + { + internal static PropertyAssertions Assert( + this DbDatabaseMapping databaseMapping, Expression> propertyExpression) + { + var structuralType + = databaseMapping.Model.NamespaceItems + .OfType() + .Single( + i => i.Annotations.Any( + a => a.Name == "ClrType" + && (Type)a.Value == typeof(TStructuralType))); + + var property + = databaseMapping.Model.NamespaceItems.OfType() + .Where( + i => i.Annotations.Any( + a => a.Name == "ClrType" + && ((Type)a.Value).IsAssignableFrom(typeof(TStructuralType)))) + .SelectMany(th => th.Members.OfType()).Distinct().Single( + i => i.Annotations.Any( + a => a.Name == "ClrPropertyInfo" + && (PropertyInfo)a.Value == GetPropertyInfo(propertyExpression))); + + var columns + = databaseMapping.EntityContainerMappings.Single().EntitySetMappings + .SelectMany(esm => esm.EntityTypeMappings) + .Where(etm => !(structuralType is EntityType) || etm.EntityType == structuralType) + .SelectMany(etm => etm.MappingFragments) + .SelectMany(tmf => tmf.ColumnMappings) + .Where(pm => pm.PropertyPath.Contains(property)) + .Select(pm => pm.ColumnProperty); + + return new PropertyAssertions(property, columns.First()); + } + + internal static TypeAssertions Assert(this DbDatabaseMapping databaseMapping) + { + var structuralType + = databaseMapping.Model.NamespaceItems.OfType().Single( + i => i.Annotations.Any( + a => a.Name == "ClrType" + && (Type)a.Value == typeof(TStructuralType))); + + var table + = databaseMapping.EntityContainerMappings.Single().EntitySetMappings + .SelectMany(esm => esm.EntityTypeMappings) + .Where(etm => etm.EntityType == structuralType) + .SelectMany(etm => etm.MappingFragments) + .Select(tmf => tmf.Table) + .Distinct() + .Single(); + + return new TypeAssertions(table, databaseMapping.Database.GetEntitySet(table), databaseMapping.Database); + } + + internal static TypeAssertions Assert(this DbDatabaseMapping databaseMapping, string tableName) + { + var structuralType + = databaseMapping.Model.NamespaceItems.OfType() + .Single( + i => i.Annotations.Any( + a => a.Name == "ClrType" + && (Type)a.Value == typeof(TStructuralType))); + + var table + = databaseMapping.EntityContainerMappings.Single().EntitySetMappings + .SelectMany(esm => esm.EntityTypeMappings) + .Where(etm => etm.EntityType == structuralType) + .SelectMany(etm => etm.MappingFragments).First( + mf => databaseMapping.Database.GetEntitySet(mf.Table).Table == tableName) + .Table; + + return new TypeAssertions(table, databaseMapping.Database.GetEntitySet(table), databaseMapping.Database); + } + + internal static TypeAssertions Assert( + this DbDatabaseMapping databaseMapping, string tableName, string schemaName = null) + { + var entitySet + = databaseMapping.Database + .GetEntitySets() + .Single( + es => es.Table == tableName + && ((schemaName == null) || es.Schema == schemaName)); + + return new TypeAssertions(entitySet.ElementType, entitySet, databaseMapping.Database); + } + + internal static MappingFragmentAssertions AssertMapping( + this DbDatabaseMapping databaseMapping, + string tableName) + { + var structuralType + = databaseMapping.Model.NamespaceItems.OfType().Single( + i => i.Annotations.Any( + a => a.Name == "ClrType" + && (Type)a.Value == typeof(TStructuralType))); + + var fragments + = databaseMapping.EntityContainerMappings.Single().EntitySetMappings + .SelectMany(esm => esm.EntityTypeMappings) + .Where(etm => etm.EntityType == structuralType) + .SelectMany(etm => etm.MappingFragments) + .Where(mf => databaseMapping.Database.GetEntitySet(mf.Table).Table == tableName) + .ToList(); + + var fragment = fragments.First(); + + Xunit.Assert.True(fragments.All(f => f.Table == fragment.Table)); + + return new MappingFragmentAssertions(fragment); + } + + internal static MappingFragmentAssertions AssertMapping( + this DbDatabaseMapping databaseMapping, + string tableName, bool isTypeOfMapping) + { + var structuralType + = databaseMapping.Model.NamespaceItems.OfType().Single( + i => i.Annotations.Any( + a => a.Name == "ClrType" + && (Type)a.Value == typeof(TStructuralType))); + + var fragment + = databaseMapping.EntityContainerMappings.Single().EntitySetMappings + .SelectMany(esm => esm.EntityTypeMappings) + .Where(etm => etm.EntityType == structuralType && isTypeOfMapping == etm.IsHierarchyMapping) + .SelectMany(etm => etm.MappingFragments) + .Single(mf => databaseMapping.Database.GetEntitySet(mf.Table).Table == tableName); + + return new MappingFragmentAssertions(fragment); + } + + internal static void AssertNoMapping(this DbDatabaseMapping databaseMapping) + { + var structuralType + = databaseMapping.Model.NamespaceItems.OfType().Single( + i => i.Annotations.Any( + a => a.Name == "ClrType" + && (Type)a.Value == typeof(TStructuralType))); + + var fragments + = databaseMapping.EntityContainerMappings.Single().EntitySetMappings + .SelectMany(esm => esm.EntityTypeMappings) + .Where(etm => etm.EntityType == structuralType) + .SelectMany(etm => etm.MappingFragments); + + Xunit.Assert.Equal(0, fragments.Count()); + } + + private static PropertyInfo GetPropertyInfo(LambdaExpression propertyExpression) + { + return (PropertyInfo)((MemberExpression)propertyExpression.Body.RemoveConvert()).Member; + } + + internal class ColumnAssertions + { + private readonly EdmProperty _column; + + public ColumnAssertions(EdmProperty column) + { + _column = column; + } + + public ColumnAssertions DbEqual(object expected, Func facet) + { + Xunit.Assert.Equal(expected, facet(_column)); + + return this; + } + + public ColumnAssertions DbIsFalse(Func column) + { + Xunit.Assert.Equal(false, column(_column)); + + return this; + } + } + + internal class PropertyAssertions + { + private readonly EdmProperty _property; + private readonly EdmProperty _column; + + public PropertyAssertions(EdmProperty property, EdmProperty column) + { + _property = property; + _column = column; + } + + public PropertyAssertions IsTrue(Func facet) + { + Xunit.Assert.Equal(true, facet(_property.TypeUsage)); + + return this; + } + + public PropertyAssertions IsTrue(Func facet) + { + Xunit.Assert.Equal(true, facet(_property)); + + return this; + } + + public PropertyAssertions IsFalse(Func facet) + { + Xunit.Assert.Equal(false, facet(_property.TypeUsage)); + + return this; + } + + public PropertyAssertions IsFalse(Func facet) + { + Xunit.Assert.Equal(false, facet(_property)); + + return this; + } + + public PropertyAssertions DbEqual(object expected, Func facet) + { + Xunit.Assert.Equal(expected, facet(_column)); + + return this; + } + + public PropertyAssertions DbIsFalse(Func column) + { + Xunit.Assert.Equal(false, column(_column)); + + return this; + } + + public PropertyAssertions FacetEqual(object expected, Func facet) + { + Xunit.Assert.Equal(expected, facet(_property.TypeUsage)); + + return this; + } + + public PropertyAssertions FacetEqual(object expected, Func facet) + { + Xunit.Assert.Equal(expected, facet(_property)); + + return this; + } + + public PropertyAssertions MetadataPropertyEqual(object expected, string annotation) + { + Xunit.Assert.Equal( + expected, _property.MetadataProperties + .Single(a => a.Name.Equals(XmlConstants.AnnotationNamespace + ":" + annotation, StringComparison.Ordinal)) + .Value); + + return this; + } + + public PropertyAssertions AnnotationNull(string annotation) + { + Xunit.Assert.Null( + _property.Annotations.SingleOrDefault(a => a.Name.Equals(annotation, StringComparison.Ordinal))); + + return this; + } + } + + internal class TypeAssertions + { + private readonly EntityType _table; + private readonly EntitySet _entitySet; + private readonly EdmModel _database; + + public TypeAssertions(EntityType table, EntitySet entitySet, EdmModel database) + { + _table = table; + _entitySet = entitySet; + _database = database; + } + + public TypeAssertions DbEqual(T expected, Func attribute) + { + Xunit.Assert.Equal(expected, attribute(_table)); + + return this; + } + + public TypeAssertions DbEqual(T expected, Func attribute) + { + Xunit.Assert.Equal(expected, attribute(_entitySet)); + + return this; + } + + public TypeAssertions HasColumns(params string[] columns) + { + Xunit.Assert.True(_table.Properties.Select(c => c.Name).SequenceEqual(columns)); + + return this; + } + + public TypeAssertions HasColumn(string column) + { + Xunit.Assert.True(_table.Properties.Any(c => c.Name == column)); + + return this; + } + + public ColumnAssertions Column(string column) + { + return new ColumnAssertions(_table.Properties.Single(c => c.Name == column)); + } + + public TypeAssertions HasForeignKeyColumn(string column) + { + Xunit.Assert.Equal( + 1, + _table.ForeignKeyBuilders.Count(f => f.DependentColumns.Any(d => d.Name == column))); + + return this; + } + + public TypeAssertions HasForeignKey(IEnumerable columns, string toTable) + { + Xunit.Assert.Equal( + 1, + _table.ForeignKeyBuilders.Count( + f => _database.GetEntitySet(f.PrincipalTable).Table == toTable && + f.DependentColumns.Select(c => c.Name).SequenceEqual(columns))); + + return this; + } + + public TypeAssertions HasForeignKeyColumn(string column, string toTable) + { + Xunit.Assert.Equal( + 1, + _table.ForeignKeyBuilders.Count( + f => _database.GetEntitySet(f.PrincipalTable).Table == toTable && + f.DependentColumns.Any(d => d.Name == column))); + + return this; + } + + public TypeAssertions HasNoForeignKeyColumn(string column) + { + Xunit.Assert.Equal( + 0, + _table.ForeignKeyBuilders.Count(f => f.DependentColumns.Any(d => d.Name == column))); + + return this; + } + + public TypeAssertions HasNoForeignKeyColumns() + { + Xunit.Assert.Equal(0, _table.ForeignKeyBuilders.Count()); + + return this; + } + + public ColumnAssertions ForeignKeyColumn(string column) + { + return + new ColumnAssertions( + _table.ForeignKeyBuilders.SelectMany(f => f.DependentColumns).Single(c => c.Name == column)); + } + } + + internal class MappingFragmentAssertions + { + private readonly StorageMappingFragment _fragment; + + public MappingFragmentAssertions(StorageMappingFragment fragment) + { + _fragment = fragment; + } + + public MappingFragmentAssertions HasColumnCondition(string column, object value) + { + var con = + _fragment.ColumnConditions.Single( + cc => String.Equals(cc.ColumnProperty.Name, column, StringComparison.Ordinal)); + + Xunit.Assert.True(Equals(con.Value, value) && con.IsNull == null); + + return this; + } + + public MappingFragmentAssertions HasNullabilityColumnCondition(string column, bool isNull) + { + Xunit.Assert.True( + _fragment.ColumnConditions.Any( + cc => + String.Equals(cc.ColumnProperty.Name, column, StringComparison.Ordinal) && cc.Value == null && + cc.IsNull == isNull)); + + return this; + } + + public MappingFragmentAssertions HasNoColumnConditions() + { + Xunit.Assert.True(!_fragment.ColumnConditions.Any()); + + return this; + } + + public MappingFragmentAssertions HasNoColumnCondition(string column) + { + Xunit.Assert.True( + !_fragment.ColumnConditions.Any( + cc => String.Equals(cc.ColumnProperty.Name, column, StringComparison.Ordinal))); + + return this; + } + + public MappingFragmentAssertions HasNoPropertyConditions() + { + return this; + } + } + + private static Expression RemoveConvert(this Expression expression) + { + while ((expression != null) + && (expression.NodeType == ExpressionType.Convert + || expression.NodeType == ExpressionType.ConvertChecked)) + { + expression = RemoveConvert(((UnaryExpression)expression).Operand); + } + + return expression; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/ModelHelpers.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ModelHelpers.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/ModelHelpers.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ModelHelpers.cs index f1a2c224..7189a4a5 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/ModelHelpers.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ModelHelpers.cs @@ -1,418 +1,418 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Collections.Generic; - using System.Configuration; - using System.Data.Common; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.Core.Objects; - using System.Data.Entity.Infrastructure; - using System.Data.SqlClient; - using System.Diagnostics; - using System.Globalization; - using System.IO; - using System.Linq; - using System.Text; - using System.Xml; - using System.Xml.Linq; - using Xunit; - - public static class ModelHelpers - { - #region State entry helpers - - /// - /// Gets all GetStateEntries for the given DbContext. - /// - /// A DbContext instance. - /// All state entries in the ObjectStateManager. - public static IEnumerable GetStateEntries(DbContext dbContext) - { - return GetStateEntries(TestBase.GetObjectContext(dbContext)); - } - - /// - /// Gets all GetStateEntries for the given ObjectContext. - /// - /// A ObjectContext instance. - /// All state entries in the ObjectStateManager. - public static IEnumerable GetStateEntries(ObjectContext objectContext) - { - return objectContext.ObjectStateManager.GetObjectStateEntries(~EntityState.Detached); - } - - /// - /// Gets the ObjectStateEntry for the given entity in the given DbContext. - /// - /// A DbContext instance. - /// The entity to lookup. - /// The ObjectStateEntry. - public static ObjectStateEntry GetStateEntry(DbContext dbContext, object entity) - { - return GetStateEntry(TestBase.GetObjectContext(dbContext), entity); - } - - /// - /// Gets the ObjectStateEntry for the given entity in the given ObjectContext. - /// - /// A ObjectContext instance. - /// The entity to lookup. - /// The ObjectStateEntry. - public static ObjectStateEntry GetStateEntry(ObjectContext objectContext, object entity) - { - return objectContext.ObjectStateManager.GetObjectStateEntry(entity); - } - - /// - /// Asserts that there's no ObjectStateEntry for the given entity in the given DbContext. - /// - /// A DbContext instance. - /// The entity to lookup. - public static void AssertNoStateEntry(DbContext dbContext, object entity) - { - AssertNoStateEntry(TestBase.GetObjectContext(dbContext), entity); - } - - /// - /// Asserts that there's no ObjectStateEntry for the given entity in the given ObjectContext. - /// - /// A ObjectContext instance. - /// The entity to lookup. - public static void AssertNoStateEntry(ObjectContext objectContext, object entity) - { - ObjectStateEntry entry; - Assert.False( - objectContext.ObjectStateManager.TryGetObjectStateEntry(entity, out entry), - "The context contains an unexpected entry for the given entity"); - } - - #endregion - - #region Connection helpers - - private static string _baseConnectionString = ConfigurationManager.AppSettings["BaseConnectionString"] - ?? @"Data Source=.\SQLEXPRESS; Integrated Security=True;"; - - public static string BaseConnectionString - { - get { return _baseConnectionString; } - } - - /// - /// Returns a simple SQL Server connection string to the local machine with the given database name. - /// - /// The database name. - /// The connection string. - public static string SimpleConnectionString(string databaseName) - { - return new SqlConnectionStringBuilder(_baseConnectionString) - { - InitialCatalog = databaseName, - ApplicationName = "EntityFrameworkMUE" - } - .ConnectionString; - } - - /// - /// Returns a simple SQL Server connection string to the local machine using an attachable database with the given database name. - /// - /// The database name. - /// The connection string. - public static string SimpleAttachConnectionString(string databaseName) - { - var databasePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, databaseName + ".mdf"); - - return new SqlConnectionStringBuilder(_baseConnectionString) - { - InitialCatalog = databaseName, - AttachDBFilename = databasePath - } - .ConnectionString; - } - - /// - /// Returns a simple SQL Server connection string with the specified credentials. - /// - /// The database name. - /// User ID to be use when connecting to SQL Server. - /// Password for the SQL Server account. - /// - /// Indicates if security-sensitive information is not returned as part of the - /// connection if the connection has ever been opened. - /// - /// The connection string. - public static string SimpleConnectionStringWithCredentials( - string databaseName, - string userId, - string password, - bool persistSecurityInfo = false) - { - var builder = new SqlConnectionStringBuilder(_baseConnectionString) - { - InitialCatalog = databaseName, - ApplicationName = "EntityFrameworkMUE", - UserID = userId, - Password = password, - PersistSecurityInfo = persistSecurityInfo - }; - builder.Remove("Integrated Security"); - - return builder.ConnectionString; - } - - /// - /// Returns a simple SQL CE connection string to the local machine with the given database name. - /// Name of the database. - /// The connection string. - public static string SimpleCeConnectionString(string databaseName) - { - return String.Format( - CultureInfo.InvariantCulture, "Data Source={0}.sdf;Persist Security Info=False;", - Path.Combine(AppDomain.CurrentDomain.BaseDirectory, databaseName)); - } - - /// - /// Returns the default name that will be created for the context of the given type. - /// - /// The type of the context to create a name for. - /// The name. - public static string DefaultDbName() where TContext : DbContext - { - return typeof(TContext).FullName; - } - - /// - /// Returns a simple SQL Server connection string to the local machine for the given context type. - /// - /// The type of the context to create a connection string for. - /// The connection string. - public static string SimpleConnectionString() where TContext : DbContext - { - return SimpleConnectionString(DefaultDbName()); - } - - /// - /// Returns a simple SQL Server connection string to the local machine using an attachable database for the given context type. - /// - /// The type of the context to create a connection string for. - /// The connection string. - public static string SimpleAttachConnectionString() where TContext : DbContext - { - return SimpleAttachConnectionString(DefaultDbName()); - } - - /// - /// Returns a simple SQLCE connection string to the local machine for the given context type. - /// - /// The type of the context to create a connection string for. - /// The connection string. - public static string SimpleCeConnectionString() where TContext : DbContext - { - return SimpleCeConnectionString(DefaultDbName()); - } - - /// - /// Returns a simple SQL Server connection to the local machine for the given context type. - /// - /// The type of the context to create a connection for. - /// The connection. - public static SqlConnection SimpleConnection() where TContext : DbContext - { - return new SqlConnection(SimpleConnectionString()); - } - - /// - /// Returns a simple SQL CE connection for the given context type. - /// - /// The type of the context to create a connection for. - /// The connection. - public static DbConnection SimpleCeConnection() where TContext : DbContext - { - return - new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0", AppDomain.CurrentDomain.BaseDirectory, ""). - CreateConnection(DefaultDbName()); - } - - #endregion - - #region Entity set name helpers - - /// - /// Gets the entity set name for the given CLR type, assuming no MEST. - /// - /// The context to look in. - /// The type to lookup. - /// The entity set name. - public static string GetEntitySetName(DbContext dbContext, Type clrType) - { - return GetEntitySetName(TestBase.GetObjectContext(dbContext), clrType); - } - - /// - /// Gets the entity set name for the given CLR type, assuming no MEST. - /// - /// The context to look in. - /// The type to lookup. - /// The entity set name. - public static string GetEntitySetName(ObjectContext objectContext, Type clrType) - { - var cspaceType = GetStructuralType(objectContext, clrType); - if (cspaceType == null) - { - return null; - } - - var inverseHierarchy = new Stack(); - do - { - inverseHierarchy.Push(cspaceType); - cspaceType = (EntityType)cspaceType.BaseType; - } - while (cspaceType != null); - - while (inverseHierarchy.Count > 0) - { - cspaceType = inverseHierarchy.Pop(); - foreach (var container in objectContext.MetadataWorkspace.GetItems(DataSpace.CSpace)) - { - var entitySet = container.BaseEntitySets.Where(s => s.ElementType == cspaceType).FirstOrDefault(); - if (entitySet != null) - { - return entitySet.Name; - } - } - } - return null; - } - - #endregion - - #region Entity type helpers - - /// - /// Gets the Entity Type of the entity, given the CLR type - /// - /// The context to look in. - /// Type of the CLR. - /// - public static EntityType GetEntityType(DbContext dbContext, Type clrType) - { - return GetStructuralType(TestBase.GetObjectContext(dbContext), clrType); - } - - /// - /// Gets the structural type of the entity type or complex type given the CLR type - /// - /// The context to look in. - /// The CLR type. - /// The EntityType or ComplexType - public static TStructural GetStructuralType(ObjectContext objectContext, Type clrType) - where TStructural : StructuralType - { - var objectItemCollection = - (ObjectItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.OSpace); - var ospaceTypes = objectContext.MetadataWorkspace.GetItems(DataSpace.OSpace); - var ospaceType = ospaceTypes.Where(t => objectItemCollection.GetClrType(t) == clrType).FirstOrDefault(); - if (ospaceType == null) - { - objectContext.MetadataWorkspace.LoadFromAssembly(clrType.Assembly); - ospaceType = ospaceTypes.Where(t => objectItemCollection.GetClrType(t) == clrType).FirstOrDefault(); - if (ospaceType == null) - { - return null; - } - } - - return (TStructural)objectContext.MetadataWorkspace.GetEdmSpaceType(ospaceType); - } - - #endregion - - #region Helpers for creating metadata (csdl/ssdl/msl) files - - /// - /// Writes an edmx file into the current directory for the model generated from the given model builder. - /// - /// The builder. - /// The filename to use for the edmx file. - public static void WriteEdmx(DbModelBuilder builder, string filename) - { - EdmxWriter.WriteEdmx( - builder.Build(new DbProviderInfo("System.Data.SqlClient", "2008")), - XmlWriter.Create(filename)); - } - - /// - /// Writes csdl, msdl, and ssdl files into the current directory for the model generated from - /// the given model builder. - /// - /// The builder. - /// The base filename to use for csdl, msdl, and sssl files. - public static void WriteMetadataFiles(DbModelBuilder builder, string filename) - { - var xml = new StringBuilder(); - EdmxWriter.WriteEdmx( - builder.Build(new DbProviderInfo("System.Data.SqlClient", "2008")), - XmlWriter.Create(xml)); - - WriteMetadataFiles(xml.ToString(), filename); - } - - /// - /// Takes the edmx given as input and splits it into csdl, msl, and ssdl files that are written to the - /// current directory. - /// - /// The edmx. (Note that this is NOT the filename of an edmx file; it is the actual edmx.) - /// The base filename to use for csdl, msdl, and sssl files. - public static void WriteMetadataFiles(string edmx, string filename) - { - var csdlNameV2 = (XNamespace)"http://schemas.microsoft.com/ado/2008/09/edm" + "Schema"; - var ssdlNameV2 = (XNamespace)"http://schemas.microsoft.com/ado/2009/02/edm/ssdl" + "Schema"; - var mslNameV2 = (XNamespace)"http://schemas.microsoft.com/ado/2008/09/mapping/cs" + "Mapping"; - - var csdlNameV3 = (XNamespace)"http://schemas.microsoft.com/ado/2009/11/edm" + "Schema"; - var ssdlNameV3 = (XNamespace)"http://schemas.microsoft.com/ado/2009/11/edm/ssdl" + "Schema"; - var mslNameV3 = (XNamespace)"http://schemas.microsoft.com/ado/2009/11/mapping/cs" + "Mapping"; - - var edmxDoc = XDocument.Load(new StringReader(edmx)); - - WriteMetadataFile( - filename + ".csdl", - ExtractMetadataContent(edmxDoc, "ConceptualModels", csdlNameV2, csdlNameV3)); - WriteMetadataFile( - filename + ".ssdl", - ExtractMetadataContent(edmxDoc, "StorageModels", ssdlNameV2, ssdlNameV3)); - WriteMetadataFile(filename + ".msl", ExtractMetadataContent(edmxDoc, "Mappings", mslNameV2, mslNameV3)); - } - - private static void WriteMetadataFile(string filename, XElement element) - { - Debug.Assert(element != null, "Expected to find element"); - - using (var writer = XmlWriter.Create(filename)) - { - element.Save(writer); - } - } - - private static XElement ExtractMetadataContent(XDocument edmxDoc, string part, params XName[] elements) - { - XNamespace edmxnsV2 = "http://schemas.microsoft.com/ado/2008/10/edmx"; - XNamespace edmxnsV3 = "http://schemas.microsoft.com/ado/2009/11/edmx"; - - var edmxNode = edmxDoc.Element(edmxnsV2 + "Edmx") ?? edmxDoc.Element(edmxnsV3 + "Edmx"); - Debug.Assert(edmxNode != null, "Expected to find edmx node."); - - var runtimeNode = edmxNode.Element(edmxnsV2 + "Runtime") ?? edmxNode.Element(edmxnsV3 + "Runtime"); - Debug.Assert(runtimeNode != null, "Expected to find runtime node."); - - var partNode = runtimeNode.Element(edmxnsV2 + part) ?? runtimeNode.Element(edmxnsV3 + part); - Debug.Assert(partNode != null, "Expected to find " + part); - - return partNode.Element(elements[0]) ?? partNode.Element(elements[1]); - } - - #endregion - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Collections.Generic; + using System.Configuration; + using System.Data.Common; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.Core.Objects; + using System.Data.Entity.Infrastructure; + using System.Data.SqlClient; + using System.Diagnostics; + using System.Globalization; + using System.IO; + using System.Linq; + using System.Text; + using System.Xml; + using System.Xml.Linq; + using Xunit; + + public static class ModelHelpers + { + #region State entry helpers + + /// + /// Gets all GetStateEntries for the given DbContext. + /// + /// A DbContext instance. + /// All state entries in the ObjectStateManager. + public static IEnumerable GetStateEntries(DbContext dbContext) + { + return GetStateEntries(TestBase.GetObjectContext(dbContext)); + } + + /// + /// Gets all GetStateEntries for the given ObjectContext. + /// + /// A ObjectContext instance. + /// All state entries in the ObjectStateManager. + public static IEnumerable GetStateEntries(ObjectContext objectContext) + { + return objectContext.ObjectStateManager.GetObjectStateEntries(~EntityState.Detached); + } + + /// + /// Gets the ObjectStateEntry for the given entity in the given DbContext. + /// + /// A DbContext instance. + /// The entity to lookup. + /// The ObjectStateEntry. + public static ObjectStateEntry GetStateEntry(DbContext dbContext, object entity) + { + return GetStateEntry(TestBase.GetObjectContext(dbContext), entity); + } + + /// + /// Gets the ObjectStateEntry for the given entity in the given ObjectContext. + /// + /// A ObjectContext instance. + /// The entity to lookup. + /// The ObjectStateEntry. + public static ObjectStateEntry GetStateEntry(ObjectContext objectContext, object entity) + { + return objectContext.ObjectStateManager.GetObjectStateEntry(entity); + } + + /// + /// Asserts that there's no ObjectStateEntry for the given entity in the given DbContext. + /// + /// A DbContext instance. + /// The entity to lookup. + public static void AssertNoStateEntry(DbContext dbContext, object entity) + { + AssertNoStateEntry(TestBase.GetObjectContext(dbContext), entity); + } + + /// + /// Asserts that there's no ObjectStateEntry for the given entity in the given ObjectContext. + /// + /// A ObjectContext instance. + /// The entity to lookup. + public static void AssertNoStateEntry(ObjectContext objectContext, object entity) + { + ObjectStateEntry entry; + Assert.False( + objectContext.ObjectStateManager.TryGetObjectStateEntry(entity, out entry), + "The context contains an unexpected entry for the given entity"); + } + + #endregion + + #region Connection helpers + + private static string _baseConnectionString = ConfigurationManager.AppSettings["BaseConnectionString"] + ?? @"Data Source=.\SQLEXPRESS; Integrated Security=True;"; + + public static string BaseConnectionString + { + get { return _baseConnectionString; } + } + + /// + /// Returns a simple SQL Server connection string to the local machine with the given database name. + /// + /// The database name. + /// The connection string. + public static string SimpleConnectionString(string databaseName) + { + return new SqlConnectionStringBuilder(_baseConnectionString) + { + InitialCatalog = databaseName, + ApplicationName = "EntityFrameworkMUE" + } + .ConnectionString; + } + + /// + /// Returns a simple SQL Server connection string to the local machine using an attachable database with the given database name. + /// + /// The database name. + /// The connection string. + public static string SimpleAttachConnectionString(string databaseName) + { + var databasePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, databaseName + ".mdf"); + + return new SqlConnectionStringBuilder(_baseConnectionString) + { + InitialCatalog = databaseName, + AttachDBFilename = databasePath + } + .ConnectionString; + } + + /// + /// Returns a simple SQL Server connection string with the specified credentials. + /// + /// The database name. + /// User ID to be use when connecting to SQL Server. + /// Password for the SQL Server account. + /// + /// Indicates if security-sensitive information is not returned as part of the + /// connection if the connection has ever been opened. + /// + /// The connection string. + public static string SimpleConnectionStringWithCredentials( + string databaseName, + string userId, + string password, + bool persistSecurityInfo = false) + { + var builder = new SqlConnectionStringBuilder(_baseConnectionString) + { + InitialCatalog = databaseName, + ApplicationName = "EntityFrameworkMUE", + UserID = userId, + Password = password, + PersistSecurityInfo = persistSecurityInfo + }; + builder.Remove("Integrated Security"); + + return builder.ConnectionString; + } + + /// + /// Returns a simple SQL CE connection string to the local machine with the given database name. + /// Name of the database. + /// The connection string. + public static string SimpleCeConnectionString(string databaseName) + { + return String.Format( + CultureInfo.InvariantCulture, "Data Source={0}.sdf;Persist Security Info=False;", + Path.Combine(AppDomain.CurrentDomain.BaseDirectory, databaseName)); + } + + /// + /// Returns the default name that will be created for the context of the given type. + /// + /// The type of the context to create a name for. + /// The name. + public static string DefaultDbName() where TContext : DbContext + { + return typeof(TContext).FullName; + } + + /// + /// Returns a simple SQL Server connection string to the local machine for the given context type. + /// + /// The type of the context to create a connection string for. + /// The connection string. + public static string SimpleConnectionString() where TContext : DbContext + { + return SimpleConnectionString(DefaultDbName()); + } + + /// + /// Returns a simple SQL Server connection string to the local machine using an attachable database for the given context type. + /// + /// The type of the context to create a connection string for. + /// The connection string. + public static string SimpleAttachConnectionString() where TContext : DbContext + { + return SimpleAttachConnectionString(DefaultDbName()); + } + + /// + /// Returns a simple SQLCE connection string to the local machine for the given context type. + /// + /// The type of the context to create a connection string for. + /// The connection string. + public static string SimpleCeConnectionString() where TContext : DbContext + { + return SimpleCeConnectionString(DefaultDbName()); + } + + /// + /// Returns a simple SQL Server connection to the local machine for the given context type. + /// + /// The type of the context to create a connection for. + /// The connection. + public static SqlConnection SimpleConnection() where TContext : DbContext + { + return new SqlConnection(SimpleConnectionString()); + } + + /// + /// Returns a simple SQL CE connection for the given context type. + /// + /// The type of the context to create a connection for. + /// The connection. + public static DbConnection SimpleCeConnection() where TContext : DbContext + { + return + new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0", AppDomain.CurrentDomain.BaseDirectory, ""). + CreateConnection(DefaultDbName()); + } + + #endregion + + #region Entity set name helpers + + /// + /// Gets the entity set name for the given CLR type, assuming no MEST. + /// + /// The context to look in. + /// The type to lookup. + /// The entity set name. + public static string GetEntitySetName(DbContext dbContext, Type clrType) + { + return GetEntitySetName(TestBase.GetObjectContext(dbContext), clrType); + } + + /// + /// Gets the entity set name for the given CLR type, assuming no MEST. + /// + /// The context to look in. + /// The type to lookup. + /// The entity set name. + public static string GetEntitySetName(ObjectContext objectContext, Type clrType) + { + var cspaceType = GetStructuralType(objectContext, clrType); + if (cspaceType == null) + { + return null; + } + + var inverseHierarchy = new Stack(); + do + { + inverseHierarchy.Push(cspaceType); + cspaceType = (EntityType)cspaceType.BaseType; + } + while (cspaceType != null); + + while (inverseHierarchy.Count > 0) + { + cspaceType = inverseHierarchy.Pop(); + foreach (var container in objectContext.MetadataWorkspace.GetItems(DataSpace.CSpace)) + { + var entitySet = container.BaseEntitySets.Where(s => s.ElementType == cspaceType).FirstOrDefault(); + if (entitySet != null) + { + return entitySet.Name; + } + } + } + return null; + } + + #endregion + + #region Entity type helpers + + /// + /// Gets the Entity Type of the entity, given the CLR type + /// + /// The context to look in. + /// Type of the CLR. + /// + public static EntityType GetEntityType(DbContext dbContext, Type clrType) + { + return GetStructuralType(TestBase.GetObjectContext(dbContext), clrType); + } + + /// + /// Gets the structural type of the entity type or complex type given the CLR type + /// + /// The context to look in. + /// The CLR type. + /// The EntityType or ComplexType + public static TStructural GetStructuralType(ObjectContext objectContext, Type clrType) + where TStructural : StructuralType + { + var objectItemCollection = + (ObjectItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.OSpace); + var ospaceTypes = objectContext.MetadataWorkspace.GetItems(DataSpace.OSpace); + var ospaceType = ospaceTypes.Where(t => objectItemCollection.GetClrType(t) == clrType).FirstOrDefault(); + if (ospaceType == null) + { + objectContext.MetadataWorkspace.LoadFromAssembly(clrType.Assembly); + ospaceType = ospaceTypes.Where(t => objectItemCollection.GetClrType(t) == clrType).FirstOrDefault(); + if (ospaceType == null) + { + return null; + } + } + + return (TStructural)objectContext.MetadataWorkspace.GetEdmSpaceType(ospaceType); + } + + #endregion + + #region Helpers for creating metadata (csdl/ssdl/msl) files + + /// + /// Writes an edmx file into the current directory for the model generated from the given model builder. + /// + /// The builder. + /// The filename to use for the edmx file. + public static void WriteEdmx(DbModelBuilder builder, string filename) + { + EdmxWriter.WriteEdmx( + builder.Build(new DbProviderInfo("System.Data.SqlClient", "2008")), + XmlWriter.Create(filename)); + } + + /// + /// Writes csdl, msdl, and ssdl files into the current directory for the model generated from + /// the given model builder. + /// + /// The builder. + /// The base filename to use for csdl, msdl, and sssl files. + public static void WriteMetadataFiles(DbModelBuilder builder, string filename) + { + var xml = new StringBuilder(); + EdmxWriter.WriteEdmx( + builder.Build(new DbProviderInfo("System.Data.SqlClient", "2008")), + XmlWriter.Create(xml)); + + WriteMetadataFiles(xml.ToString(), filename); + } + + /// + /// Takes the edmx given as input and splits it into csdl, msl, and ssdl files that are written to the + /// current directory. + /// + /// The edmx. (Note that this is NOT the filename of an edmx file; it is the actual edmx.) + /// The base filename to use for csdl, msdl, and sssl files. + public static void WriteMetadataFiles(string edmx, string filename) + { + var csdlNameV2 = (XNamespace)"http://schemas.microsoft.com/ado/2008/09/edm" + "Schema"; + var ssdlNameV2 = (XNamespace)"http://schemas.microsoft.com/ado/2009/02/edm/ssdl" + "Schema"; + var mslNameV2 = (XNamespace)"http://schemas.microsoft.com/ado/2008/09/mapping/cs" + "Mapping"; + + var csdlNameV3 = (XNamespace)"http://schemas.microsoft.com/ado/2009/11/edm" + "Schema"; + var ssdlNameV3 = (XNamespace)"http://schemas.microsoft.com/ado/2009/11/edm/ssdl" + "Schema"; + var mslNameV3 = (XNamespace)"http://schemas.microsoft.com/ado/2009/11/mapping/cs" + "Mapping"; + + var edmxDoc = XDocument.Load(new StringReader(edmx)); + + WriteMetadataFile( + filename + ".csdl", + ExtractMetadataContent(edmxDoc, "ConceptualModels", csdlNameV2, csdlNameV3)); + WriteMetadataFile( + filename + ".ssdl", + ExtractMetadataContent(edmxDoc, "StorageModels", ssdlNameV2, ssdlNameV3)); + WriteMetadataFile(filename + ".msl", ExtractMetadataContent(edmxDoc, "Mappings", mslNameV2, mslNameV3)); + } + + private static void WriteMetadataFile(string filename, XElement element) + { + Debug.Assert(element != null, "Expected to find element"); + + using (var writer = XmlWriter.Create(filename)) + { + element.Save(writer); + } + } + + private static XElement ExtractMetadataContent(XDocument edmxDoc, string part, params XName[] elements) + { + XNamespace edmxnsV2 = "http://schemas.microsoft.com/ado/2008/10/edmx"; + XNamespace edmxnsV3 = "http://schemas.microsoft.com/ado/2009/11/edmx"; + + var edmxNode = edmxDoc.Element(edmxnsV2 + "Edmx") ?? edmxDoc.Element(edmxnsV3 + "Edmx"); + Debug.Assert(edmxNode != null, "Expected to find edmx node."); + + var runtimeNode = edmxNode.Element(edmxnsV2 + "Runtime") ?? edmxNode.Element(edmxnsV3 + "Runtime"); + Debug.Assert(runtimeNode != null, "Expected to find runtime node."); + + var partNode = runtimeNode.Element(edmxnsV2 + part) ?? runtimeNode.Element(edmxnsV3 + part); + Debug.Assert(partNode != null, "Expected to find " + part); + + return partNode.Element(elements[0]) ?? partNode.Element(elements[1]); + } + + #endregion + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/MutableResolver.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/MutableResolver.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/MutableResolver.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/MutableResolver.cs index 664f883d..421ed095 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/MutableResolver.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/MutableResolver.cs @@ -1,59 +1,59 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.TestHelpers -{ - using System; - using System.Collections.Generic; - using System.Data.Entity.Config; - - /// - /// A resolver that allows to add dependency resolvers at runtime. - /// - public class MutableResolver : IDbDependencyResolver - { - private static readonly Dictionary> _resolvers = new Dictionary>(); - private static readonly MutableResolver _instance = new MutableResolver(); - - private MutableResolver() - { - } - - /// - public object GetService(Type type, object key) - { - Func resolver; - if (_resolvers.TryGetValue(type, out resolver)) - { - return resolver(key); - } - - return null; - } - - public static MutableResolver Instance - { - get { return _instance; } - } - - /// - /// Adds or replaces a resolver for a dependency of type . - /// - /// - /// Remember to call from a finally block after using this method. - /// - /// The type of dependency to resolve. - /// A delegate that takes a key object and returns a dependency instance. - public static void AddResolver(Func resolver) - { - _resolvers.Add(typeof(TResolver), resolver); - } - - /// - /// Removes all added resolvers. - /// - public static void ClearResolvers() - { - _resolvers.Clear(); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.TestHelpers +{ + using System; + using System.Collections.Generic; + using System.Data.Entity.Config; + + /// + /// A resolver that allows to add dependency resolvers at runtime. + /// + public class MutableResolver : IDbDependencyResolver + { + private static readonly Dictionary> _resolvers = new Dictionary>(); + private static readonly MutableResolver _instance = new MutableResolver(); + + private MutableResolver() + { + } + + /// + public object GetService(Type type, object key) + { + Func resolver; + if (_resolvers.TryGetValue(type, out resolver)) + { + return resolver(key); + } + + return null; + } + + public static MutableResolver Instance + { + get { return _instance; } + } + + /// + /// Adds or replaces a resolver for a dependency of type . + /// + /// + /// Remember to call from a finally block after using this method. + /// + /// The type of dependency to resolve. + /// A delegate that takes a key object and returns a dependency instance. + public static void AddResolver(Func resolver) + { + _resolvers.Add(typeof(TResolver), resolver); + } + + /// + /// Removes all added resolvers. + /// + public static void ClearResolvers() + { + _resolvers.Clear(); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/ObservableListSource`.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ObservableListSource`.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/ObservableListSource`.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ObservableListSource`.cs index ff154e9e..9041570d 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/ObservableListSource`.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ObservableListSource`.cs @@ -1,81 +1,81 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Collections; - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.ComponentModel; - using System.Diagnostics.CodeAnalysis; - - /// - /// Extends and adds an explicit implementation of . - /// The GetList method of IListSource is implemented to return an implementation that - /// stays in sync with the ObservableCollection. - /// This class can be used to implement navigation properties on entities for use in Windows Forms data binding. - /// For WPF data binding using an ObservableCollection rather than an instance of this class is recommended. - /// - /// - [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", - Justification = "Adding Collection makes the name too long.")] - public class ObservableListSource : ObservableCollection, IListSource - where T : class - { - #region Fields and constructors - - private IBindingList _bindingList; - - /// - /// Initializes a new instance of the class. - /// - public ObservableListSource() - { - } - - /// - /// Initializes a new instance of the class that - /// contains elements copied from the specified collection. - /// - /// The collection from which the elements are copied. - public ObservableListSource(IEnumerable collection) - : base(collection) - { - } - - /// - /// Initializes a new instance of the class that - /// contains elements copied from the specified list. - /// - /// The list from which the elements are copied. - public ObservableListSource(List list) - : base(list) - { - } - - #endregion - - #region IListSource implementation - - /// - /// Returns false. - /// - /// false . - bool IListSource.ContainsListCollection - { - get { return false; } - } - - /// - /// Returns an implementation that stays in sync with this . - /// The returned list is cached on this object such that the same list is returned each time this method is called. - /// - /// An implementation that stays in sync with this . - IList IListSource.GetList() - { - return _bindingList ?? (_bindingList = this.ToBindingList()); - } - - #endregion - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Collections; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.ComponentModel; + using System.Diagnostics.CodeAnalysis; + + /// + /// Extends and adds an explicit implementation of . + /// The GetList method of IListSource is implemented to return an implementation that + /// stays in sync with the ObservableCollection. + /// This class can be used to implement navigation properties on entities for use in Windows Forms data binding. + /// For WPF data binding using an ObservableCollection rather than an instance of this class is recommended. + /// + /// + [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", + Justification = "Adding Collection makes the name too long.")] + public class ObservableListSource : ObservableCollection, IListSource + where T : class + { + #region Fields and constructors + + private IBindingList _bindingList; + + /// + /// Initializes a new instance of the class. + /// + public ObservableListSource() + { + } + + /// + /// Initializes a new instance of the class that + /// contains elements copied from the specified collection. + /// + /// The collection from which the elements are copied. + public ObservableListSource(IEnumerable collection) + : base(collection) + { + } + + /// + /// Initializes a new instance of the class that + /// contains elements copied from the specified list. + /// + /// The list from which the elements are copied. + public ObservableListSource(List list) + : base(list) + { + } + + #endregion + + #region IListSource implementation + + /// + /// Returns false. + /// + /// false . + bool IListSource.ContainsListCollection + { + get { return false; } + } + + /// + /// Returns an implementation that stays in sync with this . + /// The returned list is cached on this object such that the same list is returned each time this method is called. + /// + /// An implementation that stays in sync with this . + IList IListSource.GetList() + { + return _bindingList ?? (_bindingList = this.ToBindingList()); + } + + #endregion + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/ProviderRegistry.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ProviderRegistry.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/ProviderRegistry.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ProviderRegistry.cs index 4c4ac866..b7548627 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/ProviderRegistry.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ProviderRegistry.cs @@ -1,31 +1,31 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Data.Entity.Core.Common; - using System.Data.Entity.Infrastructure; - using System.Data.SqlClient; - - public static class ProviderRegistry - { - public static DbProviderInfo Sql2008_ProviderInfo - { - get { return new DbProviderInfo("System.Data.SqlClient", "2008"); } - } - - public static DbProviderManifest Sql2008_ProviderManifest - { - get { return DbProviderServices.GetProviderServices(new SqlConnection()).GetProviderManifest("2008"); } - } - - public static DbProviderInfo SqlCe4_ProviderInfo - { - get { return new DbProviderInfo("System.Data.SqlServerCe.4.0", "4.0"); } - } - - public static DbProviderInfo SqlCe35_ProviderInfo - { - get { return new DbProviderInfo("System.Data.SqlServerCe.3.5", "3.5"); } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Data.Entity.Core.Common; + using System.Data.Entity.Infrastructure; + using System.Data.SqlClient; + + public static class ProviderRegistry + { + public static DbProviderInfo Sql2008_ProviderInfo + { + get { return new DbProviderInfo("System.Data.SqlClient", "2008"); } + } + + public static DbProviderManifest Sql2008_ProviderManifest + { + get { return DbProviderServices.GetProviderServices(new SqlConnection()).GetProviderManifest("2008"); } + } + + public static DbProviderInfo SqlCe4_ProviderInfo + { + get { return new DbProviderInfo("System.Data.SqlServerCe.4.0", "4.0"); } + } + + public static DbProviderInfo SqlCe35_ProviderInfo + { + get { return new DbProviderInfo("System.Data.SqlServerCe.3.5", "3.5"); } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/ResourceUtilities.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ResourceUtilities.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/ResourceUtilities.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ResourceUtilities.cs index f8b89c42..0497b497 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/ResourceUtilities.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/ResourceUtilities.cs @@ -1,135 +1,135 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Diagnostics; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.IO.Compression; - using System.Linq; - using System.Reflection; - using System.Resources; - using System.Security; - using System.Security.Permissions; - -#if !SILVERLIGHT -#endif - - /// - /// Various utilities for dealing with embedded resources - /// - public static class ResourceUtilities - { -#if !SILVERLIGHT - /// - /// Extracts the specified compressed resource to a given directory - /// - /// Output directory - /// Assembly that contains the resource - /// Partial resource name - /// - /// The method prefixes the actual resource with unqualified assembly name + '.Resources.' ( - /// so you should put all your resources under 'Resources' directory within a project) - /// and appends '.gz' to it. You should use gzip to produce compressed files. - /// - [SecuritySafeCritical] - // Calling File.Create demands FileIOPermission (Write flag) for the file path to which the resource is extracted. - [PermissionSet(SecurityAction.Assert, Unrestricted = true)] - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "gz", - Justification = ".gz is GZIP file extension")] - [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", - Justification = "Bogus warning, object will be disposed once.")] - public static void ExtractCompressedResourceToDirectory(string outputDirectory, Assembly assembly, string resourceName) - { - ValidateCommonArguments(outputDirectory, assembly, resourceName); - - var fullResourceName = new AssemblyName(assembly.FullName).Name + ".Resources." + resourceName + ".gz"; - using (var compressedInputStream = assembly.GetManifestResourceStream(fullResourceName)) - { - if (compressedInputStream == null) - { - throw new IOException("Embedded resource " + fullResourceName + " not found in " + assembly.FullName); - } - - using (var decompressedInputStream = new GZipStream(compressedInputStream, CompressionMode.Decompress)) - { - using (Stream outputStream = File.Create(Path.Combine(outputDirectory, resourceName))) - { - IOHelpers.CopyStream(decompressedInputStream, outputStream); - } - } - } - } -#endif - - /// - /// Copies the named embedded resources from given assembly into the current directory. - /// - /// The assembly. - /// The prefix to use for each name. - /// if set to true then an existing file of the same name name will be overwritten. - /// The resource names, which will become the file names. - public static void CopyEmbeddedResourcesToCurrentDir( - Assembly assembly, string prefix, bool overwrite, - params string[] names) - { - foreach (var name in names) - { - using (var sourceStream = assembly.GetManifestResourceStream(prefix + name)) - { - Debug.Assert(sourceStream != null, "Could not create stream for embedded resource " + prefix + name); - - var destinationPath = Path.Combine(@".\", name); - if (!File.Exists(destinationPath) || overwrite) - { - using ( - var destinationStream = new FileStream(destinationPath, FileMode.Create, FileAccess.Write)) - { - var sourceBuffer = new byte[sourceStream.Length]; - sourceStream.Read(sourceBuffer, 0, sourceBuffer.Length); - destinationStream.Write(sourceBuffer, 0, sourceBuffer.Length); - } - } - } - } - } - - /// - /// Builds a resource manager for the given assembly. - /// - /// The assembly to build the resource manager for. - /// The resource manager. - public static ResourceManager BuildResourceManager(Assembly assembly) - { - ExceptionHelpers.CheckArgumentNotNull(assembly, "assembly"); - return new ResourceManager(FindSingleResourceTable(assembly), assembly); - } - - private static void ValidateCommonArguments(string outputDirectory, Assembly assembly, string resourceName) - { - ExceptionHelpers.CheckArgumentNotNull(outputDirectory, "outputDirectory"); - ExceptionHelpers.CheckArgumentNotNull(assembly, "assembly"); - ExceptionHelpers.CheckArgumentNotNull(resourceName, "resourceName"); - - if (!Directory.Exists(outputDirectory)) - { - throw new IOException("Output directory '" + outputDirectory + "' does not exist."); - } - } - - private static string FindSingleResourceTable(Assembly assembly) - { - var resources = assembly.GetManifestResourceNames().Where(r => r.EndsWith(".resources", StringComparison.Ordinal)); - if (resources.Count() != 1) - { - throw new NotSupportedException( - "The supplied assembly does not contain exactly one resource table, if the assembly contains multiple tables call the overload that specifies which table to use."); - } - - var resource = resources.Single(); - - // Need to trim the ".resources" off the end - return resource.Substring(0, resource.Length - 10); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; + using System.IO; + using System.IO.Compression; + using System.Linq; + using System.Reflection; + using System.Resources; + using System.Security; + using System.Security.Permissions; + +#if !SILVERLIGHT +#endif + + /// + /// Various utilities for dealing with embedded resources + /// + public static class ResourceUtilities + { +#if !SILVERLIGHT + /// + /// Extracts the specified compressed resource to a given directory + /// + /// Output directory + /// Assembly that contains the resource + /// Partial resource name + /// + /// The method prefixes the actual resource with unqualified assembly name + '.Resources.' ( + /// so you should put all your resources under 'Resources' directory within a project) + /// and appends '.gz' to it. You should use gzip to produce compressed files. + /// + [SecuritySafeCritical] + // Calling File.Create demands FileIOPermission (Write flag) for the file path to which the resource is extracted. + [PermissionSet(SecurityAction.Assert, Unrestricted = true)] + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "gz", + Justification = ".gz is GZIP file extension")] + [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", + Justification = "Bogus warning, object will be disposed once.")] + public static void ExtractCompressedResourceToDirectory(string outputDirectory, Assembly assembly, string resourceName) + { + ValidateCommonArguments(outputDirectory, assembly, resourceName); + + var fullResourceName = new AssemblyName(assembly.FullName).Name + ".Resources." + resourceName + ".gz"; + using (var compressedInputStream = assembly.GetManifestResourceStream(fullResourceName)) + { + if (compressedInputStream == null) + { + throw new IOException("Embedded resource " + fullResourceName + " not found in " + assembly.FullName); + } + + using (var decompressedInputStream = new GZipStream(compressedInputStream, CompressionMode.Decompress)) + { + using (Stream outputStream = File.Create(Path.Combine(outputDirectory, resourceName))) + { + IOHelpers.CopyStream(decompressedInputStream, outputStream); + } + } + } + } +#endif + + /// + /// Copies the named embedded resources from given assembly into the current directory. + /// + /// The assembly. + /// The prefix to use for each name. + /// if set to true then an existing file of the same name name will be overwritten. + /// The resource names, which will become the file names. + public static void CopyEmbeddedResourcesToCurrentDir( + Assembly assembly, string prefix, bool overwrite, + params string[] names) + { + foreach (var name in names) + { + using (var sourceStream = assembly.GetManifestResourceStream(prefix + name)) + { + Debug.Assert(sourceStream != null, "Could not create stream for embedded resource " + prefix + name); + + var destinationPath = Path.Combine(@".\", name); + if (!File.Exists(destinationPath) || overwrite) + { + using ( + var destinationStream = new FileStream(destinationPath, FileMode.Create, FileAccess.Write)) + { + var sourceBuffer = new byte[sourceStream.Length]; + sourceStream.Read(sourceBuffer, 0, sourceBuffer.Length); + destinationStream.Write(sourceBuffer, 0, sourceBuffer.Length); + } + } + } + } + } + + /// + /// Builds a resource manager for the given assembly. + /// + /// The assembly to build the resource manager for. + /// The resource manager. + public static ResourceManager BuildResourceManager(Assembly assembly) + { + ExceptionHelpers.CheckArgumentNotNull(assembly, "assembly"); + return new ResourceManager(FindSingleResourceTable(assembly), assembly); + } + + private static void ValidateCommonArguments(string outputDirectory, Assembly assembly, string resourceName) + { + ExceptionHelpers.CheckArgumentNotNull(outputDirectory, "outputDirectory"); + ExceptionHelpers.CheckArgumentNotNull(assembly, "assembly"); + ExceptionHelpers.CheckArgumentNotNull(resourceName, "resourceName"); + + if (!Directory.Exists(outputDirectory)) + { + throw new IOException("Output directory '" + outputDirectory + "' does not exist."); + } + } + + private static string FindSingleResourceTable(Assembly assembly) + { + var resources = assembly.GetManifestResourceNames().Where(r => r.EndsWith(".resources", StringComparison.Ordinal)); + if (resources.Count() != 1) + { + throw new NotSupportedException( + "The supplied assembly does not contain exactly one resource table, if the assembly contains multiple tables call the overload that specifies which table to use."); + } + + var resource = resources.Single(); + + // Need to trim the ".resources" off the end + return resource.Substring(0, resource.Length - 10); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/StringResourceVerifier.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/StringResourceVerifier.cs similarity index 98% rename from test/EntityFramework/FunctionalTests/TestHelpers/StringResourceVerifier.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/StringResourceVerifier.cs index 0e48cd5e..122569cd 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/StringResourceVerifier.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/StringResourceVerifier.cs @@ -1,227 +1,227 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Collections.Generic; - using System.Globalization; - using System.Linq; - using Xunit; - - /// - /// Helpers for verifying strings that are pulled from a localized resources - /// - public class StringResourceVerifier - { - private readonly AssemblyResourceLookup _lookup; - - /// - /// Initializes a new instance of the StringResourceVerifier class. - /// - /// Lookup to be used for locating string resources - public StringResourceVerifier(AssemblyResourceLookup lookup) - { - _lookup = lookup; - } - - /// - /// Determines if the supplied string is an instance of the string defined in localized resources - /// - /// The key of the resource string to match against - /// String value to be verified - /// Expected values for string.Format placeholders in the resource string If none are supplied then any values for placeholders in the resource string will count as a match - /// True if the string matches, false otherwise - public bool IsMatch(string expectedResourceKey, string actualMessage, params object[] stringParameters) - { - return IsMatch(expectedResourceKey, actualMessage, true, stringParameters); - } - - /// - /// Determines if the supplied string is an instance of the string defined in localized resources - /// - /// The key of the resource string to match against - /// String value to be verified - /// Determines whether the exception message must be exact match of the message in the resource file, or just contain it. - /// Expected values for string.Format placeholders in the resource string If none are supplied then any values for placeholders in the resource string will count as a match - /// True if the string matches, false otherwise - public bool IsMatch(string expectedResourceKey, string actualMessage, bool isExactMatch, params object[] stringParameters) - { - string messageFromResources; - return IsMatch(expectedResourceKey, actualMessage, isExactMatch, stringParameters, out messageFromResources); - } - - /// - /// Verified the supplied string is an instance of the string defined in resources - /// - /// The key of the resource string to match against - /// String value to be verified - /// Expected values for string.Format placeholders in the resource string If none are supplied then any values for placeholders in the resource string will count as a match - public void VerifyMatch(string expectedResourceKey, string actualMessage, params object[] stringParameters) - { - VerifyMatch(expectedResourceKey, actualMessage, true, stringParameters); - } - - /// - /// Determines if the supplied string is an instance of the string defined in localized resources - /// If the string in the resource file contains string.Format place holders then the actual message can contain any values for these - /// - /// The key of the resource string to match against - /// String value to be verified - /// Determines whether the exception message must be exact match of the message in the resource file, or just contain it. - /// Expected values for string.Format placeholders in the resource string If none are supplied then any values for placeholders in the resource string will count as a match - public void VerifyMatch(string expectedResourceKey, string actualMessage, bool isExactMatch, params object[] stringParameters) - { - string messageFromResources; - Assert.True( - IsMatch( - expectedResourceKey, actualMessage, isExactMatch, stringParameters, - out messageFromResources), - string.Format( - @"Actual string does not match the message defined in resources. -Expected:'{0}', -Actual:'{1}'", - messageFromResources, actualMessage)); - } - - private static bool IsMatchWithAnyPlaceholderValues(string expectedMessage, string actualMessage, bool isExactMatch) - { - // Find the sections of the Exception message seperated by {x} tags - var sections = FindMessageSections(expectedMessage); - - // Check that each section is present in the actual message in correct order - var indexToCheckFrom = 0; - foreach (var section in sections) - { - // Check if it is present in the actual message - var index = actualMessage.IndexOf(section, indexToCheckFrom, StringComparison.Ordinal); - if (index < 0) - { - return false; - } - - if (section.Length == 0 - && section == sections.Last()) - { - // If the last section is a zero-length string - // then this indicates that the placeholder is the - // last thing in the resource. Thus every section - // matched and the placeholder takes up the rest of string - // from the actual message. - return true; - } - else - { - // continue checking from the end of this section - // (Ensures sections are in the correct order) - indexToCheckFrom = index + section.Length; - } - } - - // If we reach the end then everything is a match - return isExactMatch ? indexToCheckFrom == actualMessage.Length : indexToCheckFrom <= actualMessage.Length; - } - - private static IEnumerable FindMessageSections(string messageFromResources) - { - // Find the start and end index of each section of the string - var sections = new List(); - - // Start with a section that spans the whole string - // While there are still place holders shorten the previous section to end at the next { and start a new section from the following } - sections.Add( - new StringSection - { - StartIndex = 0, - EndIndex = messageFromResources.Length - }); - var indexToCheckFrom = 0; - while (messageFromResources.IndexOf("{", indexToCheckFrom, StringComparison.Ordinal) >= 0) - { - // Find the indexes to split the new section around - var previous = sections.Last(); - var previousEndIndex = messageFromResources.IndexOf("{", indexToCheckFrom, StringComparison.Ordinal); - var nextStartIndex = messageFromResources.IndexOf("}", previousEndIndex, StringComparison.Ordinal) + 1; - - // If there are no remaining closing tags then we are done - if (nextStartIndex == 0) - { - break; - } - else - { - // Contents of place holder must be integer - int temp; - var intContents = - int.TryParse(messageFromResources.Substring(previousEndIndex + 1, nextStartIndex - previousEndIndex - 2), out temp); - - // Place holder must not be escaped (i.e. {{0}}) - var escaped = messageFromResources[previousEndIndex] == '{' - && nextStartIndex < messageFromResources.Length - && messageFromResources[nextStartIndex] == '}'; - - if (!intContents || escaped) - { - indexToCheckFrom++; - continue; - } - } - - // Shorten the previous section to end at the { - previous.EndIndex = previousEndIndex; - - // Add the remaining string after the } into a new section, - // even if the '}' is the last character in the string. This - // helps verification ensure that there is actually a wildcard - // at this point in the string instead of the string ending - // without a wildcard. - sections.Add( - new StringSection - { - StartIndex = nextStartIndex, - EndIndex = messageFromResources.Length - }); - indexToCheckFrom = nextStartIndex; - } - - // Pull out the sections - return - sections.Select( - s => messageFromResources.Substring(s.StartIndex, s.EndIndex - s.StartIndex).Replace("{{", "{").Replace("}}", "}")); - } - - private bool IsMatch( - string expectedResourceKey, string actualMessage, bool isExactMatch, object[] stringParameters, out string messageFromResources) - { - ExceptionHelpers.CheckStringArgumentIsNotNullOrEmpty(expectedResourceKey, "expectedResourceKey"); - ExceptionHelpers.CheckArgumentNotNull(actualMessage, "actualMessage"); - - messageFromResources = _lookup.LookupString(expectedResourceKey); - - if (stringParameters.Length == 0) - { - return IsMatchWithAnyPlaceholderValues(messageFromResources, actualMessage, isExactMatch); - } - else - { - messageFromResources = string.Format(CultureInfo.InvariantCulture, messageFromResources, stringParameters); - - return isExactMatch ? actualMessage == messageFromResources : actualMessage.Contains(messageFromResources); - } - } - - /// - /// Represents a section of a string - /// - private class StringSection - { - /// - /// Gets or sets the index the section starts at - /// - public int StartIndex { get; set; } - - /// - /// Gets or sets the index the section ends at - /// - public int EndIndex { get; set; } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Collections.Generic; + using System.Globalization; + using System.Linq; + using Xunit; + + /// + /// Helpers for verifying strings that are pulled from a localized resources + /// + public class StringResourceVerifier + { + private readonly AssemblyResourceLookup _lookup; + + /// + /// Initializes a new instance of the StringResourceVerifier class. + /// + /// Lookup to be used for locating string resources + public StringResourceVerifier(AssemblyResourceLookup lookup) + { + _lookup = lookup; + } + + /// + /// Determines if the supplied string is an instance of the string defined in localized resources + /// + /// The key of the resource string to match against + /// String value to be verified + /// Expected values for string.Format placeholders in the resource string If none are supplied then any values for placeholders in the resource string will count as a match + /// True if the string matches, false otherwise + public bool IsMatch(string expectedResourceKey, string actualMessage, params object[] stringParameters) + { + return IsMatch(expectedResourceKey, actualMessage, true, stringParameters); + } + + /// + /// Determines if the supplied string is an instance of the string defined in localized resources + /// + /// The key of the resource string to match against + /// String value to be verified + /// Determines whether the exception message must be exact match of the message in the resource file, or just contain it. + /// Expected values for string.Format placeholders in the resource string If none are supplied then any values for placeholders in the resource string will count as a match + /// True if the string matches, false otherwise + public bool IsMatch(string expectedResourceKey, string actualMessage, bool isExactMatch, params object[] stringParameters) + { + string messageFromResources; + return IsMatch(expectedResourceKey, actualMessage, isExactMatch, stringParameters, out messageFromResources); + } + + /// + /// Verified the supplied string is an instance of the string defined in resources + /// + /// The key of the resource string to match against + /// String value to be verified + /// Expected values for string.Format placeholders in the resource string If none are supplied then any values for placeholders in the resource string will count as a match + public void VerifyMatch(string expectedResourceKey, string actualMessage, params object[] stringParameters) + { + VerifyMatch(expectedResourceKey, actualMessage, true, stringParameters); + } + + /// + /// Determines if the supplied string is an instance of the string defined in localized resources + /// If the string in the resource file contains string.Format place holders then the actual message can contain any values for these + /// + /// The key of the resource string to match against + /// String value to be verified + /// Determines whether the exception message must be exact match of the message in the resource file, or just contain it. + /// Expected values for string.Format placeholders in the resource string If none are supplied then any values for placeholders in the resource string will count as a match + public void VerifyMatch(string expectedResourceKey, string actualMessage, bool isExactMatch, params object[] stringParameters) + { + string messageFromResources; + Assert.True( + IsMatch( + expectedResourceKey, actualMessage, isExactMatch, stringParameters, + out messageFromResources), + string.Format( + @"Actual string does not match the message defined in resources. +Expected:'{0}', +Actual:'{1}'", + messageFromResources, actualMessage)); + } + + private static bool IsMatchWithAnyPlaceholderValues(string expectedMessage, string actualMessage, bool isExactMatch) + { + // Find the sections of the Exception message seperated by {x} tags + var sections = FindMessageSections(expectedMessage); + + // Check that each section is present in the actual message in correct order + var indexToCheckFrom = 0; + foreach (var section in sections) + { + // Check if it is present in the actual message + var index = actualMessage.IndexOf(section, indexToCheckFrom, StringComparison.Ordinal); + if (index < 0) + { + return false; + } + + if (section.Length == 0 + && section == sections.Last()) + { + // If the last section is a zero-length string + // then this indicates that the placeholder is the + // last thing in the resource. Thus every section + // matched and the placeholder takes up the rest of string + // from the actual message. + return true; + } + else + { + // continue checking from the end of this section + // (Ensures sections are in the correct order) + indexToCheckFrom = index + section.Length; + } + } + + // If we reach the end then everything is a match + return isExactMatch ? indexToCheckFrom == actualMessage.Length : indexToCheckFrom <= actualMessage.Length; + } + + private static IEnumerable FindMessageSections(string messageFromResources) + { + // Find the start and end index of each section of the string + var sections = new List(); + + // Start with a section that spans the whole string + // While there are still place holders shorten the previous section to end at the next { and start a new section from the following } + sections.Add( + new StringSection + { + StartIndex = 0, + EndIndex = messageFromResources.Length + }); + var indexToCheckFrom = 0; + while (messageFromResources.IndexOf("{", indexToCheckFrom, StringComparison.Ordinal) >= 0) + { + // Find the indexes to split the new section around + var previous = sections.Last(); + var previousEndIndex = messageFromResources.IndexOf("{", indexToCheckFrom, StringComparison.Ordinal); + var nextStartIndex = messageFromResources.IndexOf("}", previousEndIndex, StringComparison.Ordinal) + 1; + + // If there are no remaining closing tags then we are done + if (nextStartIndex == 0) + { + break; + } + else + { + // Contents of place holder must be integer + int temp; + var intContents = + int.TryParse(messageFromResources.Substring(previousEndIndex + 1, nextStartIndex - previousEndIndex - 2), out temp); + + // Place holder must not be escaped (i.e. {{0}}) + var escaped = messageFromResources[previousEndIndex] == '{' + && nextStartIndex < messageFromResources.Length + && messageFromResources[nextStartIndex] == '}'; + + if (!intContents || escaped) + { + indexToCheckFrom++; + continue; + } + } + + // Shorten the previous section to end at the { + previous.EndIndex = previousEndIndex; + + // Add the remaining string after the } into a new section, + // even if the '}' is the last character in the string. This + // helps verification ensure that there is actually a wildcard + // at this point in the string instead of the string ending + // without a wildcard. + sections.Add( + new StringSection + { + StartIndex = nextStartIndex, + EndIndex = messageFromResources.Length + }); + indexToCheckFrom = nextStartIndex; + } + + // Pull out the sections + return + sections.Select( + s => messageFromResources.Substring(s.StartIndex, s.EndIndex - s.StartIndex).Replace("{{", "{").Replace("}}", "}")); + } + + private bool IsMatch( + string expectedResourceKey, string actualMessage, bool isExactMatch, object[] stringParameters, out string messageFromResources) + { + ExceptionHelpers.CheckStringArgumentIsNotNullOrEmpty(expectedResourceKey, "expectedResourceKey"); + ExceptionHelpers.CheckArgumentNotNull(actualMessage, "actualMessage"); + + messageFromResources = _lookup.LookupString(expectedResourceKey); + + if (stringParameters.Length == 0) + { + return IsMatchWithAnyPlaceholderValues(messageFromResources, actualMessage, isExactMatch); + } + else + { + messageFromResources = string.Format(CultureInfo.InvariantCulture, messageFromResources, stringParameters); + + return isExactMatch ? actualMessage == messageFromResources : actualMessage.Contains(messageFromResources); + } + } + + /// + /// Represents a section of a string + /// + private class StringSection + { + /// + /// Gets or sets the index the section starts at + /// + public int StartIndex { get; set; } + + /// + /// Gets or sets the index the section ends at + /// + public int EndIndex { get; set; } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/TestBase.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/TestBase.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestHelpers/TestBase.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/TestBase.cs index 26e6113b..463b7d12 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/TestBase.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/TestBase.cs @@ -1,457 +1,457 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Collections.Generic; - using System.ComponentModel.DataAnnotations; - using System.Configuration; - using System.Data.Common; - using System.Data.Entity.Config; - using System.Data.Entity.Core.EntityClient; - using System.Data.Entity.Core.Metadata.Edm; - using System.Data.Entity.Core.Objects; - using System.Data.Entity.Infrastructure; - using System.Data.Entity.Internal.ConfigFile; - using System.Data.SqlClient; - using System.IO; - using System.Reflection; - using System.Threading.Tasks; - using System.Transactions; - using System.Xml.Linq; - using System.Linq; - using FunctionalTests.TestHelpers; - - public class TestBase : MarshalByRefObject - { - static TestBase() - { - DbConfiguration.SetConfiguration(new FunctionalTestsConfiguration()); - } - - internal DbDatabaseMapping BuildMapping(DbModelBuilder modelBuilder) - { - // Build and clone to check for idempotency issues. - - modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); - - var clone = modelBuilder.Clone(); - - return clone.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; - } - - internal DbDatabaseMapping BuildCeMapping(DbModelBuilder modelBuilder) - { - // Build and clone to check for idempotency issues. - - modelBuilder.Build(ProviderRegistry.SqlCe4_ProviderInfo); - - var clone = modelBuilder.Clone(); - - return clone.Build(ProviderRegistry.SqlCe4_ProviderInfo).DatabaseMapping; - } - - protected static DataRow CreateProviderRow(string name, string invariantName, string assemblyQualifiedName) - { - var table = new DataTable(); - table.Columns.AddRange( - new[] - { - new DataColumn("Name", typeof(string)), - new DataColumn("Description", typeof(string)), - new DataColumn("InvariantName", typeof(string)), - new DataColumn("AssemblyQualifiedName", typeof(string)), - }); - - var row = table.NewRow(); - row["Name"] = name; - row["Description"] = "Name: " + name + " Invariant: " + invariantName; - row["InvariantName"] = invariantName; - row["AssemblyQualifiedName"] = assemblyQualifiedName; - return row; - } - - #region Assemblies and exceptions - - /// - /// The assembly containing Code First and the Productivity API. - /// - public static Assembly EntityFrameworkAssembly - { - get { return typeof(DbModelBuilder).Assembly; } - } - - /// - /// System.ComponentModel.DataAnnotations. - /// - public static Assembly SystemComponentModelDataAnnotationsAssembly - { - get { return typeof(ValidationAttribute).Assembly; } - } - - /// - /// Gets an embedded resource string from the specified assembly - /// - public static string LookupString(Assembly assembly, string resourceTable, string resourceKey) - { - return new AssemblyResourceLookup(assembly, resourceTable).LookupString(resourceKey); - } - - /// - /// Executes the given delegate and returns the exception that it throws. - /// - protected Exception GenerateException(Action willThrow) - { - return ExceptionHelpers.GenerateException(willThrow); - } - - /// - /// Executes the given test multiple times in parallel. - /// - /// The test. - /// The number of copies to run in parallel. - protected static void ExecuteInParallel(Action test, int count = 20) - { - var tests = new Action[count]; - for (var i = 0; i < count; i++) - { - tests[i] = test; - } - Parallel.Invoke(tests); - } - - #endregion - - #region GetObjectContext - - /// - /// Returns the ObjectContext for the given DbContext. - /// - public static ObjectContext GetObjectContext(DbContext context) - { - return ((IObjectContextAdapter)context).ObjectContext; - } - - #endregion - - #region State entry helpers - - /// - /// Gets all GetStateEntries for the given DbContext,. - /// - /// A DbContext instance. - /// All state entries in the ObjectStateManager. - protected static IEnumerable GetStateEntries(DbContext dbContext) - { - return ModelHelpers.GetStateEntries(dbContext); - } - - /// - /// Gets all GetStateEntries for the given ObjectContext,. - /// - /// A ObjectContext instance. - /// All state entries in the ObjectStateManager. - protected static IEnumerable GetStateEntries(ObjectContext objectContext) - { - return ModelHelpers.GetStateEntries(objectContext); - } - - /// - /// Gets the ObjectStateEntry for the given entity in the given DbContext. - /// - /// A DbContext instance. - /// The entity to lookup. - /// The ObjectStateEntry. - protected static ObjectStateEntry GetStateEntry(DbContext dbContext, object entity) - { - return ModelHelpers.GetStateEntry(dbContext, entity); - } - - /// - /// Gets the ObjectStateEntry for the given entity in the given ObjectContext. - /// - /// A ObjectContext instance. - /// The entity to lookup. - /// The ObjectStateEntry. - protected static ObjectStateEntry GetStateEntry(ObjectContext objectContext, object entity) - { - return ModelHelpers.GetStateEntry(objectContext, entity); - } - - /// - /// Asserts that there's no ObjectStateEntry for the given entity in the given DbContext. - /// - /// A DbContext instance. - /// The entity to lookup. - public static void AssertNoStateEntry(DbContext dbContext, object entity) - { - ModelHelpers.AssertNoStateEntry(dbContext, entity); - } - - /// - /// Asserts that there's no ObjectStateEntry for the given entity in the given ObjectContext. - /// - /// A ObjectContext instance. - /// The entity to lookup. - public static void AssertNoStateEntry(ObjectContext objectContext, object entity) - { - ModelHelpers.AssertNoStateEntry(objectContext, entity); - } - - #endregion - - #region Connection helpers - - /// - /// Returns a simple SQL Server connection string to the local machine with the given database name. - /// - /// The database name. - /// The connection string. - protected static string SimpleConnectionString(string databaseName) - { - return ModelHelpers.SimpleConnectionString(databaseName); - } - - /// - /// Returns a simple SQL Server connection string with the specified credentials. - /// - /// The database name. - /// User ID to be use when connecting to SQL Server. - /// Password for the SQL Server account. - /// - /// Indicates if security-sensitive information is not returned as part of the - /// connection if the connection has ever been opened. - /// - /// The connection string. - protected static string SimpleConnectionStringWithCredentials( - string databaseName, - string userId, - string password, - bool persistSecurityInfo = false) - { - return ModelHelpers.SimpleConnectionStringWithCredentials( - databaseName, - userId, - password, - persistSecurityInfo); - } - - /// - /// Returns the default name that will be created for the context of the given type. - /// - /// The type of the context to create a name for. - /// The name. - protected static string DefaultDbName() where TContext : DbContext - { - return ModelHelpers.DefaultDbName(); - } - - /// - /// Returns the transaction count from the server. - /// - /// Database connection to connect against. - /// The transaction count. - protected int GetTransactionCount(DbConnection connection) - { - var closeconn = false; - - if (connection.State - != ConnectionState.Open) - { - connection.Open(); - closeconn = true; - } - - var cmd = connection.CreateCommand(); - cmd.CommandText = "select @@TranCount"; - var trancount = (int)cmd.ExecuteScalar(); - - if (closeconn) - { - connection.Close(); - } - - return trancount; - } - - /// - /// Returns a local transaction. - /// - /// - /// - protected DbTransaction BeginLocalTransaction(DbContext context) - { - return OpenEntityConnection(context).BeginTransaction(); - } - - /// - /// Opens the underlying obtained from the underlying - /// and creates a new . - /// - /// - /// - protected CommittableTransaction BeginCommittableTransaction(DbContext context) - { - OpenEntityConnection(context); - - return new CommittableTransaction(); - } - - /// - /// Opens the underlying obtained from the underlying - /// and returns it. - /// - /// The context. - /// The connection. - private static EntityConnection OpenEntityConnection(DbContext context) - { - var connection = (EntityConnection)((IObjectContextAdapter)context).ObjectContext.Connection; - if (connection.State - != ConnectionState.Open) - { - connection.Open(); - } - - return connection; - } - - /// - /// Closes the underlying obtained from the underlying - /// if the connection is open. - /// - protected void CloseEntityConnection(DbContext context) - { - var connection = ((IObjectContextAdapter)context).ObjectContext.Connection; - if (connection.State - == ConnectionState.Open) - { - connection.Close(); - } - } - - /// - /// Returns a simple SQL Server connection string to the local machine for the given context type. - /// - /// The type of the context to create a connection string for. - /// The connection string. - protected static string SimpleConnectionString() where TContext : DbContext - { - return ModelHelpers.SimpleConnectionString(); - } - - /// - /// Returns a simple SQL Server connection string to the local machine using attached database for the given context type. - /// - /// The type of the context to create a connection string for. - /// The connection string. - protected static string SimpleAttachConnectionString() where TContext : DbContext - { - return ModelHelpers.SimpleAttachConnectionString(); - } - - /// - /// Returns a simple SQLCE connection string to the local machine for the given context type. - /// - /// The type of the context. - /// The connection string. - protected static string SimpleCeConnectionString() where TContext : DbContext - { - return ModelHelpers.SimpleCeConnectionString(); - } - - /// - /// Returns a simple SQL Server connection to the local machine for the given context type. - /// - /// The type of the context to create a connection for. - /// The connection. - protected static SqlConnection SimpleConnection() where TContext : DbContext - { - return ModelHelpers.SimpleConnection(); - } - - /// - /// Returns a simple SQL CE connection for the given context type. - /// - /// The type of the context to create a connection for. - /// The connection. - protected static DbConnection SimpleCeConnection() where TContext : DbContext - { - return ModelHelpers.SimpleCeConnection(); - } - - #endregion - - #region Entity set name helpers - - /// - /// Gets the entity set name for the given CLR type, assuming no MEST. - /// - /// The context to look in. - /// The type to lookup. - /// The entity set name. - protected static string GetEntitySetName(DbContext dbContext, Type clrType) - { - return ModelHelpers.GetEntitySetName(dbContext, clrType); - } - - /// - /// Gets the entity set name for the given CLR type, assuming no MEST. - /// - /// The context to look in. - /// The type to lookup. - /// The entity set name. - protected static string GetEntitySetName(ObjectContext objetContext, Type clrType) - { - return ModelHelpers.GetEntitySetName(objetContext, clrType); - } - - #endregion - - #region Entity Type helpers - - /// - /// Gets the EntityType of the given CLR type - /// - /// The context to look in. - /// The CLR type - /// The entity type corresponding to the CLR type - protected static EntityType GetEntityType(DbContext dbContext, Type clrType) - { - return ModelHelpers.GetEntityType(dbContext, clrType); - } - - /// - /// Gets the EntityType of the given CLR type - /// - /// The context to look in. - /// The CLR type - /// The entity type corresponding to the CLR type - protected static EntityType GetEntityType(ObjectContext objectContext, Type clrType) - { - return ModelHelpers.GetStructuralType(objectContext, clrType); - } - - #endregion - - #region Creating config documents - - public static Configuration CreateEmptyConfig() - { - var tempFileName = Path.GetTempFileName(); - var doc = new XDocument(new XElement("configuration")); - doc.Save(tempFileName); - - var config = ConfigurationManager.OpenMappedExeConfiguration( - new ExeConfigurationFileMap - { - ExeConfigFilename = tempFileName - }, - ConfigurationUserLevel.None); - - config.Sections.Add("entityFramework", new EntityFrameworkSection()); - - return config; - } - - #endregion - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + using System.Configuration; + using System.Data.Common; + using System.Data.Entity.Config; + using System.Data.Entity.Core.EntityClient; + using System.Data.Entity.Core.Metadata.Edm; + using System.Data.Entity.Core.Objects; + using System.Data.Entity.Infrastructure; + using System.Data.Entity.Internal.ConfigFile; + using System.Data.SqlClient; + using System.IO; + using System.Reflection; + using System.Threading.Tasks; + using System.Transactions; + using System.Xml.Linq; + using System.Linq; + using FunctionalTests.TestHelpers; + + public class TestBase : MarshalByRefObject + { + static TestBase() + { + DbConfiguration.SetConfiguration(new FunctionalTestsConfiguration()); + } + + internal DbDatabaseMapping BuildMapping(DbModelBuilder modelBuilder) + { + // Build and clone to check for idempotency issues. + + modelBuilder.Build(ProviderRegistry.Sql2008_ProviderInfo); + + var clone = modelBuilder.Clone(); + + return clone.Build(ProviderRegistry.Sql2008_ProviderInfo).DatabaseMapping; + } + + internal DbDatabaseMapping BuildCeMapping(DbModelBuilder modelBuilder) + { + // Build and clone to check for idempotency issues. + + modelBuilder.Build(ProviderRegistry.SqlCe4_ProviderInfo); + + var clone = modelBuilder.Clone(); + + return clone.Build(ProviderRegistry.SqlCe4_ProviderInfo).DatabaseMapping; + } + + protected static DataRow CreateProviderRow(string name, string invariantName, string assemblyQualifiedName) + { + var table = new DataTable(); + table.Columns.AddRange( + new[] + { + new DataColumn("Name", typeof(string)), + new DataColumn("Description", typeof(string)), + new DataColumn("InvariantName", typeof(string)), + new DataColumn("AssemblyQualifiedName", typeof(string)), + }); + + var row = table.NewRow(); + row["Name"] = name; + row["Description"] = "Name: " + name + " Invariant: " + invariantName; + row["InvariantName"] = invariantName; + row["AssemblyQualifiedName"] = assemblyQualifiedName; + return row; + } + + #region Assemblies and exceptions + + /// + /// The assembly containing Code First and the Productivity API. + /// + public static Assembly EntityFrameworkAssembly + { + get { return typeof(DbModelBuilder).Assembly; } + } + + /// + /// System.ComponentModel.DataAnnotations. + /// + public static Assembly SystemComponentModelDataAnnotationsAssembly + { + get { return typeof(ValidationAttribute).Assembly; } + } + + /// + /// Gets an embedded resource string from the specified assembly + /// + public static string LookupString(Assembly assembly, string resourceTable, string resourceKey) + { + return new AssemblyResourceLookup(assembly, resourceTable).LookupString(resourceKey); + } + + /// + /// Executes the given delegate and returns the exception that it throws. + /// + protected Exception GenerateException(Action willThrow) + { + return ExceptionHelpers.GenerateException(willThrow); + } + + /// + /// Executes the given test multiple times in parallel. + /// + /// The test. + /// The number of copies to run in parallel. + protected static void ExecuteInParallel(Action test, int count = 20) + { + var tests = new Action[count]; + for (var i = 0; i < count; i++) + { + tests[i] = test; + } + Parallel.Invoke(tests); + } + + #endregion + + #region GetObjectContext + + /// + /// Returns the ObjectContext for the given DbContext. + /// + public static ObjectContext GetObjectContext(DbContext context) + { + return ((IObjectContextAdapter)context).ObjectContext; + } + + #endregion + + #region State entry helpers + + /// + /// Gets all GetStateEntries for the given DbContext,. + /// + /// A DbContext instance. + /// All state entries in the ObjectStateManager. + protected static IEnumerable GetStateEntries(DbContext dbContext) + { + return ModelHelpers.GetStateEntries(dbContext); + } + + /// + /// Gets all GetStateEntries for the given ObjectContext,. + /// + /// A ObjectContext instance. + /// All state entries in the ObjectStateManager. + protected static IEnumerable GetStateEntries(ObjectContext objectContext) + { + return ModelHelpers.GetStateEntries(objectContext); + } + + /// + /// Gets the ObjectStateEntry for the given entity in the given DbContext. + /// + /// A DbContext instance. + /// The entity to lookup. + /// The ObjectStateEntry. + protected static ObjectStateEntry GetStateEntry(DbContext dbContext, object entity) + { + return ModelHelpers.GetStateEntry(dbContext, entity); + } + + /// + /// Gets the ObjectStateEntry for the given entity in the given ObjectContext. + /// + /// A ObjectContext instance. + /// The entity to lookup. + /// The ObjectStateEntry. + protected static ObjectStateEntry GetStateEntry(ObjectContext objectContext, object entity) + { + return ModelHelpers.GetStateEntry(objectContext, entity); + } + + /// + /// Asserts that there's no ObjectStateEntry for the given entity in the given DbContext. + /// + /// A DbContext instance. + /// The entity to lookup. + public static void AssertNoStateEntry(DbContext dbContext, object entity) + { + ModelHelpers.AssertNoStateEntry(dbContext, entity); + } + + /// + /// Asserts that there's no ObjectStateEntry for the given entity in the given ObjectContext. + /// + /// A ObjectContext instance. + /// The entity to lookup. + public static void AssertNoStateEntry(ObjectContext objectContext, object entity) + { + ModelHelpers.AssertNoStateEntry(objectContext, entity); + } + + #endregion + + #region Connection helpers + + /// + /// Returns a simple SQL Server connection string to the local machine with the given database name. + /// + /// The database name. + /// The connection string. + protected static string SimpleConnectionString(string databaseName) + { + return ModelHelpers.SimpleConnectionString(databaseName); + } + + /// + /// Returns a simple SQL Server connection string with the specified credentials. + /// + /// The database name. + /// User ID to be use when connecting to SQL Server. + /// Password for the SQL Server account. + /// + /// Indicates if security-sensitive information is not returned as part of the + /// connection if the connection has ever been opened. + /// + /// The connection string. + protected static string SimpleConnectionStringWithCredentials( + string databaseName, + string userId, + string password, + bool persistSecurityInfo = false) + { + return ModelHelpers.SimpleConnectionStringWithCredentials( + databaseName, + userId, + password, + persistSecurityInfo); + } + + /// + /// Returns the default name that will be created for the context of the given type. + /// + /// The type of the context to create a name for. + /// The name. + protected static string DefaultDbName() where TContext : DbContext + { + return ModelHelpers.DefaultDbName(); + } + + /// + /// Returns the transaction count from the server. + /// + /// Database connection to connect against. + /// The transaction count. + protected int GetTransactionCount(DbConnection connection) + { + var closeconn = false; + + if (connection.State + != ConnectionState.Open) + { + connection.Open(); + closeconn = true; + } + + var cmd = connection.CreateCommand(); + cmd.CommandText = "select @@TranCount"; + var trancount = (int)cmd.ExecuteScalar(); + + if (closeconn) + { + connection.Close(); + } + + return trancount; + } + + /// + /// Returns a local transaction. + /// + /// + /// + protected DbTransaction BeginLocalTransaction(DbContext context) + { + return OpenEntityConnection(context).BeginTransaction(); + } + + /// + /// Opens the underlying obtained from the underlying + /// and creates a new . + /// + /// + /// + protected CommittableTransaction BeginCommittableTransaction(DbContext context) + { + OpenEntityConnection(context); + + return new CommittableTransaction(); + } + + /// + /// Opens the underlying obtained from the underlying + /// and returns it. + /// + /// The context. + /// The connection. + private static EntityConnection OpenEntityConnection(DbContext context) + { + var connection = (EntityConnection)((IObjectContextAdapter)context).ObjectContext.Connection; + if (connection.State + != ConnectionState.Open) + { + connection.Open(); + } + + return connection; + } + + /// + /// Closes the underlying obtained from the underlying + /// if the connection is open. + /// + protected void CloseEntityConnection(DbContext context) + { + var connection = ((IObjectContextAdapter)context).ObjectContext.Connection; + if (connection.State + == ConnectionState.Open) + { + connection.Close(); + } + } + + /// + /// Returns a simple SQL Server connection string to the local machine for the given context type. + /// + /// The type of the context to create a connection string for. + /// The connection string. + protected static string SimpleConnectionString() where TContext : DbContext + { + return ModelHelpers.SimpleConnectionString(); + } + + /// + /// Returns a simple SQL Server connection string to the local machine using attached database for the given context type. + /// + /// The type of the context to create a connection string for. + /// The connection string. + protected static string SimpleAttachConnectionString() where TContext : DbContext + { + return ModelHelpers.SimpleAttachConnectionString(); + } + + /// + /// Returns a simple SQLCE connection string to the local machine for the given context type. + /// + /// The type of the context. + /// The connection string. + protected static string SimpleCeConnectionString() where TContext : DbContext + { + return ModelHelpers.SimpleCeConnectionString(); + } + + /// + /// Returns a simple SQL Server connection to the local machine for the given context type. + /// + /// The type of the context to create a connection for. + /// The connection. + protected static SqlConnection SimpleConnection() where TContext : DbContext + { + return ModelHelpers.SimpleConnection(); + } + + /// + /// Returns a simple SQL CE connection for the given context type. + /// + /// The type of the context to create a connection for. + /// The connection. + protected static DbConnection SimpleCeConnection() where TContext : DbContext + { + return ModelHelpers.SimpleCeConnection(); + } + + #endregion + + #region Entity set name helpers + + /// + /// Gets the entity set name for the given CLR type, assuming no MEST. + /// + /// The context to look in. + /// The type to lookup. + /// The entity set name. + protected static string GetEntitySetName(DbContext dbContext, Type clrType) + { + return ModelHelpers.GetEntitySetName(dbContext, clrType); + } + + /// + /// Gets the entity set name for the given CLR type, assuming no MEST. + /// + /// The context to look in. + /// The type to lookup. + /// The entity set name. + protected static string GetEntitySetName(ObjectContext objetContext, Type clrType) + { + return ModelHelpers.GetEntitySetName(objetContext, clrType); + } + + #endregion + + #region Entity Type helpers + + /// + /// Gets the EntityType of the given CLR type + /// + /// The context to look in. + /// The CLR type + /// The entity type corresponding to the CLR type + protected static EntityType GetEntityType(DbContext dbContext, Type clrType) + { + return ModelHelpers.GetEntityType(dbContext, clrType); + } + + /// + /// Gets the EntityType of the given CLR type + /// + /// The context to look in. + /// The CLR type + /// The entity type corresponding to the CLR type + protected static EntityType GetEntityType(ObjectContext objectContext, Type clrType) + { + return ModelHelpers.GetStructuralType(objectContext, clrType); + } + + #endregion + + #region Creating config documents + + public static Configuration CreateEmptyConfig() + { + var tempFileName = Path.GetTempFileName(); + var doc = new XDocument(new XElement("configuration")); + doc.Save(tempFileName); + + var config = ConfigurationManager.OpenMappedExeConfiguration( + new ExeConfigurationFileMap + { + ExeConfigFilename = tempFileName + }, + ConfigurationUserLevel.None); + + config.Sections.Add("entityFramework", new EntityFrameworkSection()); + + return config; + } + + #endregion + } +} diff --git a/test/EntityFramework/FunctionalTests/TestHelpers/TypeAssertion`.cs b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/TypeAssertion`.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestHelpers/TypeAssertion`.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestHelpers/TypeAssertion`.cs index 1af08b77..7ab77c7c 100644 --- a/test/EntityFramework/FunctionalTests/TestHelpers/TypeAssertion`.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestHelpers/TypeAssertion`.cs @@ -1,36 +1,36 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity -{ - using System.Data.Entity.Core.Metadata.Edm; - using Xunit; - - public class TypeAssertion - where TStructuralType : class - { - private readonly DbContext _context; - - public TypeAssertion(DbContext context) - { - _context = context; - } - - public void IsNotInModel() - { - Assert.Null(ModelHelpers.GetEntitySetName(_context, typeof(TStructuralType))); - } - - public void IsInModel() - { - Assert.NotNull(ModelHelpers.GetEntitySetName(_context, typeof(TStructuralType))); - } - - public void IsComplexType() - { - Assert.NotNull( - ModelHelpers.GetStructuralType( - TestBase.GetObjectContext(_context), - typeof(TStructuralType))); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace System.Data.Entity +{ + using System.Data.Entity.Core.Metadata.Edm; + using Xunit; + + public class TypeAssertion + where TStructuralType : class + { + private readonly DbContext _context; + + public TypeAssertion(DbContext context) + { + _context = context; + } + + public void IsNotInModel() + { + Assert.Null(ModelHelpers.GetEntitySetName(_context, typeof(TStructuralType))); + } + + public void IsInModel() + { + Assert.NotNull(ModelHelpers.GetEntitySetName(_context, typeof(TStructuralType))); + } + + public void IsComplexType() + { + Assert.NotNull( + ModelHelpers.GetStructuralType( + TestBase.GetObjectContext(_context), + typeof(TStructuralType))); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/Address.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/Address.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/Address.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/Address.cs index d12468f0..8bf541ea 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/Address.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/Address.cs @@ -1,36 +1,36 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - using System; - using System.Globalization; - - public class Address - { - public string Street { get; set; } - public string City { get; set; } - public string State { get; set; } - public string ZipCode { get; set; } - public SiteInfo SiteInfo { get; set; } - - // None of the properties below are mapped - public string County { get; set; } - - public string FormattedAddress - { - get { return String.Format(CultureInfo.InvariantCulture, "{0}, {1}, {2} {3}", Street, City, State, ZipCode); } - } - - private string _writeOnly = "WriteOnly"; - - public string WriteOnly - { - set { _writeOnly = value; } - } - - public string GetWriteOnlyValue() - { - return _writeOnly; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + using System; + using System.Globalization; + + public class Address + { + public string Street { get; set; } + public string City { get; set; } + public string State { get; set; } + public string ZipCode { get; set; } + public SiteInfo SiteInfo { get; set; } + + // None of the properties below are mapped + public string County { get; set; } + + public string FormattedAddress + { + get { return String.Format(CultureInfo.InvariantCulture, "{0}, {1}, {2} {3}", Street, City, State, ZipCode); } + } + + private string _writeOnly = "WriteOnly"; + + public string WriteOnly + { + set { _writeOnly = value; } + } + + public string GetWriteOnlyValue() + { + return _writeOnly; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/AdvancedPatternsInitializer.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/AdvancedPatternsInitializer.cs similarity index 98% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/AdvancedPatternsInitializer.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/AdvancedPatternsInitializer.cs index 9f6b1c35..2e75e4d4 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/AdvancedPatternsInitializer.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/AdvancedPatternsInitializer.cs @@ -1,129 +1,129 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - using System; - using System.Collections.Generic; - using System.Data.Entity; - - public class AdvancedPatternsInitializer : DropCreateDatabaseIfModelChanges - { - protected override void Seed(AdvancedPatternsMasterContext context) - { - var buildings = new List - { - new Building - { - BuildingId = new Guid("21EC2020-3AEA-1069-A2DD-08002B30309D"), - Name = "Building One", - Value = 1500000m, - Address = new Address - { - Street = "100 Work St", - City = "Redmond", - State = "WA", - ZipCode = "98052", - SiteInfo = new SiteInfo - { - Zone = 1, - Environment = "Clean" - } - }, - }, - new Building - { - BuildingId = Guid.NewGuid(), - Name = "Building Two", - Value = 1000000m, - Address = new Address - { - Street = "200 Work St", - City = "Redmond", - State = "WA", - ZipCode = "98052", - SiteInfo = new SiteInfo - { - Zone = 2, - Environment = "Contaminated" - } - }, - }, - }; - buildings.ForEach(b => context.Buildings.Add(b)); - - var offices = new List - { - new Office - { - BuildingId = buildings[0].BuildingId, - Number = "1/1221" - }, - new Office - { - BuildingId = buildings[0].BuildingId, - Number = "1/1223" - }, - new Office - { - BuildingId = buildings[0].BuildingId, - Number = "2/1458" - }, - new Office - { - BuildingId = buildings[0].BuildingId, - Number = "2/1789" - }, - }; - offices.ForEach(o => context.Offices.Add(o)); - - new List - { - new CurrentEmployee - { - EmployeeId = 1, - FirstName = "Rowan", - LastName = "Miller", - LeaveBalance = 45, - Office = offices[0] - }, - new CurrentEmployee - { - EmployeeId = 2, - FirstName = "Arthur", - LastName = "Vickers", - LeaveBalance = 62, - Office = offices[1] - }, - new PastEmployee - { - EmployeeId = 3, - FirstName = "John", - LastName = "Doe", - TerminationDate = new DateTime(2006, 1, 23) - }, - }.ForEach(e => context.Employees.Add(e)); - - new List - { - new Whiteboard - { - AssetTag = "WB1973", - iD = new byte[] { 1, 9, 7, 3 }, - Office = offices[0] - }, - new Whiteboard - { - AssetTag = "WB1977", - iD = new byte[] { 1, 9, 7, 7 }, - Office = offices[0] - }, - new Whiteboard - { - AssetTag = "WB1970", - iD = new byte[] { 1, 9, 7, 0 }, - Office = offices[2] - }, - }.ForEach(w => context.Whiteboards.Add(w)); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + using System; + using System.Collections.Generic; + using System.Data.Entity; + + public class AdvancedPatternsInitializer : DropCreateDatabaseIfModelChanges + { + protected override void Seed(AdvancedPatternsMasterContext context) + { + var buildings = new List + { + new Building + { + BuildingId = new Guid("21EC2020-3AEA-1069-A2DD-08002B30309D"), + Name = "Building One", + Value = 1500000m, + Address = new Address + { + Street = "100 Work St", + City = "Redmond", + State = "WA", + ZipCode = "98052", + SiteInfo = new SiteInfo + { + Zone = 1, + Environment = "Clean" + } + }, + }, + new Building + { + BuildingId = Guid.NewGuid(), + Name = "Building Two", + Value = 1000000m, + Address = new Address + { + Street = "200 Work St", + City = "Redmond", + State = "WA", + ZipCode = "98052", + SiteInfo = new SiteInfo + { + Zone = 2, + Environment = "Contaminated" + } + }, + }, + }; + buildings.ForEach(b => context.Buildings.Add(b)); + + var offices = new List + { + new Office + { + BuildingId = buildings[0].BuildingId, + Number = "1/1221" + }, + new Office + { + BuildingId = buildings[0].BuildingId, + Number = "1/1223" + }, + new Office + { + BuildingId = buildings[0].BuildingId, + Number = "2/1458" + }, + new Office + { + BuildingId = buildings[0].BuildingId, + Number = "2/1789" + }, + }; + offices.ForEach(o => context.Offices.Add(o)); + + new List + { + new CurrentEmployee + { + EmployeeId = 1, + FirstName = "Rowan", + LastName = "Miller", + LeaveBalance = 45, + Office = offices[0] + }, + new CurrentEmployee + { + EmployeeId = 2, + FirstName = "Arthur", + LastName = "Vickers", + LeaveBalance = 62, + Office = offices[1] + }, + new PastEmployee + { + EmployeeId = 3, + FirstName = "John", + LastName = "Doe", + TerminationDate = new DateTime(2006, 1, 23) + }, + }.ForEach(e => context.Employees.Add(e)); + + new List + { + new Whiteboard + { + AssetTag = "WB1973", + iD = new byte[] { 1, 9, 7, 3 }, + Office = offices[0] + }, + new Whiteboard + { + AssetTag = "WB1977", + iD = new byte[] { 1, 9, 7, 7 }, + Office = offices[0] + }, + new Whiteboard + { + AssetTag = "WB1970", + iD = new byte[] { 1, 9, 7, 0 }, + Office = offices[2] + }, + }.ForEach(w => context.Whiteboards.Add(w)); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/AdvancedPatternsMasterContext.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/AdvancedPatternsMasterContext.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/AdvancedPatternsMasterContext.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/AdvancedPatternsMasterContext.cs index 9761d31b..36cffc89 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/AdvancedPatternsMasterContext.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/AdvancedPatternsMasterContext.cs @@ -1,57 +1,57 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - using System.Data.Entity; - - public class AdvancedPatternsMasterContext : DbContext - { - public AdvancedPatternsMasterContext() - : base("AdvancedPatternsDatabase") - { - } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - SetupModel(modelBuilder); - base.OnModelCreating(modelBuilder); - } - - internal static void SetupModel(DbModelBuilder builder) - { - builder.Entity(); - builder.Entity() - .HasOptional(b => b.PrincipalMailRoom) - .WithMany() - .HasForeignKey(b => b.PrincipalMailRoomId); - - builder.ComplexType
(); - builder.ComplexType(); - builder.Entity() - .HasRequired(m => m.Building) - .WithMany(b => b.MailRooms) - .HasForeignKey(m => m.BuildingId); - - builder.Entity().HasKey( - o => new - { - o.Number, - o.BuildingId - }); - builder.Ignore(); - builder.Entity() - .HasKey(d => d.BuildingId) - .HasRequired(d => d.Building).WithOptional(); - - builder.Entity().Ignore(b => b.NotInModel); - builder.ComplexType
().Ignore(a => a.County); - } - - public DbSet Employees { get; set; } - public DbSet Offices { get; set; } - public DbSet Buildings { get; set; } - public DbSet BuildingDetails { get; set; } - public DbSet WorkOrders { get; set; } - public DbSet Whiteboards { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + using System.Data.Entity; + + public class AdvancedPatternsMasterContext : DbContext + { + public AdvancedPatternsMasterContext() + : base("AdvancedPatternsDatabase") + { + } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + SetupModel(modelBuilder); + base.OnModelCreating(modelBuilder); + } + + internal static void SetupModel(DbModelBuilder builder) + { + builder.Entity(); + builder.Entity() + .HasOptional(b => b.PrincipalMailRoom) + .WithMany() + .HasForeignKey(b => b.PrincipalMailRoomId); + + builder.ComplexType
(); + builder.ComplexType(); + builder.Entity() + .HasRequired(m => m.Building) + .WithMany(b => b.MailRooms) + .HasForeignKey(m => m.BuildingId); + + builder.Entity().HasKey( + o => new + { + o.Number, + o.BuildingId + }); + builder.Ignore(); + builder.Entity() + .HasKey(d => d.BuildingId) + .HasRequired(d => d.Building).WithOptional(); + + builder.Entity().Ignore(b => b.NotInModel); + builder.ComplexType
().Ignore(a => a.County); + } + + public DbSet Employees { get; set; } + public DbSet Offices { get; set; } + public DbSet Buildings { get; set; } + public DbSet BuildingDetails { get; set; } + public DbSet WorkOrders { get; set; } + public DbSet Whiteboards { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/AdvancedPatternsModelFirstInitializer.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/AdvancedPatternsModelFirstInitializer.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/AdvancedPatternsModelFirstInitializer.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/AdvancedPatternsModelFirstInitializer.cs index 16fbf201..3675bcb3 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/AdvancedPatternsModelFirstInitializer.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/AdvancedPatternsModelFirstInitializer.cs @@ -1,140 +1,140 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - using System; - using System.Collections.Generic; - using System.Data.Entity; - - internal class AdvancedPatternsModelFirstInitializer : DropCreateDatabaseAlways - { - private static readonly Guid _knownBuildingGuid = new Guid("21EC2020-3AEA-1069-A2DD-08002B30309D"); - - public static Guid KnownBuildingGuid - { - get { return _knownBuildingGuid; } - } - - protected override void Seed(AdvancedPatternsModelFirstContext context) - { - context.Database.ExecuteSqlCommand(@"CREATE PROCEDURE dbo.AllOffices - AS - SET NOCOUNT ON; - SELECT Number, BuildingId, Description - FROM dbo.Offices"); - - context.Database.ExecuteSqlCommand(@"CREATE PROCEDURE dbo.OfficesInBuilding - @BuildingId uniqueidentifier - AS - SET NOCOUNT ON; - SELECT Number, BuildingId, Description - FROM dbo.Offices - WHERE BuildingId = @BuildingId"); - - context.Database.ExecuteSqlCommand( - @"CREATE PROCEDURE dbo.SkimOffLeaveBalance - @First nvarchar(4000), - @Last nvarchar(4000) - AS - SET NOCOUNT ON; - UPDATE dbo.Employees - SET LeaveBalance = 0 - WHERE FirstName = @First And LastName = @Last"); - - context.Database.ExecuteSqlCommand( - @"CREATE PROCEDURE dbo.EmployeeIdsInOffice - @OfficeNumber nvarchar(128), - @BuildingId uniqueidentifier - AS - SET NOCOUNT ON; - SELECT EmployeeId - FROM dbo.Employees - WHERE OfficeBuildingId = @BuildingId And OfficeNumber = @OfficeNumber"); - - context.Database.ExecuteSqlCommand(@"CREATE PROCEDURE dbo.AllSiteInfo - AS - SET NOCOUNT ON; - SELECT Zone, Environment - FROM dbo.Buildings"); - - var buildings = new List - { - new BuildingMf( - _knownBuildingGuid, "Building One", 1500000m, - new AddressMf("100 Work St", "Redmond", "WA", "98052", 1, "Clean")), - new BuildingMf( - Guid.NewGuid(), "Building Two", 1000000m, - new AddressMf("200 Work St", "Redmond", "WA", "98052", 2, "Contaminated")), - }; - buildings.ForEach(b => context.Buildings.Add(b)); - - var offices = new List - { - new OfficeMf - { - BuildingId = buildings[0].BuildingId, - Number = "1/1221" - }, - new OfficeMf - { - BuildingId = buildings[0].BuildingId, - Number = "1/1223" - }, - new OfficeMf - { - BuildingId = buildings[1].BuildingId, - Number = "2/1458" - }, - new OfficeMf - { - BuildingId = buildings[1].BuildingId, - Number = "2/1789" - }, - }; - offices.ForEach(o => context.Offices.Add(o)); - - new List - { - new CurrentEmployeeMf("Rowan", "Miller") - { - EmployeeId = 1, - LeaveBalance = 45, - Office = offices[0] - }, - new CurrentEmployeeMf("Arthur", "Vickers") - { - EmployeeId = 2, - LeaveBalance = 62, - Office = offices[1] - }, - new PastEmployeeMf("John", "Doe") - { - EmployeeId = 3, - TerminationDate = new DateTime(2006, 1, 23) - }, - }.ForEach(e => context.Employees.Add(e)); - - new List - { - new WhiteboardMf - { - AssetTag = "WB1973", - iD = new byte[] { 1, 9, 7, 3 }, - Office = offices[0] - }, - new WhiteboardMf - { - AssetTag = "WB1977", - iD = new byte[] { 1, 9, 7, 7 }, - Office = offices[0] - }, - new WhiteboardMf - { - AssetTag = "WB1970", - iD = new byte[] { 1, 9, 7, 0 }, - Office = offices[2] - }, - }.ForEach(w => context.Whiteboards.Add(w)); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + using System; + using System.Collections.Generic; + using System.Data.Entity; + + internal class AdvancedPatternsModelFirstInitializer : DropCreateDatabaseAlways + { + private static readonly Guid _knownBuildingGuid = new Guid("21EC2020-3AEA-1069-A2DD-08002B30309D"); + + public static Guid KnownBuildingGuid + { + get { return _knownBuildingGuid; } + } + + protected override void Seed(AdvancedPatternsModelFirstContext context) + { + context.Database.ExecuteSqlCommand(@"CREATE PROCEDURE dbo.AllOffices + AS + SET NOCOUNT ON; + SELECT Number, BuildingId, Description + FROM dbo.Offices"); + + context.Database.ExecuteSqlCommand(@"CREATE PROCEDURE dbo.OfficesInBuilding + @BuildingId uniqueidentifier + AS + SET NOCOUNT ON; + SELECT Number, BuildingId, Description + FROM dbo.Offices + WHERE BuildingId = @BuildingId"); + + context.Database.ExecuteSqlCommand( + @"CREATE PROCEDURE dbo.SkimOffLeaveBalance + @First nvarchar(4000), + @Last nvarchar(4000) + AS + SET NOCOUNT ON; + UPDATE dbo.Employees + SET LeaveBalance = 0 + WHERE FirstName = @First And LastName = @Last"); + + context.Database.ExecuteSqlCommand( + @"CREATE PROCEDURE dbo.EmployeeIdsInOffice + @OfficeNumber nvarchar(128), + @BuildingId uniqueidentifier + AS + SET NOCOUNT ON; + SELECT EmployeeId + FROM dbo.Employees + WHERE OfficeBuildingId = @BuildingId And OfficeNumber = @OfficeNumber"); + + context.Database.ExecuteSqlCommand(@"CREATE PROCEDURE dbo.AllSiteInfo + AS + SET NOCOUNT ON; + SELECT Zone, Environment + FROM dbo.Buildings"); + + var buildings = new List + { + new BuildingMf( + _knownBuildingGuid, "Building One", 1500000m, + new AddressMf("100 Work St", "Redmond", "WA", "98052", 1, "Clean")), + new BuildingMf( + Guid.NewGuid(), "Building Two", 1000000m, + new AddressMf("200 Work St", "Redmond", "WA", "98052", 2, "Contaminated")), + }; + buildings.ForEach(b => context.Buildings.Add(b)); + + var offices = new List + { + new OfficeMf + { + BuildingId = buildings[0].BuildingId, + Number = "1/1221" + }, + new OfficeMf + { + BuildingId = buildings[0].BuildingId, + Number = "1/1223" + }, + new OfficeMf + { + BuildingId = buildings[1].BuildingId, + Number = "2/1458" + }, + new OfficeMf + { + BuildingId = buildings[1].BuildingId, + Number = "2/1789" + }, + }; + offices.ForEach(o => context.Offices.Add(o)); + + new List + { + new CurrentEmployeeMf("Rowan", "Miller") + { + EmployeeId = 1, + LeaveBalance = 45, + Office = offices[0] + }, + new CurrentEmployeeMf("Arthur", "Vickers") + { + EmployeeId = 2, + LeaveBalance = 62, + Office = offices[1] + }, + new PastEmployeeMf("John", "Doe") + { + EmployeeId = 3, + TerminationDate = new DateTime(2006, 1, 23) + }, + }.ForEach(e => context.Employees.Add(e)); + + new List + { + new WhiteboardMf + { + AssetTag = "WB1973", + iD = new byte[] { 1, 9, 7, 3 }, + Office = offices[0] + }, + new WhiteboardMf + { + AssetTag = "WB1977", + iD = new byte[] { 1, 9, 7, 7 }, + Office = offices[0] + }, + new WhiteboardMf + { + AssetTag = "WB1970", + iD = new byte[] { 1, 9, 7, 0 }, + Office = offices[2] + }, + }.ForEach(w => context.Whiteboards.Add(w)); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/Building.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/Building.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/Building.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/Building.cs index 51e29935..ae6bcc70 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/Building.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/Building.cs @@ -1,45 +1,45 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - using System; - using System.Collections.Generic; - - public class Building - { - public Building() - { - Offices = new List(); - MailRooms = new List(); - } - - public Guid BuildingId { get; set; } - public string Name { get; set; } - public decimal Value { get; set; } - public virtual ICollection Offices { get; set; } - public virtual IList MailRooms { get; set; } - public Address Address { get; set; } - - public int? PrincipalMailRoomId { get; set; } - public MailRoom PrincipalMailRoom { get; set; } - - public string NotInModel { get; set; } - - private string _noGetter = "NoGetter"; - - public string NoGetter - { - set { _noGetter = value; } - } - - public string GetNoGetterValue() - { - return _noGetter; - } - - public string NoSetter - { - get { return "NoSetter"; } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + using System; + using System.Collections.Generic; + + public class Building + { + public Building() + { + Offices = new List(); + MailRooms = new List(); + } + + public Guid BuildingId { get; set; } + public string Name { get; set; } + public decimal Value { get; set; } + public virtual ICollection Offices { get; set; } + public virtual IList MailRooms { get; set; } + public Address Address { get; set; } + + public int? PrincipalMailRoomId { get; set; } + public MailRoom PrincipalMailRoom { get; set; } + + public string NotInModel { get; set; } + + private string _noGetter = "NoGetter"; + + public string NoGetter + { + set { _noGetter = value; } + } + + public string GetNoGetterValue() + { + return _noGetter; + } + + public string NoSetter + { + get { return "NoSetter"; } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/BuildingDetail.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/BuildingDetail.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/BuildingDetail.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/BuildingDetail.cs index 60cbc81c..530b8101 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/BuildingDetail.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/BuildingDetail.cs @@ -1,13 +1,13 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - using System; - - public class BuildingDetail - { - public Guid BuildingId { get; set; } - public Building Building { get; set; } - public string Details { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + using System; + + public class BuildingDetail + { + public Guid BuildingId { get; set; } + public Building Building { get; set; } + public string Details { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/CurrentEmployee.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/CurrentEmployee.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/CurrentEmployee.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/CurrentEmployee.cs index baf82d6f..6c408bd1 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/CurrentEmployee.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/CurrentEmployee.cs @@ -1,11 +1,11 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - public class CurrentEmployee : Employee - { - public CurrentEmployee Manager { get; set; } - public decimal LeaveBalance { get; set; } - public Office Office { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + public class CurrentEmployee : Employee + { + public CurrentEmployee Manager { get; set; } + public decimal LeaveBalance { get; set; } + public Office Office { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/Employee.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/Employee.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/Employee.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/Employee.cs index 2e3305c4..538b19fc 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/Employee.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/Employee.cs @@ -1,9 +1,9 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - public abstract class Employee : UnMappedPersonBase - { - public int EmployeeId { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + public abstract class Employee : UnMappedPersonBase + { + public int EmployeeId { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/MailRoom.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/MailRoom.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/MailRoom.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/MailRoom.cs index 5989d773..30901e29 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/MailRoom.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/MailRoom.cs @@ -1,13 +1,13 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - using System; - - public class MailRoom - { - public int id { get; set; } - public Building Building { get; set; } - public Guid BuildingId { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + using System; + + public class MailRoom + { + public int id { get; set; } + public Building Building { get; set; } + public Guid BuildingId { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/Office.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/Office.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/Office.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/Office.cs index 29a849b1..81ba061a 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/Office.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/Office.cs @@ -1,19 +1,19 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - using System; - using System.Collections.Generic; - - public class Office : UnMappedOfficeBase - { - public Office() - { - WhiteBoards = new List(); - } - - public Guid BuildingId { get; set; } - public Building Building { get; set; } - public IList WhiteBoards { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + using System; + using System.Collections.Generic; + + public class Office : UnMappedOfficeBase + { + public Office() + { + WhiteBoards = new List(); + } + + public Guid BuildingId { get; set; } + public Building Building { get; set; } + public IList WhiteBoards { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/PastEmployee.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/PastEmployee.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/PastEmployee.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/PastEmployee.cs index 7a15997e..388eae69 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/PastEmployee.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/PastEmployee.cs @@ -1,11 +1,11 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - using System; - - public class PastEmployee : Employee - { - public DateTime TerminationDate { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + using System; + + public class PastEmployee : Employee + { + public DateTime TerminationDate { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/SiteInfo.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/SiteInfo.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/SiteInfo.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/SiteInfo.cs index 74f9eb09..a540b9b3 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/SiteInfo.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/SiteInfo.cs @@ -1,10 +1,10 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - public class SiteInfo - { - public int? Zone { get; set; } - public string Environment { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + public class SiteInfo + { + public int? Zone { get; set; } + public string Environment { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/UnMappedOffice.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/UnMappedOffice.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/UnMappedOffice.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/UnMappedOffice.cs index 0c20c1a5..68085f1f 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/UnMappedOffice.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/UnMappedOffice.cs @@ -1,8 +1,8 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - public class UnMappedOffice : Office - { - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + public class UnMappedOffice : Office + { + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/UnMappedOfficeBase.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/UnMappedOfficeBase.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/UnMappedOfficeBase.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/UnMappedOfficeBase.cs index 69d34fcd..8f772f50 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/UnMappedOfficeBase.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/UnMappedOfficeBase.cs @@ -1,10 +1,10 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - public abstract class UnMappedOfficeBase - { - public string Number { get; set; } - public string Description { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + public abstract class UnMappedOfficeBase + { + public string Number { get; set; } + public string Description { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/UnMappedPersonBase.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/UnMappedPersonBase.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/UnMappedPersonBase.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/UnMappedPersonBase.cs index 8484f38a..2d6c7887 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/UnMappedPersonBase.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/UnMappedPersonBase.cs @@ -1,10 +1,10 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - public class UnMappedPersonBase - { - public string FirstName { get; set; } - public string LastName { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + public class UnMappedPersonBase + { + public string FirstName { get; set; } + public string LastName { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/Whiteboard.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/Whiteboard.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/Whiteboard.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/Whiteboard.cs index 173ce7cf..e608e1aa 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/Whiteboard.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/Whiteboard.cs @@ -1,11 +1,11 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - public class Whiteboard - { - public byte[] iD { get; set; } - public string AssetTag { get; set; } - public Office Office { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + public class Whiteboard + { + public byte[] iD { get; set; } + public string AssetTag { get; set; } + public Office Office { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/WorkOrder.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/WorkOrder.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/WorkOrder.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/WorkOrder.cs index 5571bc4f..09a8fce1 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AdvancedPatternsModel/WorkOrder.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AdvancedPatternsModel/WorkOrder.cs @@ -1,12 +1,12 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AdvancedPatternsModel -{ - public class WorkOrder - { - public int WorkOrderId { get; set; } - public int EmployeeId { get; set; } - public Employee Employee { get; set; } - public string Details { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AdvancedPatternsModel +{ + public class WorkOrder + { + public int WorkOrderId { get; set; } + public int EmployeeId { get; set; } + public Employee Employee { get; set; } + public string Details { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/AllTypeKeysContext.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/AllTypeKeysContext.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/AllTypeKeysContext.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/AllTypeKeysContext.cs index 3d83aa07..bc1ed521 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/AllTypeKeysContext.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/AllTypeKeysContext.cs @@ -1,69 +1,69 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AllTypeKeysModel -{ - using System.ComponentModel.DataAnnotations.Schema; - using System.Data.Entity; - using System.Data.Entity.Infrastructure; - - public class AllTypeKeysContext : DbContext - { - static AllTypeKeysContext() - { - Database.SetInitializer(new AllTypeKeysModelInitializer()); - } - - public AllTypeKeysContext() - { - } - - public AllTypeKeysContext(DbCompiledModel model) - : base(model) - { - } - - // CompositeKeyEntity has ordering of keys specified via configuration - public DbSet CompositeKeyEntities { get; set; } - - // CompositeKeyEntityWithOrderingAnnotations has ordering of keys specified via annotations - public DbSet CompositeKeyEntitiesWithOrderingAnnotations { get; set; } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - CreateModel(modelBuilder); - } - - private static void CreateModel(DbModelBuilder modelBuilder) - { - modelBuilder.Entity().HasKey( - k => new - { - k.binaryKey, - k.intKey, - k.stringKey - }); - modelBuilder.Entity(); - - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity(); - modelBuilder.Entity().Property(s => s.key).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); - modelBuilder.Entity().Property(s => s.key).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); - modelBuilder.Entity(); - } - - public static DbModelBuilder CreateBuilder() - { - var builder = new DbModelBuilder(); - - CreateModel(builder); - - return builder; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AllTypeKeysModel +{ + using System.ComponentModel.DataAnnotations.Schema; + using System.Data.Entity; + using System.Data.Entity.Infrastructure; + + public class AllTypeKeysContext : DbContext + { + static AllTypeKeysContext() + { + Database.SetInitializer(new AllTypeKeysModelInitializer()); + } + + public AllTypeKeysContext() + { + } + + public AllTypeKeysContext(DbCompiledModel model) + : base(model) + { + } + + // CompositeKeyEntity has ordering of keys specified via configuration + public DbSet CompositeKeyEntities { get; set; } + + // CompositeKeyEntityWithOrderingAnnotations has ordering of keys specified via annotations + public DbSet CompositeKeyEntitiesWithOrderingAnnotations { get; set; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + CreateModel(modelBuilder); + } + + private static void CreateModel(DbModelBuilder modelBuilder) + { + modelBuilder.Entity().HasKey( + k => new + { + k.binaryKey, + k.intKey, + k.stringKey + }); + modelBuilder.Entity(); + + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity(); + modelBuilder.Entity().Property(s => s.key).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); + modelBuilder.Entity().Property(s => s.key).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); + modelBuilder.Entity(); + } + + public static DbModelBuilder CreateBuilder() + { + var builder = new DbModelBuilder(); + + CreateModel(builder); + + return builder; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/AllTypeKeysModelInitializer.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/AllTypeKeysModelInitializer.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/AllTypeKeysModelInitializer.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/AllTypeKeysModelInitializer.cs index b68f2b0a..17eea8f4 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/AllTypeKeysModelInitializer.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/AllTypeKeysModelInitializer.cs @@ -1,128 +1,128 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AllTypeKeysModel -{ - using System; - using System.Collections.Generic; - using System.Data.Entity; - - public class AllTypeKeysModelInitializer : DropCreateDatabaseIfModelChanges - { - protected override void Seed(AllTypeKeysContext context) - { - new List - { - new CompositeKeyEntity - { - binaryKey = new byte[] { 1, 2, 3, 4, 5, 6 }, - intKey = 6, - stringKey = "TheOneWithBinaryKeyLength6", - Details = "Some Random Stuff" - }, - new CompositeKeyEntity - { - binaryKey = new byte[] { 201, 202, 203, 204 }, - intKey = 4, - stringKey = "TheOneWithBinaryKeyLength4", - Details = "Does it Matter?" - }, - new CompositeKeyEntity - { - binaryKey = new byte[] { 101, 102, 103, 104, 105 }, - intKey = 5, - stringKey = "TheOneWithBinaryKeyLength5", - Details = "Maybe Details are important!" - }, - }.ForEach(c => context.CompositeKeyEntities.Add(c)); - - new List - { - new CompositeKeyEntityWithOrderingAnnotations - { - intKey = 1, - stringKey = "TheOneWithBinaryKeyLength1", - binaryKey = new byte[] { 220 } - }, - new CompositeKeyEntityWithOrderingAnnotations - { - intKey = 2, - stringKey = "TheOneWithBinaryKeyLength2", - binaryKey = new byte[] { 220, 221 } - }, - new CompositeKeyEntityWithOrderingAnnotations - { - intKey = 3, - stringKey = "TheOneWithBinaryKeyLength3", - binaryKey = new byte[] { 230, 231, 232 } - }, - }.ForEach(c => context.CompositeKeyEntitiesWithOrderingAnnotations.Add(c)); - - context.Set().Add( - new BoolKeyEntity - { - key = true, - Description = "BoolKeyEntity" - }); - context.Set().Add( - new ByteKeyEntity - { - key = 255, - Description = "ByteKeyEntity" - }); - context.Set().Add( - new DateTimeKeyEntity - { - key = new DateTime(2008, 5, 1, 8, 30, 52), - Description = "DateTimeKeyEntity" - }); - context.Set().Add( - new DateTimeOffSetKeyEntity - { - key = new DateTimeOffset(new DateTime(2008, 5, 1, 8, 30, 52)), - Description = "DateTimeOffSetKeyEntity" - }); - context.Set().Add( - new DecimalKeyEntity - { - key = 300.5m, - Description = "DecimalKeyEntity" - }); - context.Set().Add( - new DoubleKeyEntity - { - key = 1.7E+3D, - Description = "DoubleKeyEntity" - }); - context.Set().Add( - new FloatKeyEntity - { - key = 33.2F, - Description = "FloatKeyEntity" - }); - context.Set().Add( - new GuidKeyEntity - { - key = Guid.Parse("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4"), - Description = "GuidKeyEntity" - }); - context.Set().Add( - new LongKeyEntity - { - key = 4294967296L, - Description = "LongKeyEntity" - }); - context.Set().Add( - new ShortKeyEntity - { - key = 32767, - Description = "ShortKeyEntity" - }); - context.Set().Add( - new TimeSpanKeyEntity - { - key = new TimeSpan(2, 14, 18), - Description = "TimeSpanKeyEntity" - }); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AllTypeKeysModel +{ + using System; + using System.Collections.Generic; + using System.Data.Entity; + + public class AllTypeKeysModelInitializer : DropCreateDatabaseIfModelChanges + { + protected override void Seed(AllTypeKeysContext context) + { + new List + { + new CompositeKeyEntity + { + binaryKey = new byte[] { 1, 2, 3, 4, 5, 6 }, + intKey = 6, + stringKey = "TheOneWithBinaryKeyLength6", + Details = "Some Random Stuff" + }, + new CompositeKeyEntity + { + binaryKey = new byte[] { 201, 202, 203, 204 }, + intKey = 4, + stringKey = "TheOneWithBinaryKeyLength4", + Details = "Does it Matter?" + }, + new CompositeKeyEntity + { + binaryKey = new byte[] { 101, 102, 103, 104, 105 }, + intKey = 5, + stringKey = "TheOneWithBinaryKeyLength5", + Details = "Maybe Details are important!" + }, + }.ForEach(c => context.CompositeKeyEntities.Add(c)); + + new List + { + new CompositeKeyEntityWithOrderingAnnotations + { + intKey = 1, + stringKey = "TheOneWithBinaryKeyLength1", + binaryKey = new byte[] { 220 } + }, + new CompositeKeyEntityWithOrderingAnnotations + { + intKey = 2, + stringKey = "TheOneWithBinaryKeyLength2", + binaryKey = new byte[] { 220, 221 } + }, + new CompositeKeyEntityWithOrderingAnnotations + { + intKey = 3, + stringKey = "TheOneWithBinaryKeyLength3", + binaryKey = new byte[] { 230, 231, 232 } + }, + }.ForEach(c => context.CompositeKeyEntitiesWithOrderingAnnotations.Add(c)); + + context.Set().Add( + new BoolKeyEntity + { + key = true, + Description = "BoolKeyEntity" + }); + context.Set().Add( + new ByteKeyEntity + { + key = 255, + Description = "ByteKeyEntity" + }); + context.Set().Add( + new DateTimeKeyEntity + { + key = new DateTime(2008, 5, 1, 8, 30, 52), + Description = "DateTimeKeyEntity" + }); + context.Set().Add( + new DateTimeOffSetKeyEntity + { + key = new DateTimeOffset(new DateTime(2008, 5, 1, 8, 30, 52)), + Description = "DateTimeOffSetKeyEntity" + }); + context.Set().Add( + new DecimalKeyEntity + { + key = 300.5m, + Description = "DecimalKeyEntity" + }); + context.Set().Add( + new DoubleKeyEntity + { + key = 1.7E+3D, + Description = "DoubleKeyEntity" + }); + context.Set().Add( + new FloatKeyEntity + { + key = 33.2F, + Description = "FloatKeyEntity" + }); + context.Set().Add( + new GuidKeyEntity + { + key = Guid.Parse("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4"), + Description = "GuidKeyEntity" + }); + context.Set().Add( + new LongKeyEntity + { + key = 4294967296L, + Description = "LongKeyEntity" + }); + context.Set().Add( + new ShortKeyEntity + { + key = 32767, + Description = "ShortKeyEntity" + }); + context.Set().Add( + new TimeSpanKeyEntity + { + key = new TimeSpan(2, 14, 18), + Description = "TimeSpanKeyEntity" + }); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/BoolKeyEntity.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/BoolKeyEntity.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/BoolKeyEntity.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/BoolKeyEntity.cs index 68c07ed9..ebfb2532 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/BoolKeyEntity.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/BoolKeyEntity.cs @@ -1,14 +1,14 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AllTypeKeysModel -{ - using System.ComponentModel.DataAnnotations; - - public class BoolKeyEntity - { - [Key] - public bool key { get; set; } - - public string Description { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AllTypeKeysModel +{ + using System.ComponentModel.DataAnnotations; + + public class BoolKeyEntity + { + [Key] + public bool key { get; set; } + + public string Description { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/ByteKeyEntity.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/ByteKeyEntity.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/ByteKeyEntity.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/ByteKeyEntity.cs index dbc13848..4551df98 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/ByteKeyEntity.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/ByteKeyEntity.cs @@ -1,14 +1,14 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AllTypeKeysModel -{ - using System.ComponentModel.DataAnnotations; - - public class ByteKeyEntity - { - [Key] - public byte key { get; set; } - - public string Description { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AllTypeKeysModel +{ + using System.ComponentModel.DataAnnotations; + + public class ByteKeyEntity + { + [Key] + public byte key { get; set; } + + public string Description { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/CompositeKeyEntity.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/CompositeKeyEntity.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/CompositeKeyEntity.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/CompositeKeyEntity.cs index 7a082a34..54fa7e3d 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/CompositeKeyEntity.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/CompositeKeyEntity.cs @@ -1,20 +1,20 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AllTypeKeysModel -{ - using System.ComponentModel.DataAnnotations; - - public class CompositeKeyEntity - { - [Key] - public int intKey { get; set; } - - [Key] - public string stringKey { get; set; } - - [Key] - public byte[] binaryKey { get; set; } - - public string Details { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AllTypeKeysModel +{ + using System.ComponentModel.DataAnnotations; + + public class CompositeKeyEntity + { + [Key] + public int intKey { get; set; } + + [Key] + public string stringKey { get; set; } + + [Key] + public byte[] binaryKey { get; set; } + + public string Details { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/CompositeKeyEntityWithOrderingAnnotations.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/CompositeKeyEntityWithOrderingAnnotations.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/CompositeKeyEntityWithOrderingAnnotations.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/CompositeKeyEntityWithOrderingAnnotations.cs index b969c04d..7b856f86 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/CompositeKeyEntityWithOrderingAnnotations.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/CompositeKeyEntityWithOrderingAnnotations.cs @@ -1,22 +1,22 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AllTypeKeysModel -{ - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; - - public class CompositeKeyEntityWithOrderingAnnotations - { - [Key] - [Column(Order = 1)] - public int intKey { get; set; } - - [Key] - [Column(Order = 2)] - public string stringKey { get; set; } - - [Key] - [Column(Order = 3)] - public byte[] binaryKey { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AllTypeKeysModel +{ + using System.ComponentModel.DataAnnotations; + using System.ComponentModel.DataAnnotations.Schema; + + public class CompositeKeyEntityWithOrderingAnnotations + { + [Key] + [Column(Order = 1)] + public int intKey { get; set; } + + [Key] + [Column(Order = 2)] + public string stringKey { get; set; } + + [Key] + [Column(Order = 3)] + public byte[] binaryKey { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/DateTimeKeyEntity.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/DateTimeKeyEntity.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/DateTimeKeyEntity.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/DateTimeKeyEntity.cs index 068f77b5..16104e8b 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/DateTimeKeyEntity.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/DateTimeKeyEntity.cs @@ -1,15 +1,15 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AllTypeKeysModel -{ - using System; - using System.ComponentModel.DataAnnotations; - - public class DateTimeKeyEntity - { - [Key] - public DateTime key { get; set; } - - public string Description { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AllTypeKeysModel +{ + using System; + using System.ComponentModel.DataAnnotations; + + public class DateTimeKeyEntity + { + [Key] + public DateTime key { get; set; } + + public string Description { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/DateTimeOffsetKeyEntity.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/DateTimeOffsetKeyEntity.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/DateTimeOffsetKeyEntity.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/DateTimeOffsetKeyEntity.cs index b9744f6c..02327770 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/DateTimeOffsetKeyEntity.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/DateTimeOffsetKeyEntity.cs @@ -1,15 +1,15 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AllTypeKeysModel -{ - using System; - using System.ComponentModel.DataAnnotations; - - public class DateTimeOffSetKeyEntity - { - [Key] - public DateTimeOffset key { get; set; } - - public string Description { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AllTypeKeysModel +{ + using System; + using System.ComponentModel.DataAnnotations; + + public class DateTimeOffSetKeyEntity + { + [Key] + public DateTimeOffset key { get; set; } + + public string Description { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/DecimalKeyEntity.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/DecimalKeyEntity.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/DecimalKeyEntity.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/DecimalKeyEntity.cs index 6d419dae..37b86a0c 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/DecimalKeyEntity.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/DecimalKeyEntity.cs @@ -1,14 +1,14 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AllTypeKeysModel -{ - using System.ComponentModel.DataAnnotations; - - public class DecimalKeyEntity - { - [Key] - public decimal key { get; set; } - - public string Description { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AllTypeKeysModel +{ + using System.ComponentModel.DataAnnotations; + + public class DecimalKeyEntity + { + [Key] + public decimal key { get; set; } + + public string Description { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/DoubleKeyEntity.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/DoubleKeyEntity.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/DoubleKeyEntity.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/DoubleKeyEntity.cs index e9e862b5..50843b6b 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/DoubleKeyEntity.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/DoubleKeyEntity.cs @@ -1,14 +1,14 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AllTypeKeysModel -{ - using System.ComponentModel.DataAnnotations; - - public class DoubleKeyEntity - { - [Key] - public double key { get; set; } - - public string Description { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AllTypeKeysModel +{ + using System.ComponentModel.DataAnnotations; + + public class DoubleKeyEntity + { + [Key] + public double key { get; set; } + + public string Description { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/FloatKeyEntity.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/FloatKeyEntity.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/FloatKeyEntity.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/FloatKeyEntity.cs index 84e75954..98e07dbb 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/FloatKeyEntity.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/FloatKeyEntity.cs @@ -1,14 +1,14 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AllTypeKeysModel -{ - using System.ComponentModel.DataAnnotations; - - public class FloatKeyEntity - { - [Key] - public float key { get; set; } - - public string Description { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AllTypeKeysModel +{ + using System.ComponentModel.DataAnnotations; + + public class FloatKeyEntity + { + [Key] + public float key { get; set; } + + public string Description { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/GuidKeyEntity.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/GuidKeyEntity.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/GuidKeyEntity.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/GuidKeyEntity.cs index 45aa7106..7fe94970 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/GuidKeyEntity.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/GuidKeyEntity.cs @@ -1,15 +1,15 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AllTypeKeysModel -{ - using System; - using System.ComponentModel.DataAnnotations; - - public class GuidKeyEntity - { - [Key] - public Guid key { get; set; } - - public string Description { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AllTypeKeysModel +{ + using System; + using System.ComponentModel.DataAnnotations; + + public class GuidKeyEntity + { + [Key] + public Guid key { get; set; } + + public string Description { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/LongKeyEntity.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/LongKeyEntity.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/LongKeyEntity.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/LongKeyEntity.cs index a9512b81..ce713e51 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/LongKeyEntity.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/LongKeyEntity.cs @@ -1,16 +1,16 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AllTypeKeysModel -{ - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; - - public class LongKeyEntity - { - [Key] - [DatabaseGenerated(DatabaseGeneratedOption.None)] - public long key { get; set; } - - public string Description { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AllTypeKeysModel +{ + using System.ComponentModel.DataAnnotations; + using System.ComponentModel.DataAnnotations.Schema; + + public class LongKeyEntity + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public long key { get; set; } + + public string Description { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/ShortKeyEntity.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/ShortKeyEntity.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/ShortKeyEntity.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/ShortKeyEntity.cs index acf26e58..fc632e6e 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/ShortKeyEntity.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/ShortKeyEntity.cs @@ -1,14 +1,14 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AllTypeKeysModel -{ - using System.ComponentModel.DataAnnotations; - - public class ShortKeyEntity - { - [Key] - public short key { get; set; } - - public string Description { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AllTypeKeysModel +{ + using System.ComponentModel.DataAnnotations; + + public class ShortKeyEntity + { + [Key] + public short key { get; set; } + + public string Description { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/TimeSpanKeyEntity.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/TimeSpanKeyEntity.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/TimeSpanKeyEntity.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/TimeSpanKeyEntity.cs index 681d751b..a01695a2 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/AllTypeKeysModel/TimeSpanKeyEntity.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/AllTypeKeysModel/TimeSpanKeyEntity.cs @@ -1,15 +1,15 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace AllTypeKeysModel -{ - using System; - using System.ComponentModel.DataAnnotations; - - public class TimeSpanKeyEntity - { - [Key] - public TimeSpan key { get; set; } - - public string Description { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace AllTypeKeysModel +{ + using System; + using System.ComponentModel.DataAnnotations; + + public class TimeSpanKeyEntity + { + [Key] + public TimeSpan key { get; set; } + + public string Description { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaAllTypes.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaAllTypes.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaAllTypes.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaAllTypes.cs diff --git a/test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaBaseline.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaBaseline.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaBaseline.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaBaseline.cs diff --git a/test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaBug.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaBug.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaBug.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaBug.cs diff --git a/test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaConfig.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaConfig.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaConfig.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaConfig.cs diff --git a/test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaContext.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaContext.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaContext.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaContext.cs diff --git a/test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaFailure.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaFailure.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaFailure.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaFailure.cs diff --git a/test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaInitializer.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaInitializer.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaInitializer.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaInitializer.cs diff --git a/test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaMachineConfig.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaMachineConfig.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaMachineConfig.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaMachineConfig.cs diff --git a/test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaOwner.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaOwner.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaOwner.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaOwner.cs diff --git a/test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaRun.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaRun.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaRun.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaRun.cs diff --git a/test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaTask.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaTask.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaTask.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaTask.cs diff --git a/test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaTaskInfo.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaTaskInfo.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaTaskInfo.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaTaskInfo.cs diff --git a/test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaTestFailure.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaTestFailure.cs similarity index 100% rename from test/EntityFramework/FunctionalTests/TestModels/ArubaModel/ArubaTestFailure.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ArubaModel/ArubaTestFailure.cs diff --git a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Chassis.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Chassis.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Chassis.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Chassis.cs index 7763c200..c7863192 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Chassis.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Chassis.cs @@ -1,21 +1,21 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace ConcurrencyModel -{ - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; - - public class Chassis - { - [Timestamp] - public byte[] Version { get; set; } - - [Key] - [DatabaseGenerated(DatabaseGeneratedOption.None)] - public int TeamId { get; set; } - - public string Name { get; set; } - - public virtual Team Team { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace ConcurrencyModel +{ + using System.ComponentModel.DataAnnotations; + using System.ComponentModel.DataAnnotations.Schema; + + public class Chassis + { + [Timestamp] + public byte[] Version { get; set; } + + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public int TeamId { get; set; } + + public string Name { get; set; } + + public virtual Team Team { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/ConcurrencyModelInitializer.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/ConcurrencyModelInitializer.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/ConcurrencyModelInitializer.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/ConcurrencyModelInitializer.cs index d1445dd7..c84dc155 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/ConcurrencyModelInitializer.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/ConcurrencyModelInitializer.cs @@ -1,874 +1,874 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace ConcurrencyModel -{ - using System.Collections.Generic; - using System.Data.Entity; - using System.Linq; - - public class ConcurrencyModelInitializer : DropCreateDatabaseIfModelChanges - { - protected override void Seed(F1Context context) - { - new List - { - new EngineSupplier - { - Name = "Mercedes" - }, - new EngineSupplier - { - Name = "Renault" - }, - new EngineSupplier - { - Name = "Ferrari" - }, - new EngineSupplier - { - Name = "Cosworth" - }, - }.ForEach(s => context.EngineSuppliers.Add(s)); - - var engineSuppliers = context.EngineSuppliers.Local; - var mercedesEngine = new Engine - { - Name = "FO 108X", - StorageLocation = new Location - { - Latitude = 47.64491, - Longitude = -122.128101 - }, - EngineSupplier = engineSuppliers.Single(s => s.Name == "Mercedes") - }; - var renaultEngine = new Engine - { - Name = "RS27-2010", - StorageLocation = new Location - { - Latitude = 47.644199, - Longitude = -122.127049 - }, - EngineSupplier = engineSuppliers.Single(s => s.Name == "Renault") - }; - var ferrariEngine = new Engine - { - Name = "056", - StorageLocation = new Location - { - Latitude = 47.64256, - Longitude = -122.130609 - }, - EngineSupplier = engineSuppliers.Single(s => s.Name == "Ferrari") - }; - var cosworthEngine = new Engine - { - Name = "CA2010", - StorageLocation = new Location - { - Latitude = 47.644851, - Longitude = -122.129781 - }, - EngineSupplier = engineSuppliers.Single(s => s.Name == "Cosworth") - }; - - new List - { - mercedesEngine, - renaultEngine, - ferrariEngine, - cosworthEngine - }.ForEach(e => context.Engines.Add(e)); - - new List - { - new Team - { - Id = Team.McLaren, - Name = "Vodafone McLaren Mercedes", - Constructor = "McLaren", - Chassis = new Chassis - { - Name = "MP4-25" - }, - Engine = mercedesEngine, - Tire = "Bridgestone", - Principal = "Martin Whitmarsh", - ConstructorsChampionships = 8, - DriversChampionships = 12, - Races = 678, - Victories = 168, - Poles = 146, - FastestLaps = 140 - }, - new Team - { - Id = Team.Mercedes, - Name = "Mercedes GP Petronas F1 Team", - Constructor = "Mercedes", - Chassis = new Chassis - { - Name = "MGP W01" - }, - Engine = mercedesEngine, - Tire = "Bridgestone", - Principal = "Ross Brawn", - ConstructorsChampionships = 0, - DriversChampionships = 2, - Races = 24, - Victories = 9, - Poles = 8, - FastestLaps = 9 - }, - new Team - { - Id = Team.RedBull, - Name = "Red Bull Racing", - Constructor = "Red Bull", - Chassis = new Chassis - { - Name = "RB6" - }, - Engine = renaultEngine, - Tire = "Bridgestone", - Principal = "Christian Horner", - ConstructorsChampionships = 0, - DriversChampionships = 0, - Races = 101, - Victories = 12, - Poles = 16, - FastestLaps = 11 - }, - new Team - { - Id = Team.Ferrari, - Name = "Scuderia Ferrari Marlboro", - Constructor = "Ferrari", - Chassis = new Chassis - { - Name = "F10" - }, - Engine = ferrariEngine, - Tire = "Bridgestone", - Principal = "Stefano Domenicali", - ConstructorsChampionships = 16, - DriversChampionships = 15, - Races = 805, - Victories = 212, - Poles = 203, - FastestLaps = 221 - }, - new Team - { - Id = Team.Williams, - Name = "AT&T Williams", - Constructor = "Williams", - Chassis = new Chassis - { - Name = "FW32" - }, - Engine = cosworthEngine, - Tire = "Bridgestone", - Principal = "Frank Williams/Patrick Head", - ConstructorsChampionships = 9, - DriversChampionships = 7, - Races = 532, - Victories = 113, - Poles = 125, - FastestLaps = 130 - }, - new Team - { - Id = Team.Renault, - Name = "Renault F1 Team", - Constructor = "Renault", - Chassis = new Chassis - { - Name = "R30" - }, - Engine = renaultEngine, - Tire = "Bridgestone", - Principal = "Eric Boullier", - ConstructorsChampionships = 2, - DriversChampionships = 2, - Races = 278, - Victories = 35, - Poles = 51, - FastestLaps = 31 - }, - new Team - { - Id = Team.ForceIndia, - Name = "Force India F1 Team", - Constructor = "Force India", - Chassis = new Chassis - { - Name = "VJM03" - }, - Engine = mercedesEngine, - Tire = "Bridgestone", - Principal = "Vijay Mallya", - ConstructorsChampionships = 0, - DriversChampionships = 0, - Races = 47, - Victories = 0, - Poles = 1, - FastestLaps = 1 - }, - new Team - { - Id = Team.ToroRosso, - Name = "Scuderia Toro Rosso", - Constructor = "Toro Rosso", - Chassis = new Chassis - { - Name = "STR5" - }, - Engine = ferrariEngine, - Tire = "Bridgestone", - Principal = "Franz Tost", - ConstructorsChampionships = 0, - DriversChampionships = 0, - Races = 82, - Victories = 1, - Poles = 1, - FastestLaps = 0 - }, - new Team - { - Id = Team.Lotus, - Name = "Lotus Racing", - Constructor = "Lotus", - Chassis = new Chassis - { - Name = "T127" - }, - Engine = cosworthEngine, - Tire = "Bridgestone", - Principal = "Tony Fernandes", - ConstructorsChampionships = 7, - DriversChampionships = 6, - Races = 503, - Victories = 73, - Poles = 102, - FastestLaps = 65 - }, - new Team - { - Id = Team.Hispania, - Name = "Hispania Racing F1 Team (HRT)", - Constructor = "HRT", - Chassis = new Chassis - { - Name = "F110" - }, - Engine = cosworthEngine, - Tire = "Bridgestone", - Principal = "Colin Kolles", - ConstructorsChampionships = 0, - DriversChampionships = 0, - Races = 12, - Victories = 0, - Poles = 0, - FastestLaps = 0 - }, - new Team - { - Id = Team.Sauber, - Name = "BMW Sauber F1 Team", - Constructor = "Sauber", - Chassis = new Chassis - { - Name = "C29" - }, - Engine = ferrariEngine, - Tire = "Bridgestone", - Principal = "Peter Sauber", - ConstructorsChampionships = 0, - DriversChampionships = 0, - Races = 288, - Victories = 1, - Poles = 1, - FastestLaps = 2 - }, - new Team - { - Id = Team.Virgin, - Name = "Virgin Racing", - Constructor = "Virgin", - Chassis = new Chassis - { - Name = "VR-01" - }, - Engine = cosworthEngine, - Tire = "Bridgestone", - Principal = "John Booth", - ConstructorsChampionships = 0, - DriversChampionships = 0, - Races = 12, - Victories = 0, - Poles = 0, - FastestLaps = 0 - }, - }.ForEach(t => context.Teams.Add(t)); - - new List - { - new Driver - { - Name = "Jenson Button", - TeamId = Team.McLaren, - CarNumber = 1, - Championships = 1, - Races = 184, - Wins = 9, - Podiums = 29, - Poles = 7, - FastestLaps = 3 - }, - new Driver - { - Name = "Lewis Hamilton", - TeamId = Team.McLaren, - CarNumber = 2, - Championships = 1, - Races = 64, - Wins = 13, - Podiums = 33, - Poles = 18, - FastestLaps = 5 - }, - new TestDriver - { - Name = "Gary Paffett", - TeamId = Team.McLaren, - CarNumber = null, - Championships = 0, - Races = 0, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new Driver - { - Name = "Michael Schumacher", - TeamId = Team.Mercedes, - CarNumber = 3, - Championships = 7, - Races = 262, - Wins = 91, - Podiums = 154, - Poles = 68, - FastestLaps = 76 - }, - new Driver - { - Name = "Nico Rosberg", - TeamId = Team.Mercedes, - CarNumber = 4, - Championships = 0, - Races = 82, - Wins = 0, - Podiums = 5, - Poles = 0, - FastestLaps = 2 - }, - new TestDriver - { - Name = "Nick Heidfeld", - TeamId = Team.Mercedes, - CarNumber = null, - Championships = 0, - Races = 169, - Wins = 0, - Podiums = 12, - Poles = 1, - FastestLaps = 2 - }, - new Driver - { - Name = "Sebastian Vettel", - TeamId = Team.RedBull, - CarNumber = 5, - Championships = 0, - Races = 55, - Wins = 7, - Podiums = 15, - Poles = 12, - FastestLaps = 6 - }, - new Driver - { - Name = "Mark Webber", - TeamId = Team.RedBull, - CarNumber = 6, - Championships = 0, - Races = 152, - Wins = 6, - Podiums = 16, - Poles = 5, - FastestLaps = 5 - }, - new TestDriver - { - Name = "Brendon Hartley", - TeamId = Team.RedBull, - CarNumber = null, - Championships = 0, - Races = 0, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new TestDriver - { - Name = "Daniel Ricciardo", - TeamId = Team.RedBull, - CarNumber = null, - Championships = 0, - Races = 0, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new TestDriver - { - Name = "David Coulthard", - TeamId = Team.RedBull, - CarNumber = null, - Championships = 0, - Races = 247, - Wins = 13, - Podiums = 62, - Poles = 12, - FastestLaps = 18 - }, - new Driver - { - Name = "Felipe Massa", - TeamId = Team.Ferrari, - CarNumber = 7, - Championships = 0, - Races = 128, - Wins = 11, - Podiums = 31, - Poles = 15, - FastestLaps = 12 - }, - new Driver - { - Name = "Fernando Alonso", - TeamId = Team.Ferrari, - CarNumber = 8, - Championships = 2, - Races = 152, - Wins = 23, - Podiums = 58, - Poles = 18, - FastestLaps = 15 - }, - new TestDriver - { - Name = "Giancarlo Fisichella", - TeamId = Team.Ferrari, - CarNumber = null, - Championships = 0, - Races = 231, - Wins = 3, - Podiums = 19, - Poles = 4, - FastestLaps = 2 - }, - new TestDriver - { - Name = "Luca Badoer", - TeamId = Team.Ferrari, - CarNumber = null, - Championships = 0, - Races = 58, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new TestDriver - { - Name = "Marc Gené", - TeamId = Team.Ferrari, - CarNumber = null, - Championships = 0, - Races = 36, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new Driver - { - Name = "Rubens Barrichello", - TeamId = Team.Williams, - CarNumber = 9, - Championships = 0, - Races = 300, - Wins = 11, - Podiums = 68, - Poles = 14, - FastestLaps = 17 - }, - new Driver - { - Name = "Nico Hülkenberg", - TeamId = Team.Williams, - CarNumber = 10, - Championships = 0, - Races = 12, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new TestDriver - { - Name = "Valtteri Bottas", - TeamId = Team.Williams, - CarNumber = null, - Championships = 0, - Races = 0, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new Driver - { - Name = "Robert Kubica", - TeamId = Team.Renault, - CarNumber = 11, - Championships = 0, - Races = 69, - Wins = 1, - Podiums = 11, - Poles = 1, - FastestLaps = 1 - }, - new Driver - { - Name = "Vitaly Petrov", - TeamId = Team.Renault, - CarNumber = 12, - Championships = 0, - Races = 12, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 1 - }, - new TestDriver - { - Name = "Ho-Pin Tung", - TeamId = Team.Renault, - CarNumber = null, - Championships = 0, - Races = 0, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new TestDriver - { - Name = "Jérôme d'Ambrosio", - TeamId = Team.Renault, - CarNumber = null, - Championships = 0, - Races = 0, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new TestDriver - { - Name = "Jan Charouz", - TeamId = Team.Renault, - CarNumber = null, - Championships = 0, - Races = 0, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new Driver - { - Name = "Adrian Sutil", - TeamId = Team.ForceIndia, - CarNumber = 14, - Championships = 0, - Races = 64, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 1 - }, - new Driver - { - Name = "Vitantonio Liuzzi", - TeamId = Team.ForceIndia, - CarNumber = 15, - Championships = 0, - Races = 56, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new TestDriver - { - Name = "Paul di Resta", - TeamId = Team.ForceIndia, - CarNumber = null, - Championships = 0, - Races = 0, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new Driver - { - Name = "Sébastien Buemi", - TeamId = Team.ToroRosso, - CarNumber = 16, - Championships = 0, - Races = 29, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new Driver - { - Name = "Jaime Alguersuari", - TeamId = Team.ToroRosso, - CarNumber = 17, - Championships = 0, - Races = 20, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new TestDriver - { - Name = "Brendon Hartley", - TeamId = Team.ToroRosso, - CarNumber = null, - Championships = 0, - Races = 0, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new TestDriver - { - Name = "Daniel Ricciardo", - TeamId = Team.ToroRosso, - CarNumber = null, - Championships = 0, - Races = 0, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new Driver - { - Name = "Jarno Trulli", - TeamId = Team.Lotus, - CarNumber = 18, - Championships = 0, - Races = 231, - Wins = 1, - Podiums = 11, - Poles = 4, - FastestLaps = 1 - }, - new Driver - { - Name = "Heikki Kovalainen", - TeamId = Team.Lotus, - CarNumber = 19, - Championships = 0, - Races = 64, - Wins = 1, - Podiums = 4, - Poles = 1, - FastestLaps = 2 - }, - new TestDriver - { - Name = "Fairuz Fauzy", - TeamId = Team.Lotus, - CarNumber = null, - Championships = 0, - Races = 0, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new Driver - { - Name = "Karun Chandhok", - TeamId = Team.Hispania, - CarNumber = 20, - Championships = 0, - Races = 10, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new Driver - { - Name = "Bruno Senna", - TeamId = Team.Hispania, - CarNumber = 21, - Championships = 0, - Races = 11, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new TestDriver - { - Name = "Christian Klien", - TeamId = Team.Hispania, - CarNumber = null, - Championships = 0, - Races = 48, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new TestDriver - { - Name = "Sakon Yamamoto", - TeamId = Team.Hispania, - CarNumber = null, - Championships = 0, - Races = 17, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new Driver - { - Name = "Timo Glock", - TeamId = Team.Virgin, - CarNumber = 24, - Championships = 0, - Races = 48, - Wins = 0, - Podiums = 3, - Poles = 0, - FastestLaps = 1 - }, - new Driver - { - Name = "Lucas di Grassi", - TeamId = Team.Virgin, - CarNumber = 25, - Championships = 0, - Races = 12, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new TestDriver - { - Name = "Andy Soucek", - TeamId = Team.Virgin, - CarNumber = null, - Championships = 0, - Races = 0, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - new TestDriver - { - Name = "Luiz Razia", - TeamId = Team.Virgin, - CarNumber = null, - Championships = 0, - Races = 0, - Wins = 0, - Podiums = 0, - Poles = 0, - FastestLaps = 0 - }, - }.ForEach(d => context.Drivers.Add(d)); - - var shell = new Sponsor - { - Id = 1, - Name = "Shell" - }; - var vodafone = new TitleSponsor - { - Id = 2, - Name = "Vodafone", - Details = new SponsorDetails - { - Days = 10, - Space = 50m - } - }; - var bridgestone = new Sponsor - { - Id = 3, - Name = "Bridgestone" - }; - var fia = new Sponsor - { - Id = 4, - Name = "FIA" - }; - - new List - { - shell, - vodafone, - bridgestone, - fia - }.ForEach(s => context.Sponsors.Add(s)); - - // Intentionally using Local in the initializer to test that it works - foreach (var team in context.Teams.Local) - { - team.Chassis.TeamId = team.Id; - - if (team.Id - != Team.Hispania) - { - team.Sponsors.Add(bridgestone); - team.Sponsors.Add(fia); - } - } - - context.Teams.Local.Single(t => t.Id == Team.McLaren).Sponsors.Add(vodafone); - context.Teams.Local.Single(t => t.Id == Team.Ferrari).Sponsors.Add(shell); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace ConcurrencyModel +{ + using System.Collections.Generic; + using System.Data.Entity; + using System.Linq; + + public class ConcurrencyModelInitializer : DropCreateDatabaseIfModelChanges + { + protected override void Seed(F1Context context) + { + new List + { + new EngineSupplier + { + Name = "Mercedes" + }, + new EngineSupplier + { + Name = "Renault" + }, + new EngineSupplier + { + Name = "Ferrari" + }, + new EngineSupplier + { + Name = "Cosworth" + }, + }.ForEach(s => context.EngineSuppliers.Add(s)); + + var engineSuppliers = context.EngineSuppliers.Local; + var mercedesEngine = new Engine + { + Name = "FO 108X", + StorageLocation = new Location + { + Latitude = 47.64491, + Longitude = -122.128101 + }, + EngineSupplier = engineSuppliers.Single(s => s.Name == "Mercedes") + }; + var renaultEngine = new Engine + { + Name = "RS27-2010", + StorageLocation = new Location + { + Latitude = 47.644199, + Longitude = -122.127049 + }, + EngineSupplier = engineSuppliers.Single(s => s.Name == "Renault") + }; + var ferrariEngine = new Engine + { + Name = "056", + StorageLocation = new Location + { + Latitude = 47.64256, + Longitude = -122.130609 + }, + EngineSupplier = engineSuppliers.Single(s => s.Name == "Ferrari") + }; + var cosworthEngine = new Engine + { + Name = "CA2010", + StorageLocation = new Location + { + Latitude = 47.644851, + Longitude = -122.129781 + }, + EngineSupplier = engineSuppliers.Single(s => s.Name == "Cosworth") + }; + + new List + { + mercedesEngine, + renaultEngine, + ferrariEngine, + cosworthEngine + }.ForEach(e => context.Engines.Add(e)); + + new List + { + new Team + { + Id = Team.McLaren, + Name = "Vodafone McLaren Mercedes", + Constructor = "McLaren", + Chassis = new Chassis + { + Name = "MP4-25" + }, + Engine = mercedesEngine, + Tire = "Bridgestone", + Principal = "Martin Whitmarsh", + ConstructorsChampionships = 8, + DriversChampionships = 12, + Races = 678, + Victories = 168, + Poles = 146, + FastestLaps = 140 + }, + new Team + { + Id = Team.Mercedes, + Name = "Mercedes GP Petronas F1 Team", + Constructor = "Mercedes", + Chassis = new Chassis + { + Name = "MGP W01" + }, + Engine = mercedesEngine, + Tire = "Bridgestone", + Principal = "Ross Brawn", + ConstructorsChampionships = 0, + DriversChampionships = 2, + Races = 24, + Victories = 9, + Poles = 8, + FastestLaps = 9 + }, + new Team + { + Id = Team.RedBull, + Name = "Red Bull Racing", + Constructor = "Red Bull", + Chassis = new Chassis + { + Name = "RB6" + }, + Engine = renaultEngine, + Tire = "Bridgestone", + Principal = "Christian Horner", + ConstructorsChampionships = 0, + DriversChampionships = 0, + Races = 101, + Victories = 12, + Poles = 16, + FastestLaps = 11 + }, + new Team + { + Id = Team.Ferrari, + Name = "Scuderia Ferrari Marlboro", + Constructor = "Ferrari", + Chassis = new Chassis + { + Name = "F10" + }, + Engine = ferrariEngine, + Tire = "Bridgestone", + Principal = "Stefano Domenicali", + ConstructorsChampionships = 16, + DriversChampionships = 15, + Races = 805, + Victories = 212, + Poles = 203, + FastestLaps = 221 + }, + new Team + { + Id = Team.Williams, + Name = "AT&T Williams", + Constructor = "Williams", + Chassis = new Chassis + { + Name = "FW32" + }, + Engine = cosworthEngine, + Tire = "Bridgestone", + Principal = "Frank Williams/Patrick Head", + ConstructorsChampionships = 9, + DriversChampionships = 7, + Races = 532, + Victories = 113, + Poles = 125, + FastestLaps = 130 + }, + new Team + { + Id = Team.Renault, + Name = "Renault F1 Team", + Constructor = "Renault", + Chassis = new Chassis + { + Name = "R30" + }, + Engine = renaultEngine, + Tire = "Bridgestone", + Principal = "Eric Boullier", + ConstructorsChampionships = 2, + DriversChampionships = 2, + Races = 278, + Victories = 35, + Poles = 51, + FastestLaps = 31 + }, + new Team + { + Id = Team.ForceIndia, + Name = "Force India F1 Team", + Constructor = "Force India", + Chassis = new Chassis + { + Name = "VJM03" + }, + Engine = mercedesEngine, + Tire = "Bridgestone", + Principal = "Vijay Mallya", + ConstructorsChampionships = 0, + DriversChampionships = 0, + Races = 47, + Victories = 0, + Poles = 1, + FastestLaps = 1 + }, + new Team + { + Id = Team.ToroRosso, + Name = "Scuderia Toro Rosso", + Constructor = "Toro Rosso", + Chassis = new Chassis + { + Name = "STR5" + }, + Engine = ferrariEngine, + Tire = "Bridgestone", + Principal = "Franz Tost", + ConstructorsChampionships = 0, + DriversChampionships = 0, + Races = 82, + Victories = 1, + Poles = 1, + FastestLaps = 0 + }, + new Team + { + Id = Team.Lotus, + Name = "Lotus Racing", + Constructor = "Lotus", + Chassis = new Chassis + { + Name = "T127" + }, + Engine = cosworthEngine, + Tire = "Bridgestone", + Principal = "Tony Fernandes", + ConstructorsChampionships = 7, + DriversChampionships = 6, + Races = 503, + Victories = 73, + Poles = 102, + FastestLaps = 65 + }, + new Team + { + Id = Team.Hispania, + Name = "Hispania Racing F1 Team (HRT)", + Constructor = "HRT", + Chassis = new Chassis + { + Name = "F110" + }, + Engine = cosworthEngine, + Tire = "Bridgestone", + Principal = "Colin Kolles", + ConstructorsChampionships = 0, + DriversChampionships = 0, + Races = 12, + Victories = 0, + Poles = 0, + FastestLaps = 0 + }, + new Team + { + Id = Team.Sauber, + Name = "BMW Sauber F1 Team", + Constructor = "Sauber", + Chassis = new Chassis + { + Name = "C29" + }, + Engine = ferrariEngine, + Tire = "Bridgestone", + Principal = "Peter Sauber", + ConstructorsChampionships = 0, + DriversChampionships = 0, + Races = 288, + Victories = 1, + Poles = 1, + FastestLaps = 2 + }, + new Team + { + Id = Team.Virgin, + Name = "Virgin Racing", + Constructor = "Virgin", + Chassis = new Chassis + { + Name = "VR-01" + }, + Engine = cosworthEngine, + Tire = "Bridgestone", + Principal = "John Booth", + ConstructorsChampionships = 0, + DriversChampionships = 0, + Races = 12, + Victories = 0, + Poles = 0, + FastestLaps = 0 + }, + }.ForEach(t => context.Teams.Add(t)); + + new List + { + new Driver + { + Name = "Jenson Button", + TeamId = Team.McLaren, + CarNumber = 1, + Championships = 1, + Races = 184, + Wins = 9, + Podiums = 29, + Poles = 7, + FastestLaps = 3 + }, + new Driver + { + Name = "Lewis Hamilton", + TeamId = Team.McLaren, + CarNumber = 2, + Championships = 1, + Races = 64, + Wins = 13, + Podiums = 33, + Poles = 18, + FastestLaps = 5 + }, + new TestDriver + { + Name = "Gary Paffett", + TeamId = Team.McLaren, + CarNumber = null, + Championships = 0, + Races = 0, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new Driver + { + Name = "Michael Schumacher", + TeamId = Team.Mercedes, + CarNumber = 3, + Championships = 7, + Races = 262, + Wins = 91, + Podiums = 154, + Poles = 68, + FastestLaps = 76 + }, + new Driver + { + Name = "Nico Rosberg", + TeamId = Team.Mercedes, + CarNumber = 4, + Championships = 0, + Races = 82, + Wins = 0, + Podiums = 5, + Poles = 0, + FastestLaps = 2 + }, + new TestDriver + { + Name = "Nick Heidfeld", + TeamId = Team.Mercedes, + CarNumber = null, + Championships = 0, + Races = 169, + Wins = 0, + Podiums = 12, + Poles = 1, + FastestLaps = 2 + }, + new Driver + { + Name = "Sebastian Vettel", + TeamId = Team.RedBull, + CarNumber = 5, + Championships = 0, + Races = 55, + Wins = 7, + Podiums = 15, + Poles = 12, + FastestLaps = 6 + }, + new Driver + { + Name = "Mark Webber", + TeamId = Team.RedBull, + CarNumber = 6, + Championships = 0, + Races = 152, + Wins = 6, + Podiums = 16, + Poles = 5, + FastestLaps = 5 + }, + new TestDriver + { + Name = "Brendon Hartley", + TeamId = Team.RedBull, + CarNumber = null, + Championships = 0, + Races = 0, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new TestDriver + { + Name = "Daniel Ricciardo", + TeamId = Team.RedBull, + CarNumber = null, + Championships = 0, + Races = 0, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new TestDriver + { + Name = "David Coulthard", + TeamId = Team.RedBull, + CarNumber = null, + Championships = 0, + Races = 247, + Wins = 13, + Podiums = 62, + Poles = 12, + FastestLaps = 18 + }, + new Driver + { + Name = "Felipe Massa", + TeamId = Team.Ferrari, + CarNumber = 7, + Championships = 0, + Races = 128, + Wins = 11, + Podiums = 31, + Poles = 15, + FastestLaps = 12 + }, + new Driver + { + Name = "Fernando Alonso", + TeamId = Team.Ferrari, + CarNumber = 8, + Championships = 2, + Races = 152, + Wins = 23, + Podiums = 58, + Poles = 18, + FastestLaps = 15 + }, + new TestDriver + { + Name = "Giancarlo Fisichella", + TeamId = Team.Ferrari, + CarNumber = null, + Championships = 0, + Races = 231, + Wins = 3, + Podiums = 19, + Poles = 4, + FastestLaps = 2 + }, + new TestDriver + { + Name = "Luca Badoer", + TeamId = Team.Ferrari, + CarNumber = null, + Championships = 0, + Races = 58, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new TestDriver + { + Name = "Marc Gené", + TeamId = Team.Ferrari, + CarNumber = null, + Championships = 0, + Races = 36, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new Driver + { + Name = "Rubens Barrichello", + TeamId = Team.Williams, + CarNumber = 9, + Championships = 0, + Races = 300, + Wins = 11, + Podiums = 68, + Poles = 14, + FastestLaps = 17 + }, + new Driver + { + Name = "Nico Hülkenberg", + TeamId = Team.Williams, + CarNumber = 10, + Championships = 0, + Races = 12, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new TestDriver + { + Name = "Valtteri Bottas", + TeamId = Team.Williams, + CarNumber = null, + Championships = 0, + Races = 0, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new Driver + { + Name = "Robert Kubica", + TeamId = Team.Renault, + CarNumber = 11, + Championships = 0, + Races = 69, + Wins = 1, + Podiums = 11, + Poles = 1, + FastestLaps = 1 + }, + new Driver + { + Name = "Vitaly Petrov", + TeamId = Team.Renault, + CarNumber = 12, + Championships = 0, + Races = 12, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 1 + }, + new TestDriver + { + Name = "Ho-Pin Tung", + TeamId = Team.Renault, + CarNumber = null, + Championships = 0, + Races = 0, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new TestDriver + { + Name = "Jérôme d'Ambrosio", + TeamId = Team.Renault, + CarNumber = null, + Championships = 0, + Races = 0, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new TestDriver + { + Name = "Jan Charouz", + TeamId = Team.Renault, + CarNumber = null, + Championships = 0, + Races = 0, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new Driver + { + Name = "Adrian Sutil", + TeamId = Team.ForceIndia, + CarNumber = 14, + Championships = 0, + Races = 64, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 1 + }, + new Driver + { + Name = "Vitantonio Liuzzi", + TeamId = Team.ForceIndia, + CarNumber = 15, + Championships = 0, + Races = 56, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new TestDriver + { + Name = "Paul di Resta", + TeamId = Team.ForceIndia, + CarNumber = null, + Championships = 0, + Races = 0, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new Driver + { + Name = "Sébastien Buemi", + TeamId = Team.ToroRosso, + CarNumber = 16, + Championships = 0, + Races = 29, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new Driver + { + Name = "Jaime Alguersuari", + TeamId = Team.ToroRosso, + CarNumber = 17, + Championships = 0, + Races = 20, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new TestDriver + { + Name = "Brendon Hartley", + TeamId = Team.ToroRosso, + CarNumber = null, + Championships = 0, + Races = 0, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new TestDriver + { + Name = "Daniel Ricciardo", + TeamId = Team.ToroRosso, + CarNumber = null, + Championships = 0, + Races = 0, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new Driver + { + Name = "Jarno Trulli", + TeamId = Team.Lotus, + CarNumber = 18, + Championships = 0, + Races = 231, + Wins = 1, + Podiums = 11, + Poles = 4, + FastestLaps = 1 + }, + new Driver + { + Name = "Heikki Kovalainen", + TeamId = Team.Lotus, + CarNumber = 19, + Championships = 0, + Races = 64, + Wins = 1, + Podiums = 4, + Poles = 1, + FastestLaps = 2 + }, + new TestDriver + { + Name = "Fairuz Fauzy", + TeamId = Team.Lotus, + CarNumber = null, + Championships = 0, + Races = 0, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new Driver + { + Name = "Karun Chandhok", + TeamId = Team.Hispania, + CarNumber = 20, + Championships = 0, + Races = 10, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new Driver + { + Name = "Bruno Senna", + TeamId = Team.Hispania, + CarNumber = 21, + Championships = 0, + Races = 11, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new TestDriver + { + Name = "Christian Klien", + TeamId = Team.Hispania, + CarNumber = null, + Championships = 0, + Races = 48, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new TestDriver + { + Name = "Sakon Yamamoto", + TeamId = Team.Hispania, + CarNumber = null, + Championships = 0, + Races = 17, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new Driver + { + Name = "Timo Glock", + TeamId = Team.Virgin, + CarNumber = 24, + Championships = 0, + Races = 48, + Wins = 0, + Podiums = 3, + Poles = 0, + FastestLaps = 1 + }, + new Driver + { + Name = "Lucas di Grassi", + TeamId = Team.Virgin, + CarNumber = 25, + Championships = 0, + Races = 12, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new TestDriver + { + Name = "Andy Soucek", + TeamId = Team.Virgin, + CarNumber = null, + Championships = 0, + Races = 0, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + new TestDriver + { + Name = "Luiz Razia", + TeamId = Team.Virgin, + CarNumber = null, + Championships = 0, + Races = 0, + Wins = 0, + Podiums = 0, + Poles = 0, + FastestLaps = 0 + }, + }.ForEach(d => context.Drivers.Add(d)); + + var shell = new Sponsor + { + Id = 1, + Name = "Shell" + }; + var vodafone = new TitleSponsor + { + Id = 2, + Name = "Vodafone", + Details = new SponsorDetails + { + Days = 10, + Space = 50m + } + }; + var bridgestone = new Sponsor + { + Id = 3, + Name = "Bridgestone" + }; + var fia = new Sponsor + { + Id = 4, + Name = "FIA" + }; + + new List + { + shell, + vodafone, + bridgestone, + fia + }.ForEach(s => context.Sponsors.Add(s)); + + // Intentionally using Local in the initializer to test that it works + foreach (var team in context.Teams.Local) + { + team.Chassis.TeamId = team.Id; + + if (team.Id + != Team.Hispania) + { + team.Sponsors.Add(bridgestone); + team.Sponsors.Add(fia); + } + } + + context.Teams.Local.Single(t => t.Id == Team.McLaren).Sponsors.Add(vodafone); + context.Teams.Local.Single(t => t.Id == Team.Ferrari).Sponsors.Add(shell); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Driver.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Driver.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Driver.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Driver.cs index 80a6177c..771467b4 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Driver.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Driver.cs @@ -1,26 +1,26 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace ConcurrencyModel -{ - using System.ComponentModel.DataAnnotations; - - public class Driver - { - [Timestamp] - public byte[] Version { get; set; } - - public int Id { get; set; } - - public string Name { get; set; } - public int? CarNumber { get; set; } - public int Championships { get; set; } - public int Races { get; set; } - public int Wins { get; set; } - public int Podiums { get; set; } - public int Poles { get; set; } - public int FastestLaps { get; set; } - - public virtual Team Team { get; set; } - public int TeamId { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace ConcurrencyModel +{ + using System.ComponentModel.DataAnnotations; + + public class Driver + { + [Timestamp] + public byte[] Version { get; set; } + + public int Id { get; set; } + + public string Name { get; set; } + public int? CarNumber { get; set; } + public int Championships { get; set; } + public int Races { get; set; } + public int Wins { get; set; } + public int Podiums { get; set; } + public int Poles { get; set; } + public int FastestLaps { get; set; } + + public virtual Team Team { get; set; } + public int TeamId { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Engine.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Engine.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Engine.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Engine.cs index 2853961b..c5e4d3a0 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Engine.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Engine.cs @@ -1,26 +1,26 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace ConcurrencyModel -{ - using System.Collections.Generic; - using System.ComponentModel.DataAnnotations; - - public class Engine - { - public int Id { get; set; } - - [ConcurrencyCheck] - public string Name { get; set; } - - public Location StorageLocation { get; set; } - - [ConcurrencyCheck] - public int EngineSupplierId { get; set; } - - public virtual EngineSupplier EngineSupplier { get; set; } - - public virtual ICollection Teams { get; set; } - - public virtual ICollection Gearboxes { get; set; } // Uni-directional - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace ConcurrencyModel +{ + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + + public class Engine + { + public int Id { get; set; } + + [ConcurrencyCheck] + public string Name { get; set; } + + public Location StorageLocation { get; set; } + + [ConcurrencyCheck] + public int EngineSupplierId { get; set; } + + public virtual EngineSupplier EngineSupplier { get; set; } + + public virtual ICollection Teams { get; set; } + + public virtual ICollection Gearboxes { get; set; } // Uni-directional + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/EngineSupplier.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/EngineSupplier.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/EngineSupplier.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/EngineSupplier.cs index 527fb41f..dcc70ccb 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/EngineSupplier.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/EngineSupplier.cs @@ -1,15 +1,15 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace ConcurrencyModel -{ - using System.Collections.Generic; - - public class EngineSupplier - { - public int Id { get; set; } - - public string Name { get; set; } - - public virtual ICollection Engines { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace ConcurrencyModel +{ + using System.Collections.Generic; + + public class EngineSupplier + { + public int Id { get; set; } + + public string Name { get; set; } + + public virtual ICollection Engines { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/F1Context.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/F1Context.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/F1Context.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/F1Context.cs index 4f93d6a0..9f416981 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/F1Context.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/F1Context.cs @@ -1,95 +1,95 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace ConcurrencyModel -{ - using System.Data.Common; - using System.Data.Entity; - using System.Data.Entity.Core.Objects; - using System.Data.Entity.Infrastructure; - - public class F1Context : DbContext - { - static F1Context() - { - Database.SetInitializer(new ConcurrencyModelInitializer()); - } - - public F1Context(bool lazyLoadingEnabled = true, bool proxyCreationEnabled = true) - { - SetContextOptions(lazyLoadingEnabled, proxyCreationEnabled); - } - - public F1Context(DbCompiledModel model, bool lazyLoadingEnabled = true, bool proxyCreationEnabled = true) - : base(model) - { - SetContextOptions(lazyLoadingEnabled, proxyCreationEnabled); - } - - public F1Context(string nameOrConnectionString, bool lazyLoadingEnabled = true, bool proxyCreationEnabled = true) - : base(nameOrConnectionString) - { - SetContextOptions(lazyLoadingEnabled, proxyCreationEnabled); - } - - public F1Context( - string nameOrConnectionString, DbCompiledModel model, bool lazyLoadingEnabled = true, bool proxyCreationEnabled = true) - : base(nameOrConnectionString, model) - { - SetContextOptions(lazyLoadingEnabled, proxyCreationEnabled); - } - - public F1Context( - DbConnection existingConnection, bool contextOwnsConnection, bool lazyLoadingEnabled = true, bool proxyCreationEnabled = true) - : base(existingConnection, contextOwnsConnection) - { - SetContextOptions(lazyLoadingEnabled, proxyCreationEnabled); - } - - public F1Context( - DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection, bool lazyLoadingEnabled = true, - bool proxyCreationEnabled = true) - : base(existingConnection, model, contextOwnsConnection) - { - SetContextOptions(lazyLoadingEnabled, proxyCreationEnabled); - } - - public F1Context( - ObjectContext objectContext, bool dbContextOwnsObjectContext, bool lazyLoadingEnabled = true, bool proxyCreationEnabled = true) - : base(objectContext, dbContextOwnsObjectContext) - { - SetContextOptions(lazyLoadingEnabled, proxyCreationEnabled); - } - - private void SetContextOptions(bool lazyLoadingEnabled, bool proxyCreationEnabled) - { - // Only change the flags if set to false so that the tests can test that the defaults are true. - if (!lazyLoadingEnabled) - { - Configuration.LazyLoadingEnabled = false; - } - if (!proxyCreationEnabled) - { - Configuration.ProxyCreationEnabled = false; - } - } - - public DbSet Teams { get; set; } - public DbSet Drivers { get; set; } - public DbSet Sponsors { get; set; } - public DbSet Engines { get; set; } - public DbSet EngineSuppliers { get; set; } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - AdditionalModelConfiguration(modelBuilder); - } - - public static void AdditionalModelConfiguration(DbModelBuilder modelBuilder) - { - modelBuilder.Entity().HasRequired(c => c.Team).WithRequiredDependent(t => t.Chassis).WillCascadeOnDelete(); - modelBuilder.ComplexType(); - modelBuilder.Entity().ToTable("Sponsors"); - modelBuilder.Entity().ToTable("TitleSponsors"); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace ConcurrencyModel +{ + using System.Data.Common; + using System.Data.Entity; + using System.Data.Entity.Core.Objects; + using System.Data.Entity.Infrastructure; + + public class F1Context : DbContext + { + static F1Context() + { + Database.SetInitializer(new ConcurrencyModelInitializer()); + } + + public F1Context(bool lazyLoadingEnabled = true, bool proxyCreationEnabled = true) + { + SetContextOptions(lazyLoadingEnabled, proxyCreationEnabled); + } + + public F1Context(DbCompiledModel model, bool lazyLoadingEnabled = true, bool proxyCreationEnabled = true) + : base(model) + { + SetContextOptions(lazyLoadingEnabled, proxyCreationEnabled); + } + + public F1Context(string nameOrConnectionString, bool lazyLoadingEnabled = true, bool proxyCreationEnabled = true) + : base(nameOrConnectionString) + { + SetContextOptions(lazyLoadingEnabled, proxyCreationEnabled); + } + + public F1Context( + string nameOrConnectionString, DbCompiledModel model, bool lazyLoadingEnabled = true, bool proxyCreationEnabled = true) + : base(nameOrConnectionString, model) + { + SetContextOptions(lazyLoadingEnabled, proxyCreationEnabled); + } + + public F1Context( + DbConnection existingConnection, bool contextOwnsConnection, bool lazyLoadingEnabled = true, bool proxyCreationEnabled = true) + : base(existingConnection, contextOwnsConnection) + { + SetContextOptions(lazyLoadingEnabled, proxyCreationEnabled); + } + + public F1Context( + DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection, bool lazyLoadingEnabled = true, + bool proxyCreationEnabled = true) + : base(existingConnection, model, contextOwnsConnection) + { + SetContextOptions(lazyLoadingEnabled, proxyCreationEnabled); + } + + public F1Context( + ObjectContext objectContext, bool dbContextOwnsObjectContext, bool lazyLoadingEnabled = true, bool proxyCreationEnabled = true) + : base(objectContext, dbContextOwnsObjectContext) + { + SetContextOptions(lazyLoadingEnabled, proxyCreationEnabled); + } + + private void SetContextOptions(bool lazyLoadingEnabled, bool proxyCreationEnabled) + { + // Only change the flags if set to false so that the tests can test that the defaults are true. + if (!lazyLoadingEnabled) + { + Configuration.LazyLoadingEnabled = false; + } + if (!proxyCreationEnabled) + { + Configuration.ProxyCreationEnabled = false; + } + } + + public DbSet Teams { get; set; } + public DbSet Drivers { get; set; } + public DbSet Sponsors { get; set; } + public DbSet Engines { get; set; } + public DbSet EngineSuppliers { get; set; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + AdditionalModelConfiguration(modelBuilder); + } + + public static void AdditionalModelConfiguration(DbModelBuilder modelBuilder) + { + modelBuilder.Entity().HasRequired(c => c.Team).WithRequiredDependent(t => t.Chassis).WillCascadeOnDelete(); + modelBuilder.ComplexType(); + modelBuilder.Entity().ToTable("Sponsors"); + modelBuilder.Entity().ToTable("TitleSponsors"); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Gearbox.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Gearbox.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Gearbox.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Gearbox.cs index d57eaae6..3efe9eaf 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Gearbox.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Gearbox.cs @@ -1,13 +1,13 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace ConcurrencyModel -{ - public class Gearbox - { - public int Id { get; set; } - public string Name { get; set; } - - // Removed nav-prop to collection of Teams - // Removed nav-prop to Engine - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace ConcurrencyModel +{ + public class Gearbox + { + public int Id { get; set; } + public string Name { get; set; } + + // Removed nav-prop to collection of Teams + // Removed nav-prop to Engine + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Location.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Location.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Location.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Location.cs index b3fc0ba4..b84b9b96 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Location.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Location.cs @@ -1,15 +1,15 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace ConcurrencyModel -{ - using System.ComponentModel.DataAnnotations; - - public class Location - { - [ConcurrencyCheck] - public double Latitude { get; set; } - - [ConcurrencyCheck] - public double Longitude { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace ConcurrencyModel +{ + using System.ComponentModel.DataAnnotations; + + public class Location + { + [ConcurrencyCheck] + public double Latitude { get; set; } + + [ConcurrencyCheck] + public double Longitude { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Sponsor.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Sponsor.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Sponsor.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Sponsor.cs index 85cfa88d..a1a8016e 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Sponsor.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Sponsor.cs @@ -1,24 +1,24 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace ConcurrencyModel -{ - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.ComponentModel.DataAnnotations; - - public class Sponsor - { - private readonly ObservableCollection _teams = new ObservableCollection(); - - [Timestamp] - public byte[] Version { get; set; } - - public int Id { get; set; } - public string Name { get; set; } - - public virtual ICollection Teams - { - get { return _teams; } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace ConcurrencyModel +{ + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.ComponentModel.DataAnnotations; + + public class Sponsor + { + private readonly ObservableCollection _teams = new ObservableCollection(); + + [Timestamp] + public byte[] Version { get; set; } + + public int Id { get; set; } + public string Name { get; set; } + + public virtual ICollection Teams + { + get { return _teams; } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/SponsorDetails.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/SponsorDetails.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/SponsorDetails.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/SponsorDetails.cs index 821cbfc2..ddacaa1e 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/SponsorDetails.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/SponsorDetails.cs @@ -1,13 +1,13 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace ConcurrencyModel -{ - using System.ComponentModel.DataAnnotations.Schema; - - [ComplexType] - public class SponsorDetails - { - public int Days { get; set; } - public decimal Space { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace ConcurrencyModel +{ + using System.ComponentModel.DataAnnotations.Schema; + + [ComplexType] + public class SponsorDetails + { + public int Days { get; set; } + public decimal Space { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Team.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Team.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Team.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Team.cs index 99938a49..02f2832a 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/Team.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/Team.cs @@ -1,63 +1,63 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace ConcurrencyModel -{ - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; - using System.Data.Entity; - - public class Team - { - private readonly ObservableCollection _drivers = new ObservableListSource(); - private readonly ObservableCollection _sponsors = new ObservableCollection(); - - [Timestamp] - public byte[] Version { get; set; } - - [DatabaseGenerated(DatabaseGeneratedOption.None)] - public int Id { get; set; } - - public string Name { get; set; } - public string Constructor { get; set; } - public string Tire { get; set; } - public string Principal { get; set; } - public int ConstructorsChampionships { get; set; } - public int DriversChampionships { get; set; } - public int Races { get; set; } - public int Victories { get; set; } - public int Poles { get; set; } - public int FastestLaps { get; set; } - - public virtual Engine Engine { get; set; } // Independent Association - - public virtual Chassis Chassis { get; set; } - - public virtual ICollection Drivers - { - get { return _drivers; } - } - - public virtual ICollection Sponsors - { - get { return _sponsors; } - } - - public int? GearboxId { get; set; } - public virtual Gearbox Gearbox { get; set; } // Uni-directional - - public const int McLaren = 1; - public const int Mercedes = 2; - public const int RedBull = 3; - public const int Ferrari = 4; - public const int Williams = 5; - public const int Renault = 6; - public const int ForceIndia = 7; - public const int ToroRosso = 8; - public const int Lotus = 9; - public const int Hispania = 10; - public const int Sauber = 11; - public const int Virgin = 12; - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace ConcurrencyModel +{ + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.ComponentModel.DataAnnotations; + using System.ComponentModel.DataAnnotations.Schema; + using System.Data.Entity; + + public class Team + { + private readonly ObservableCollection _drivers = new ObservableListSource(); + private readonly ObservableCollection _sponsors = new ObservableCollection(); + + [Timestamp] + public byte[] Version { get; set; } + + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public int Id { get; set; } + + public string Name { get; set; } + public string Constructor { get; set; } + public string Tire { get; set; } + public string Principal { get; set; } + public int ConstructorsChampionships { get; set; } + public int DriversChampionships { get; set; } + public int Races { get; set; } + public int Victories { get; set; } + public int Poles { get; set; } + public int FastestLaps { get; set; } + + public virtual Engine Engine { get; set; } // Independent Association + + public virtual Chassis Chassis { get; set; } + + public virtual ICollection Drivers + { + get { return _drivers; } + } + + public virtual ICollection Sponsors + { + get { return _sponsors; } + } + + public int? GearboxId { get; set; } + public virtual Gearbox Gearbox { get; set; } // Uni-directional + + public const int McLaren = 1; + public const int Mercedes = 2; + public const int RedBull = 3; + public const int Ferrari = 4; + public const int Williams = 5; + public const int Renault = 6; + public const int ForceIndia = 7; + public const int ToroRosso = 8; + public const int Lotus = 9; + public const int Hispania = 10; + public const int Sauber = 11; + public const int Virgin = 12; + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/TestDriver.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/TestDriver.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/TestDriver.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/TestDriver.cs index a28f40e3..829cea58 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/TestDriver.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/TestDriver.cs @@ -1,8 +1,8 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace ConcurrencyModel -{ - public class TestDriver : Driver - { - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace ConcurrencyModel +{ + public class TestDriver : Driver + { + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/TitleSponsor.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/TitleSponsor.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/TitleSponsor.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/TitleSponsor.cs index 6a73b117..3bb76c67 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/ConcurrencyModel/TitleSponsor.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/ConcurrencyModel/TitleSponsor.cs @@ -1,9 +1,9 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace ConcurrencyModel -{ - public class TitleSponsor : Sponsor - { - public SponsorDetails Details { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace ConcurrencyModel +{ + public class TitleSponsor : Sponsor + { + public SponsorDetails Details { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/201112202056275_InitialCreate.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/201112202056275_InitialCreate.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/201112202056275_InitialCreate.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/201112202056275_InitialCreate.cs index 785526c3..6040c3ca 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/201112202056275_InitialCreate.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/201112202056275_InitialCreate.cs @@ -1,26 +1,26 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.SimpleMigrationsModel -{ - using System.Data.Entity.Migrations; - - public partial class InitialCreate : DbMigration - { - public override void Up() - { - CreateTable( - "Blogs", - c => new - { - BlogId = c.Int(nullable: false, identity: true), - Name = c.String(), - }) - .PrimaryKey(t => t.BlogId); - } - - public override void Down() - { - DropTable("Blogs"); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.SimpleMigrationsModel +{ + using System.Data.Entity.Migrations; + + public partial class InitialCreate : DbMigration + { + public override void Up() + { + CreateTable( + "Blogs", + c => new + { + BlogId = c.Int(nullable: false, identity: true), + Name = c.String(), + }) + .PrimaryKey(t => t.BlogId); + } + + public override void Down() + { + DropTable("Blogs"); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/201112202056275_InitialCreate.designer.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/201112202056275_InitialCreate.designer.cs similarity index 98% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/201112202056275_InitialCreate.designer.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/201112202056275_InitialCreate.designer.cs index 63c7367c..86f60918 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/201112202056275_InitialCreate.designer.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/201112202056275_InitialCreate.designer.cs @@ -1,23 +1,23 @@ -// -namespace FunctionalTests.SimpleMigrationsModel -{ - using System.Data.Entity.Migrations.Infrastructure; - - public sealed partial class InitialCreate : IMigrationMetadata - { - string IMigrationMetadata.Id - { - get { return "201112202056275_InitialCreate"; } - } - - string IMigrationMetadata.Source - { - get { return null; } - } - - string IMigrationMetadata.Target - { - get { return "H4sIAAAAAAAEAOy9B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Iv7Hv/cffPx7vFuU6WVeN0W1/Oyj3fHOR2m+nFazYnnx2Ufr9nz74KPf4+g3Th6fzhbv0p807fbQjt5cNp99NG/b1aO7d5vpPF9kzXhRTOuqqc7b8bRa3M1m1d29nZ2Du7s7d3MC8RHBStPHr9bLtljk/Af9eVItp/mqXWflF9UsLxv9nL55zVDTF9kib1bZNP/so2fr5bQlJLLyTd60zfh1sViV+RfFRZ3h44YhfJQel0VGyL3Oy/P3xHTnITD9yOJAWJwStu31m+tVzph89tGTsrrwW1Cb3yu/Dj6gj17W1Sqv2+tX+bn33tnso/Ru+O7d7sv21c57QOGzj86W7b29j9IX67LMJiV9cJ6VTf5Ruvr00eu2qvPP82VO1MhnL7O2zWuar7NZzkNQUjxafXo7ajy8u7MHatzNlsuqZQL3kO+gin8Noq/bmvjoo/RZ8S6fPc+XF+3cIvtF9s58Qr9+lH61LIjt6KW2Xuf+4ORvv9PHd92E9KeJmKnNCqKAIiSskZ8ti7bIyuIHeY0W+bu2M4Hy9uu89WjefJS6roSbxjz3UXxsz45/7woDG0a/O8Dpj7/IVisilcf5+kn6Wtj+ZPv1+/PxQmDcnTYRdrbY2p6Id7KLvPMtdU2YPivqpn2atdkkw+SdzBa9Zu9NZ9OvT+6uCDnqm9b4Xd64lSYY90WVASu4ZzTiBckGD16HTqjFJFxffD3NyqwekM+TqlwvlptkfRMUER0fhnzSh/D4bgf/Lt08CdGWHY3TnYVN7NxtYnu3bN1h38fKSjdr8x5vSZOPUiLNZTEDX72+btp8MUaD8etfVJ6UBY3XNfgiWxbnNP9vqrc5LBOx/tfX/lbfNc2s/H+zCShAghuVfc9C3F51Ly+zejrP6q1F9u7ON6mO+9rkZjU8qIWFWz77aDapCHFBUPX211TQfc59fNf3Vh4/zZviwoGA77LMWQ85oKbN2fK8MjSmEfkYmSadKfgib7MZEea4bovzbNrS19O8adiK/mRWrqnJ6WKSz86WX67b1bo9bpp8MSmv/fE+vru5f7ZCIc6Pv1yxyvwmhkBoFjSE/Mvlk3VRzizez/osOAQCPKJ8TViRF0HgLq4tpBfV8paAlHxP81W+hFS8yclEELDmy+Xr7DIfxu1mGoYUe/y0yMjuLHwKyieKyesMxsl1QR34b7j+6E9iV3KVj/6fAAAA///YrxpUnwsAAA=="; } - } - } -} +// +namespace FunctionalTests.SimpleMigrationsModel +{ + using System.Data.Entity.Migrations.Infrastructure; + + public sealed partial class InitialCreate : IMigrationMetadata + { + string IMigrationMetadata.Id + { + get { return "201112202056275_InitialCreate"; } + } + + string IMigrationMetadata.Source + { + get { return null; } + } + + string IMigrationMetadata.Target + { + get { return "H4sIAAAAAAAEAOy9B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Iv7Hv/cffPx7vFuU6WVeN0W1/Oyj3fHOR2m+nFazYnnx2Ufr9nz74KPf4+g3Th6fzhbv0p807fbQjt5cNp99NG/b1aO7d5vpPF9kzXhRTOuqqc7b8bRa3M1m1d29nZ2Du7s7d3MC8RHBStPHr9bLtljk/Af9eVItp/mqXWflF9UsLxv9nL55zVDTF9kib1bZNP/so2fr5bQlJLLyTd60zfh1sViV+RfFRZ3h44YhfJQel0VGyL3Oy/P3xHTnITD9yOJAWJwStu31m+tVzph89tGTsrrwW1Cb3yu/Dj6gj17W1Sqv2+tX+bn33tnso/Ru+O7d7sv21c57QOGzj86W7b29j9IX67LMJiV9cJ6VTf5Ruvr00eu2qvPP82VO1MhnL7O2zWuar7NZzkNQUjxafXo7ajy8u7MHatzNlsuqZQL3kO+gin8Noq/bmvjoo/RZ8S6fPc+XF+3cIvtF9s58Qr9+lH61LIjt6KW2Xuf+4ORvv9PHd92E9KeJmKnNCqKAIiSskZ8ti7bIyuIHeY0W+bu2M4Hy9uu89WjefJS6roSbxjz3UXxsz45/7woDG0a/O8Dpj7/IVisilcf5+kn6Wtj+ZPv1+/PxQmDcnTYRdrbY2p6Id7KLvPMtdU2YPivqpn2atdkkw+SdzBa9Zu9NZ9OvT+6uCDnqm9b4Xd64lSYY90WVASu4ZzTiBckGD16HTqjFJFxffD3NyqwekM+TqlwvlptkfRMUER0fhnzSh/D4bgf/Lt08CdGWHY3TnYVN7NxtYnu3bN1h38fKSjdr8x5vSZOPUiLNZTEDX72+btp8MUaD8etfVJ6UBY3XNfgiWxbnNP9vqrc5LBOx/tfX/lbfNc2s/H+zCShAghuVfc9C3F51Ly+zejrP6q1F9u7ON6mO+9rkZjU8qIWFWz77aDapCHFBUPX211TQfc59fNf3Vh4/zZviwoGA77LMWQ85oKbN2fK8MjSmEfkYmSadKfgib7MZEea4bovzbNrS19O8adiK/mRWrqnJ6WKSz86WX67b1bo9bpp8MSmv/fE+vru5f7ZCIc6Pv1yxyvwmhkBoFjSE/Mvlk3VRzizez/osOAQCPKJ8TViRF0HgLq4tpBfV8paAlHxP81W+hFS8yclEELDmy+Xr7DIfxu1mGoYUe/y0yMjuLHwKyieKyesMxsl1QR34b7j+6E9iV3KVj/6fAAAA///YrxpUnwsAAA=="; } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/201112202056573_AddUrlToBlog.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/201112202056573_AddUrlToBlog.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/201112202056573_AddUrlToBlog.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/201112202056573_AddUrlToBlog.cs index dd5a8f6f..9c6d9a67 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/201112202056573_AddUrlToBlog.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/201112202056573_AddUrlToBlog.cs @@ -1,19 +1,19 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.SimpleMigrationsModel -{ - using System.Data.Entity.Migrations; - - public partial class AddUrlToBlog : DbMigration - { - public override void Up() - { - AddColumn("Blogs", "Url", c => c.String()); - } - - public override void Down() - { - DropColumn("Blogs", "Url"); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.SimpleMigrationsModel +{ + using System.Data.Entity.Migrations; + + public partial class AddUrlToBlog : DbMigration + { + public override void Up() + { + AddColumn("Blogs", "Url", c => c.String()); + } + + public override void Down() + { + DropColumn("Blogs", "Url"); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/201112202056573_AddUrlToBlog.designer.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/201112202056573_AddUrlToBlog.designer.cs similarity index 98% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/201112202056573_AddUrlToBlog.designer.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/201112202056573_AddUrlToBlog.designer.cs index b2071714..add81da9 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/201112202056573_AddUrlToBlog.designer.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/201112202056573_AddUrlToBlog.designer.cs @@ -1,23 +1,23 @@ -// -namespace FunctionalTests.SimpleMigrationsModel -{ - using System.Data.Entity.Migrations.Infrastructure; - - public sealed partial class AddUrlToBlog : IMigrationMetadata - { - string IMigrationMetadata.Id - { - get { return "201112202056573_AddUrlToBlog"; } - } - - string IMigrationMetadata.Source - { - get { return null; } - } - - string IMigrationMetadata.Target - { - get { return "H4sIAAAAAAAEAOy9B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Iv7Hv/cffPx7vFuU6WVeN0W1/Oyj3fHOR2m+nFazYnnx2Ufr9nz74KPf4+g3Th6fzhbv0p807fbQjt5cNp99NG/b1aO7d5vpPF9kzXhRTOuqqc7b8bRa3M1m1d29nZ2Du7s7d3MC8RHBStPHr9bLtljk/Af9eVItp/mqXWflF9UsLxv9nL55zVDTF9kib1bZNP/so2fr5bQlJLLyTd60zfh1sViV+RfFRZ3h44YhfJQel0VGyL3Oy/P3xHTnITD9yOJAWJwStu31m+tVzph89tGTsrrwW1Cb3yu/Dj6gj17W1Sqv2+tX+bn33tnso/Ru+O7d7sv21c57QOGzj86W7b29j9IX67LMJiV9cJ6VTf5Ruvr00eu2qvPP82VO1MhnL7O2zWuar7NZzkNQUjxafXo7ajy8u7MHatzNlsuqZQL3kO+gin8Noq/bmvjoo/RZ8S6fPc+XF+3cIvtF9s58Qr9+lH61LIjt6KW2Xuf+4OTvzZ1+VZc/y30+vuuYoM8axMBtVhDVFR9hx/xsWbRFVhY/yGu0yN+1HaaRt1/nrTfPzUep60o4eMz8FsXH9uxk5q4IjRGuuwPS9fiLbLUiUnnSpp+kr0XUTrZfv7/sLATG3WkTESGLre2J+DW7yDvfUteE6bOibtqnWZtNMkzeyWzRa/bedDb9+uTuiq2jvmmN3+WNW2mfcV89MGAF94xGvCB55MHr0Am1mFbRF19PszKrB3TCSVWuF8tN+mUTFBFXH4Z8cnsILHs+AP6g//7ju53xd+nuSZi27GjJ7ixuEoduE9u7FYsO+z9WVrzZAvV4U5p8lBJhLosZ+PL1ddPmizEajF//ovKkLGi8rsEX2bI4J/55U73NYU1JdL6+xbI6umlm5f+bzVYBEtxooHpW7fbmZnmZ1dN5Vm8tsnd3PsCEvAec9zMLfa12szkYtAbCdZ99NJtUhLggqPbjaxqKvgQ8vut7ao+f5k1x4UDAb1vmrA8dUNPmbHleGRLTiHyMTJPODHyRt9mMCHNct8V5Nm3p62neNGzNfzIr19TkdDHJZ2fLL9ftat0eN02+mJTX/ngf393cP1vDEOfHX65YdX8TQyA0CxpC/uXyybooZxbvZ31WHgIBHlH5IKzImyFwF9cW0otqeUtASr6n+SpfQrre5GSqCFjz5fJ1dpkP43YzDUOKPX5aZGT/Fj4F5RPF5HUGI+m6oA78N1x/9CexK4UJR/9PAAAA//9OGYbgmwwAAA=="; } - } - } -} +// +namespace FunctionalTests.SimpleMigrationsModel +{ + using System.Data.Entity.Migrations.Infrastructure; + + public sealed partial class AddUrlToBlog : IMigrationMetadata + { + string IMigrationMetadata.Id + { + get { return "201112202056573_AddUrlToBlog"; } + } + + string IMigrationMetadata.Source + { + get { return null; } + } + + string IMigrationMetadata.Target + { + get { return "H4sIAAAAAAAEAOy9B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Iv7Hv/cffPx7vFuU6WVeN0W1/Oyj3fHOR2m+nFazYnnx2Ufr9nz74KPf4+g3Th6fzhbv0p807fbQjt5cNp99NG/b1aO7d5vpPF9kzXhRTOuqqc7b8bRa3M1m1d29nZ2Du7s7d3MC8RHBStPHr9bLtljk/Af9eVItp/mqXWflF9UsLxv9nL55zVDTF9kib1bZNP/so2fr5bQlJLLyTd60zfh1sViV+RfFRZ3h44YhfJQel0VGyL3Oy/P3xHTnITD9yOJAWJwStu31m+tVzph89tGTsrrwW1Cb3yu/Dj6gj17W1Sqv2+tX+bn33tnso/Ru+O7d7sv21c57QOGzj86W7b29j9IX67LMJiV9cJ6VTf5Ruvr00eu2qvPP82VO1MhnL7O2zWuar7NZzkNQUjxafXo7ajy8u7MHatzNlsuqZQL3kO+gin8Noq/bmvjoo/RZ8S6fPc+XF+3cIvtF9s58Qr9+lH61LIjt6KW2Xuf+4OTvzZ1+VZc/y30+vuuYoM8axMBtVhDVFR9hx/xsWbRFVhY/yGu0yN+1HaaRt1/nrTfPzUep60o4eMz8FsXH9uxk5q4IjRGuuwPS9fiLbLUiUnnSpp+kr0XUTrZfv7/sLATG3WkTESGLre2J+DW7yDvfUteE6bOibtqnWZtNMkzeyWzRa/bedDb9+uTuiq2jvmmN3+WNW2mfcV89MGAF94xGvCB55MHr0Am1mFbRF19PszKrB3TCSVWuF8tN+mUTFBFXH4Z8cnsILHs+AP6g//7ju53xd+nuSZi27GjJ7ixuEoduE9u7FYsO+z9WVrzZAvV4U5p8lBJhLosZ+PL1ddPmizEajF//ovKkLGi8rsEX2bI4J/55U73NYU1JdL6+xbI6umlm5f+bzVYBEtxooHpW7fbmZnmZ1dN5Vm8tsnd3PsCEvAec9zMLfa12szkYtAbCdZ99NJtUhLggqPbjaxqKvgQ8vut7ao+f5k1x4UDAb1vmrA8dUNPmbHleGRLTiHyMTJPODHyRt9mMCHNct8V5Nm3p62neNGzNfzIr19TkdDHJZ2fLL9ftat0eN02+mJTX/ngf393cP1vDEOfHX65YdX8TQyA0CxpC/uXyybooZxbvZ31WHgIBHlH5IKzImyFwF9cW0otqeUtASr6n+SpfQrre5GSqCFjz5fJ1dpkP43YzDUOKPX5aZGT/Fj4F5RPF5HUGI+m6oA78N1x/9CexK4UJR/9PAAAA//9OGYbgmwwAAA=="; } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/Blog.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/Blog.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/Blog.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/Blog.cs index 7dd3b3ad..28e0b6c5 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/Blog.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/Blog.cs @@ -1,11 +1,11 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.SimpleMigrationsModel -{ - public class Blog - { - public int BlogId { get; set; } - public string Name { get; set; } - public string Url { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.SimpleMigrationsModel +{ + public class Blog + { + public int BlogId { get; set; } + public string Name { get; set; } + public string Url { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/MigrateInitializerConfiguration.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/MigrateInitializerConfiguration.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/MigrateInitializerConfiguration.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/MigrateInitializerConfiguration.cs index e090b5d3..4b2da8f4 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/MigrateInitializerConfiguration.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/MigrateInitializerConfiguration.cs @@ -1,28 +1,28 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.SimpleMigrationsModel -{ - using System.Data.Entity.Migrations; - - public class MigrateInitializerConfiguration : DbMigrationsConfiguration - { - public MigrateInitializerConfiguration() - { - MigrationsNamespace = "FunctionalTests.SimpleMigrationsModel"; - } - - protected override void Seed(MigrateInitializerContext context) - { - context.Blogs.AddOrUpdate( - b => b.Name, - new Blog - { - Name = "romiller.com" - }, - new Blog - { - Name = "blogs.msdn.com\adonet" - }); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.SimpleMigrationsModel +{ + using System.Data.Entity.Migrations; + + public class MigrateInitializerConfiguration : DbMigrationsConfiguration + { + public MigrateInitializerConfiguration() + { + MigrationsNamespace = "FunctionalTests.SimpleMigrationsModel"; + } + + protected override void Seed(MigrateInitializerContext context) + { + context.Blogs.AddOrUpdate( + b => b.Name, + new Blog + { + Name = "romiller.com" + }, + new Blog + { + Name = "blogs.msdn.com\adonet" + }); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/MigrateInitializerContext.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/MigrateInitializerContext.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/MigrateInitializerContext.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/MigrateInitializerContext.cs index 89dca73b..dd0aefbf 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleMigrationsModel/MigrateInitializerContext.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleMigrationsModel/MigrateInitializerContext.cs @@ -1,11 +1,11 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.SimpleMigrationsModel -{ - using System.Data.Entity; - - public class MigrateInitializerContext : DbContext - { - public DbSet Blogs { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.SimpleMigrationsModel +{ + using System.Data.Entity; + + public class MigrateInitializerContext : DbContext + { + public DbSet Blogs { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/Blog.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/Blog.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleModel/Blog.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/Blog.cs index 9ad1c2e0..7c73411c 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/Blog.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/Blog.cs @@ -1,15 +1,15 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace SimpleModel -{ - using System.ComponentModel.DataAnnotations; - - public class Blog - { - [Key] - public int Id { get; set; } - - public string Title { get; set; } - public string Content { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace SimpleModel +{ + using System.ComponentModel.DataAnnotations; + + public class Blog + { + [Key] + public int Id { get; set; } + + public string Title { get; set; } + public string Content { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/Category.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/Category.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleModel/Category.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/Category.cs index 72113a76..62d15d9c 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/Category.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/Category.cs @@ -1,24 +1,24 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace SimpleModel -{ - using System.Collections.Generic; - - public class Category - { - public Category() - { - Products = new List(); - } - - public Category(string id) - : this() - { - Id = id; - } - - public string Id { get; set; } - public ICollection Products { get; set; } - public string DetailedDescription { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace SimpleModel +{ + using System.Collections.Generic; + + public class Category + { + public Category() + { + Products = new List(); + } + + public Category(string id) + : this() + { + Id = id; + } + + public string Id { get; set; } + public ICollection Products { get; set; } + public string DetailedDescription { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/EmptyContext.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/EmptyContext.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleModel/EmptyContext.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/EmptyContext.cs index 9255b4ef..a117acff 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/EmptyContext.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/EmptyContext.cs @@ -1,24 +1,24 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace SimpleModel -{ - using System.Data.Common; - using System.Data.Entity; - - public class EmptyContext : DbContext - { - public EmptyContext() - { - } - - public EmptyContext(string nameOrConnectionString) - : base(nameOrConnectionString) - { - } - - public EmptyContext(DbConnection connection, bool contextOwnsConnection = false) - : base(connection, contextOwnsConnection) - { - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace SimpleModel +{ + using System.Data.Common; + using System.Data.Entity; + + public class EmptyContext : DbContext + { + public EmptyContext() + { + } + + public EmptyContext(string nameOrConnectionString) + : base(nameOrConnectionString) + { + } + + public EmptyContext(DbConnection connection, bool contextOwnsConnection = false) + : base(connection, contextOwnsConnection) + { + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/ExtraEntity.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/ExtraEntity.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleModel/ExtraEntity.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/ExtraEntity.cs index 9633bad2..25183e0e 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/ExtraEntity.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/ExtraEntity.cs @@ -1,13 +1,13 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace SimpleModel -{ - /// - /// Stand-alone entity type that is not part of any other models - /// - public class ExtraEntity - { - public int Id { get; set; } - public string Name { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace SimpleModel +{ + /// + /// Stand-alone entity type that is not part of any other models + /// + public class ExtraEntity + { + public int Id { get; set; } + public string Name { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/FeaturedProduct.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/FeaturedProduct.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleModel/FeaturedProduct.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/FeaturedProduct.cs index ed7a5ef0..a6283574 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/FeaturedProduct.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/FeaturedProduct.cs @@ -1,9 +1,9 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace SimpleModel -{ - public class FeaturedProduct : Product - { - public string PromotionalCode { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace SimpleModel +{ + public class FeaturedProduct : Product + { + public string PromotionalCode { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/FuncyContexts.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/FuncyContexts.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleModel/FuncyContexts.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/FuncyContexts.cs index 09f750b9..9d3e6116 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/FuncyContexts.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/FuncyContexts.cs @@ -1,40 +1,40 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace DaFunc -{ - using System.Data.Entity; - - /// - /// A normal type with an intentionally short name--see above. - /// - public class NT - { - } - - /// - /// A generic type with an intentionally short name--see above. - /// - public class GT - { - /// - /// A context type nested in a generic type. - /// - public class Funcy : DbContext - { - } - - /// - /// A generic context type nested in a generic type. - /// - public class GenericFuncy : DbContext - { - } - } - - /// - /// A generic context type. - /// - public class GenericFuncy : DbContext - { - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace DaFunc +{ + using System.Data.Entity; + + /// + /// A normal type with an intentionally short name--see above. + /// + public class NT + { + } + + /// + /// A generic type with an intentionally short name--see above. + /// + public class GT + { + /// + /// A context type nested in a generic type. + /// + public class Funcy : DbContext + { + } + + /// + /// A generic context type nested in a generic type. + /// + public class GenericFuncy : DbContext + { + } + } + + /// + /// A generic context type. + /// + public class GenericFuncy : DbContext + { + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/LiveWriterContext.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/LiveWriterContext.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleModel/LiveWriterContext.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/LiveWriterContext.cs index ff43626d..833f3523 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/LiveWriterContext.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/LiveWriterContext.cs @@ -1,32 +1,32 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace SimpleModel -{ - using System.Data.Entity; - using System.Data.Entity.Infrastructure; - - public class LiveWriterContext : DbContext - { - static LiveWriterContext() - { - Database.SetInitializer(new DropCreateDatabaseIfModelChanges()); - } - - public LiveWriterContext() - { - } - - public LiveWriterContext(DbCompiledModel model) - : base(model) - { - } - - public DbSet Blogs { get; set; } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - modelBuilder.Entity().HasKey(k => k.Id); - base.OnModelCreating(modelBuilder); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace SimpleModel +{ + using System.Data.Entity; + using System.Data.Entity.Infrastructure; + + public class LiveWriterContext : DbContext + { + static LiveWriterContext() + { + Database.SetInitializer(new DropCreateDatabaseIfModelChanges()); + } + + public LiveWriterContext() + { + } + + public LiveWriterContext(DbCompiledModel model) + : base(model) + { + } + + public DbSet Blogs { get; set; } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + modelBuilder.Entity().HasKey(k => k.Id); + base.OnModelCreating(modelBuilder); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/Login.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/Login.cs similarity index 95% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleModel/Login.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/Login.cs index 95e4c9f1..266f478e 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/Login.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/Login.cs @@ -1,21 +1,21 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace SimpleModel -{ - using System; - - public class Login - { - public Login() - { - } - - public Login(Guid id) - { - Id = id; - } - - public Guid Id { get; set; } - public string Username { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace SimpleModel +{ + using System; + + public class Login + { + public Login() + { + } + + public Login(Guid id) + { + Id = id; + } + + public Guid Id { get; set; } + public string Username { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/Product.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/Product.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleModel/Product.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/Product.cs index 71ad7c40..152544d6 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/Product.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/Product.cs @@ -1,10 +1,10 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace SimpleModel -{ - public class Product : ProductBase - { - public string CategoryId { get; set; } - public Category Category { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace SimpleModel +{ + public class Product : ProductBase + { + public string CategoryId { get; set; } + public Category Category { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/ProductBase.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/ProductBase.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleModel/ProductBase.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/ProductBase.cs index 47569fc5..c0a7211e 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/ProductBase.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/ProductBase.cs @@ -1,10 +1,10 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace SimpleModel -{ - public class ProductBase - { - public int Id { get; set; } - public string Name { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace SimpleModel +{ + public class ProductBase + { + public int Id { get; set; } + public string Name { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/SimpleModelContext.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/SimpleModelContext.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleModel/SimpleModelContext.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/SimpleModelContext.cs index bc46eda8..aab0fec6 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/SimpleModelContext.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/SimpleModelContext.cs @@ -1,60 +1,60 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace SimpleModel -{ - using System.Data.Common; - using System.Data.Entity; - using System.Data.Entity.Core.Objects; - using System.Data.Entity.Infrastructure; - - [DbModelBuilderVersion(DbModelBuilderVersion.Latest)] - public class SimpleModelContext : DbContext - { - public SimpleModelContext() - { - } - - public SimpleModelContext(DbCompiledModel model) - : base(model) - { - } - - public SimpleModelContext(string nameOrConnectionString) - : base(nameOrConnectionString) - { - } - - public SimpleModelContext(string nameOrConnectionString, DbCompiledModel model) - : base(nameOrConnectionString, model) - { - } - - public SimpleModelContext(DbConnection existingConnection, bool contextOwnsConnection = false) - : base(existingConnection, contextOwnsConnection) - { - } - - public SimpleModelContext(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection = false) - : base(existingConnection, model, contextOwnsConnection) - { - } - - public SimpleModelContext(ObjectContext objectContext, bool dbContextOwnsObjectContext = false) - : base(objectContext, dbContextOwnsObjectContext) - { - } - - public DbSet Products { get; set; } - public DbSet Categories { get; set; } - - public static DbModelBuilder CreateBuilder() - { - var builder = new DbModelBuilder(); - - builder.Entity(); - builder.Entity(); - - return builder; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace SimpleModel +{ + using System.Data.Common; + using System.Data.Entity; + using System.Data.Entity.Core.Objects; + using System.Data.Entity.Infrastructure; + + [DbModelBuilderVersion(DbModelBuilderVersion.Latest)] + public class SimpleModelContext : DbContext + { + public SimpleModelContext() + { + } + + public SimpleModelContext(DbCompiledModel model) + : base(model) + { + } + + public SimpleModelContext(string nameOrConnectionString) + : base(nameOrConnectionString) + { + } + + public SimpleModelContext(string nameOrConnectionString, DbCompiledModel model) + : base(nameOrConnectionString, model) + { + } + + public SimpleModelContext(DbConnection existingConnection, bool contextOwnsConnection = false) + : base(existingConnection, contextOwnsConnection) + { + } + + public SimpleModelContext(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection = false) + : base(existingConnection, model, contextOwnsConnection) + { + } + + public SimpleModelContext(ObjectContext objectContext, bool dbContextOwnsObjectContext = false) + : base(objectContext, dbContextOwnsObjectContext) + { + } + + public DbSet Products { get; set; } + public DbSet Categories { get; set; } + + public static DbModelBuilder CreateBuilder() + { + var builder = new DbModelBuilder(); + + builder.Entity(); + builder.Entity(); + + return builder; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/SimpleModelContextWithNoData.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/SimpleModelContextWithNoData.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleModel/SimpleModelContextWithNoData.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/SimpleModelContextWithNoData.cs index a271f7e5..fb75dca4 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/SimpleModelContextWithNoData.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/SimpleModelContextWithNoData.cs @@ -1,74 +1,74 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace SimpleModel -{ - using System.Data.Common; - using System.Data.Entity; - using System.Data.Entity.Core.Objects; - using System.Data.Entity.Infrastructure; - using System.Threading; - using System.Threading.Tasks; - - public class SimpleModelContextWithNoData : DbContext - { - static SimpleModelContextWithNoData() - { - Database.SetInitializer(new DropCreateDatabaseAlways()); - } - - public SimpleModelContextWithNoData() - { - } - - public SimpleModelContextWithNoData(string nameOrConnectionString) - : base(nameOrConnectionString) - { - } - - public SimpleModelContextWithNoData(DbCompiledModel model) - : base(model) - { - } - - public SimpleModelContextWithNoData(string nameOrConnectionString, DbCompiledModel model) - : base(nameOrConnectionString, model) - { - } - - public SimpleModelContextWithNoData(DbConnection existingConnection, bool contextOwnsConnection = false) - : base(existingConnection, contextOwnsConnection) - { - } - - public SimpleModelContextWithNoData(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection = false) - : base(existingConnection, model, contextOwnsConnection) - { - } - - public SimpleModelContextWithNoData(ObjectContext objectContext, bool dbContextOwnsObjectContext = false) - : base(objectContext, dbContextOwnsObjectContext) - { - } - - public IDbSet Products { get; set; } - public IDbSet Categories { get; set; } - - public bool SaveChangesCalled { get; set; } - - public override int SaveChanges() - { - SaveChangesCalled = true; - return base.SaveChanges(); - } - -#if !NET40 - - public override Task SaveChangesAsync(CancellationToken cancellationToken) - { - SaveChangesCalled = true; - return base.SaveChangesAsync(cancellationToken); - } - -#endif - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace SimpleModel +{ + using System.Data.Common; + using System.Data.Entity; + using System.Data.Entity.Core.Objects; + using System.Data.Entity.Infrastructure; + using System.Threading; + using System.Threading.Tasks; + + public class SimpleModelContextWithNoData : DbContext + { + static SimpleModelContextWithNoData() + { + Database.SetInitializer(new DropCreateDatabaseAlways()); + } + + public SimpleModelContextWithNoData() + { + } + + public SimpleModelContextWithNoData(string nameOrConnectionString) + : base(nameOrConnectionString) + { + } + + public SimpleModelContextWithNoData(DbCompiledModel model) + : base(model) + { + } + + public SimpleModelContextWithNoData(string nameOrConnectionString, DbCompiledModel model) + : base(nameOrConnectionString, model) + { + } + + public SimpleModelContextWithNoData(DbConnection existingConnection, bool contextOwnsConnection = false) + : base(existingConnection, contextOwnsConnection) + { + } + + public SimpleModelContextWithNoData(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection = false) + : base(existingConnection, model, contextOwnsConnection) + { + } + + public SimpleModelContextWithNoData(ObjectContext objectContext, bool dbContextOwnsObjectContext = false) + : base(objectContext, dbContextOwnsObjectContext) + { + } + + public IDbSet Products { get; set; } + public IDbSet Categories { get; set; } + + public bool SaveChangesCalled { get; set; } + + public override int SaveChanges() + { + SaveChangesCalled = true; + return base.SaveChanges(); + } + +#if !NET40 + + public override Task SaveChangesAsync(CancellationToken cancellationToken) + { + SaveChangesCalled = true; + return base.SaveChangesAsync(cancellationToken); + } + +#endif + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/SimpleModelInitializer.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/SimpleModelInitializer.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/SimpleModel/SimpleModelInitializer.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/SimpleModelInitializer.cs index 4ba7b9cc..7f70119c 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/SimpleModel/SimpleModelInitializer.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/SimpleModel/SimpleModelInitializer.cs @@ -1,73 +1,73 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace SimpleModel -{ - using System.Collections.Generic; - using System.Data.Entity; - - public class SimpleModelInitializer : DropCreateDatabaseIfModelChanges - { - protected override void Seed(SimpleModelContext context) - { - new List - { - new Product - { - Name = "Marmite", - CategoryId = "Foods" - }, - new Product - { - Name = "Bovril", - CategoryId = "Beverages" - }, - new Product - { - Name = "iSnack 2.0", - CategoryId = "Foods" - }, - new Product - { - Name = "Irn-Bru", - CategoryId = "Beverages" - }, - new Product - { - Name = "Ibuprofen", - CategoryId = "Medications" - }, - new Product - { - Name = "Strongbow", - CategoryId = "Medications" - }, - new FeaturedProduct - { - Name = "Cadillac", - CategoryId = "Cars", - PromotionalCode = "Ed Wood" - }, - }.ForEach(p => context.Products.Add(p)); - - new List - { - new Category - { - Id = "Beverages" - }, - new Category - { - Id = "Foods" - }, - new Category - { - Id = "Medications" - }, - new Category - { - Id = "Cars" - }, - }.ForEach(c => context.Categories.Add(c)); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace SimpleModel +{ + using System.Collections.Generic; + using System.Data.Entity; + + public class SimpleModelInitializer : DropCreateDatabaseIfModelChanges + { + protected override void Seed(SimpleModelContext context) + { + new List + { + new Product + { + Name = "Marmite", + CategoryId = "Foods" + }, + new Product + { + Name = "Bovril", + CategoryId = "Beverages" + }, + new Product + { + Name = "iSnack 2.0", + CategoryId = "Foods" + }, + new Product + { + Name = "Irn-Bru", + CategoryId = "Beverages" + }, + new Product + { + Name = "Ibuprofen", + CategoryId = "Medications" + }, + new Product + { + Name = "Strongbow", + CategoryId = "Medications" + }, + new FeaturedProduct + { + Name = "Cadillac", + CategoryId = "Cars", + PromotionalCode = "Ed Wood" + }, + }.ForEach(p => context.Products.Add(p)); + + new List + { + new Category + { + Id = "Beverages" + }, + new Category + { + Id = "Foods" + }, + new Category + { + Id = "Medications" + }, + new Category + { + Id = "Cars" + }, + }.ForEach(c => context.Categories.Add(c)); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/AbstractType1.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/AbstractType1.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/AbstractType1.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/AbstractType1.cs index f00ea750..7feb2419 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/AbstractType1.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/AbstractType1.cs @@ -1,13 +1,13 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - public abstract class AbstractType1 - { - public virtual int Property1_ID { get; set; } - - public virtual string Property2 { get; set; } - - public virtual string Property3 { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + public abstract class AbstractType1 + { + public virtual int Property1_ID { get; set; } + + public virtual string Property2 { get; set; } + + public virtual string Property3 { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/AbstractType1_1.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/AbstractType1_1.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/AbstractType1_1.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/AbstractType1_1.cs index a76157f2..c071f948 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/AbstractType1_1.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/AbstractType1_1.cs @@ -1,9 +1,9 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - public abstract class AbstractType1_1 : AbstractType1 - { - public virtual string Property4 { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + public abstract class AbstractType1_1 : AbstractType1 + { + public virtual string Property4 { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Address.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Address.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/Address.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Address.cs index 3a29ae7f..2a941728 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Address.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Address.cs @@ -1,356 +1,356 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class Address - { - public virtual int AddressID { get; set; } - - public virtual string AddressLine1 { get; set; } - - public virtual string AddressLine2 { get; set; } - - public virtual string City { get; set; } - - public virtual int StateProvinceID - { - get { return _stateProvinceID; } - set - { - if (_stateProvinceID != value) - { - if (StateProvince != null - && StateProvince.StateProvinceID != value) - { - StateProvince = null; - } - _stateProvinceID = value; - } - } - } - - private int _stateProvinceID; - - public virtual string PostalCode { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection EmployeeAddresses - { - get - { - if (_employeeAddresses == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupEmployeeAddresses; - _employeeAddresses = newCollection; - } - return _employeeAddresses; - } - set - { - if (!ReferenceEquals(_employeeAddresses, value)) - { - var previousValue = _employeeAddresses as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupEmployeeAddresses; - } - _employeeAddresses = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupEmployeeAddresses; - } - } - } - } - - private ICollection _employeeAddresses; - - public virtual StateProvince StateProvince - { - get { return _stateProvince; } - set - { - if (!ReferenceEquals(_stateProvince, value)) - { - var previousValue = _stateProvince; - _stateProvince = value; - FixupStateProvince(previousValue); - } - } - } - - private StateProvince _stateProvince; - - public virtual ICollection CustomerAddresses - { - get - { - if (_customerAddresses == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupCustomerAddresses; - _customerAddresses = newCollection; - } - return _customerAddresses; - } - set - { - if (!ReferenceEquals(_customerAddresses, value)) - { - var previousValue = _customerAddresses as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupCustomerAddresses; - } - _customerAddresses = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupCustomerAddresses; - } - } - } - } - - private ICollection _customerAddresses; - - public virtual ICollection SalesOrderHeaders - { - get - { - if (_salesOrderHeaders == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesOrderHeaders; - _salesOrderHeaders = newCollection; - } - return _salesOrderHeaders; - } - set - { - if (!ReferenceEquals(_salesOrderHeaders, value)) - { - var previousValue = _salesOrderHeaders as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesOrderHeaders; - } - _salesOrderHeaders = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesOrderHeaders; - } - } - } - } - - private ICollection _salesOrderHeaders; - - public virtual ICollection SalesOrderHeaders1 - { - get - { - if (_salesOrderHeaders1 == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesOrderHeaders1; - _salesOrderHeaders1 = newCollection; - } - return _salesOrderHeaders1; - } - set - { - if (!ReferenceEquals(_salesOrderHeaders1, value)) - { - var previousValue = _salesOrderHeaders1 as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesOrderHeaders1; - } - _salesOrderHeaders1 = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesOrderHeaders1; - } - } - } - } - - private ICollection _salesOrderHeaders1; - - public virtual ICollection VendorAddresses - { - get - { - if (_vendorAddresses == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupVendorAddresses; - _vendorAddresses = newCollection; - } - return _vendorAddresses; - } - set - { - if (!ReferenceEquals(_vendorAddresses, value)) - { - var previousValue = _vendorAddresses as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupVendorAddresses; - } - _vendorAddresses = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupVendorAddresses; - } - } - } - } - - private ICollection _vendorAddresses; - - private void FixupStateProvince(StateProvince previousValue) - { - if (previousValue != null - && previousValue.Addresses.Contains(this)) - { - previousValue.Addresses.Remove(this); - } - - if (StateProvince != null) - { - if (!StateProvince.Addresses.Contains(this)) - { - StateProvince.Addresses.Add(this); - } - if (StateProvinceID != StateProvince.StateProvinceID) - { - StateProvinceID = StateProvince.StateProvinceID; - } - } - } - - private void FixupEmployeeAddresses(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (EmployeeAddress item in e.NewItems) - { - item.Address = this; - } - } - - if (e.OldItems != null) - { - foreach (EmployeeAddress item in e.OldItems) - { - if (ReferenceEquals(item.Address, this)) - { - item.Address = null; - } - } - } - } - - private void FixupCustomerAddresses(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (CustomerAddress item in e.NewItems) - { - item.Address = this; - } - } - - if (e.OldItems != null) - { - foreach (CustomerAddress item in e.OldItems) - { - if (ReferenceEquals(item.Address, this)) - { - item.Address = null; - } - } - } - } - - private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesOrderHeader item in e.NewItems) - { - item.Address = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesOrderHeader item in e.OldItems) - { - if (ReferenceEquals(item.Address, this)) - { - item.Address = null; - } - } - } - } - - private void FixupSalesOrderHeaders1(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesOrderHeader item in e.NewItems) - { - item.Address1 = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesOrderHeader item in e.OldItems) - { - if (ReferenceEquals(item.Address1, this)) - { - item.Address1 = null; - } - } - } - } - - private void FixupVendorAddresses(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (VendorAddress item in e.NewItems) - { - item.Address = this; - } - } - - if (e.OldItems != null) - { - foreach (VendorAddress item in e.OldItems) - { - if (ReferenceEquals(item.Address, this)) - { - item.Address = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class Address + { + public virtual int AddressID { get; set; } + + public virtual string AddressLine1 { get; set; } + + public virtual string AddressLine2 { get; set; } + + public virtual string City { get; set; } + + public virtual int StateProvinceID + { + get { return _stateProvinceID; } + set + { + if (_stateProvinceID != value) + { + if (StateProvince != null + && StateProvince.StateProvinceID != value) + { + StateProvince = null; + } + _stateProvinceID = value; + } + } + } + + private int _stateProvinceID; + + public virtual string PostalCode { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection EmployeeAddresses + { + get + { + if (_employeeAddresses == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupEmployeeAddresses; + _employeeAddresses = newCollection; + } + return _employeeAddresses; + } + set + { + if (!ReferenceEquals(_employeeAddresses, value)) + { + var previousValue = _employeeAddresses as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupEmployeeAddresses; + } + _employeeAddresses = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupEmployeeAddresses; + } + } + } + } + + private ICollection _employeeAddresses; + + public virtual StateProvince StateProvince + { + get { return _stateProvince; } + set + { + if (!ReferenceEquals(_stateProvince, value)) + { + var previousValue = _stateProvince; + _stateProvince = value; + FixupStateProvince(previousValue); + } + } + } + + private StateProvince _stateProvince; + + public virtual ICollection CustomerAddresses + { + get + { + if (_customerAddresses == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupCustomerAddresses; + _customerAddresses = newCollection; + } + return _customerAddresses; + } + set + { + if (!ReferenceEquals(_customerAddresses, value)) + { + var previousValue = _customerAddresses as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupCustomerAddresses; + } + _customerAddresses = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupCustomerAddresses; + } + } + } + } + + private ICollection _customerAddresses; + + public virtual ICollection SalesOrderHeaders + { + get + { + if (_salesOrderHeaders == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesOrderHeaders; + _salesOrderHeaders = newCollection; + } + return _salesOrderHeaders; + } + set + { + if (!ReferenceEquals(_salesOrderHeaders, value)) + { + var previousValue = _salesOrderHeaders as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesOrderHeaders; + } + _salesOrderHeaders = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesOrderHeaders; + } + } + } + } + + private ICollection _salesOrderHeaders; + + public virtual ICollection SalesOrderHeaders1 + { + get + { + if (_salesOrderHeaders1 == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesOrderHeaders1; + _salesOrderHeaders1 = newCollection; + } + return _salesOrderHeaders1; + } + set + { + if (!ReferenceEquals(_salesOrderHeaders1, value)) + { + var previousValue = _salesOrderHeaders1 as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesOrderHeaders1; + } + _salesOrderHeaders1 = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesOrderHeaders1; + } + } + } + } + + private ICollection _salesOrderHeaders1; + + public virtual ICollection VendorAddresses + { + get + { + if (_vendorAddresses == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupVendorAddresses; + _vendorAddresses = newCollection; + } + return _vendorAddresses; + } + set + { + if (!ReferenceEquals(_vendorAddresses, value)) + { + var previousValue = _vendorAddresses as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupVendorAddresses; + } + _vendorAddresses = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupVendorAddresses; + } + } + } + } + + private ICollection _vendorAddresses; + + private void FixupStateProvince(StateProvince previousValue) + { + if (previousValue != null + && previousValue.Addresses.Contains(this)) + { + previousValue.Addresses.Remove(this); + } + + if (StateProvince != null) + { + if (!StateProvince.Addresses.Contains(this)) + { + StateProvince.Addresses.Add(this); + } + if (StateProvinceID != StateProvince.StateProvinceID) + { + StateProvinceID = StateProvince.StateProvinceID; + } + } + } + + private void FixupEmployeeAddresses(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (EmployeeAddress item in e.NewItems) + { + item.Address = this; + } + } + + if (e.OldItems != null) + { + foreach (EmployeeAddress item in e.OldItems) + { + if (ReferenceEquals(item.Address, this)) + { + item.Address = null; + } + } + } + } + + private void FixupCustomerAddresses(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (CustomerAddress item in e.NewItems) + { + item.Address = this; + } + } + + if (e.OldItems != null) + { + foreach (CustomerAddress item in e.OldItems) + { + if (ReferenceEquals(item.Address, this)) + { + item.Address = null; + } + } + } + } + + private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesOrderHeader item in e.NewItems) + { + item.Address = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesOrderHeader item in e.OldItems) + { + if (ReferenceEquals(item.Address, this)) + { + item.Address = null; + } + } + } + } + + private void FixupSalesOrderHeaders1(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesOrderHeader item in e.NewItems) + { + item.Address1 = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesOrderHeader item in e.OldItems) + { + if (ReferenceEquals(item.Address1, this)) + { + item.Address1 = null; + } + } + } + } + + private void FixupVendorAddresses(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (VendorAddress item in e.NewItems) + { + item.Address = this; + } + } + + if (e.OldItems != null) + { + foreach (VendorAddress item in e.OldItems) + { + if (ReferenceEquals(item.Address, this)) + { + item.Address = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/AddressType.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/AddressType.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/AddressType.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/AddressType.cs index 4551826c..9814b71b 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/AddressType.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/AddressType.cs @@ -1,129 +1,129 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class AddressType - { - public virtual int AddressTypeID { get; set; } - - public virtual string Name { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection CustomerAddresses - { - get - { - if (_customerAddresses == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupCustomerAddresses; - _customerAddresses = newCollection; - } - return _customerAddresses; - } - set - { - if (!ReferenceEquals(_customerAddresses, value)) - { - var previousValue = _customerAddresses as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupCustomerAddresses; - } - _customerAddresses = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupCustomerAddresses; - } - } - } - } - - private ICollection _customerAddresses; - - public virtual ICollection VendorAddresses - { - get - { - if (_vendorAddresses == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupVendorAddresses; - _vendorAddresses = newCollection; - } - return _vendorAddresses; - } - set - { - if (!ReferenceEquals(_vendorAddresses, value)) - { - var previousValue = _vendorAddresses as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupVendorAddresses; - } - _vendorAddresses = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupVendorAddresses; - } - } - } - } - - private ICollection _vendorAddresses; - - private void FixupCustomerAddresses(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (CustomerAddress item in e.NewItems) - { - item.AddressType = this; - } - } - - if (e.OldItems != null) - { - foreach (CustomerAddress item in e.OldItems) - { - if (ReferenceEquals(item.AddressType, this)) - { - item.AddressType = null; - } - } - } - } - - private void FixupVendorAddresses(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (VendorAddress item in e.NewItems) - { - item.AddressType = this; - } - } - - if (e.OldItems != null) - { - foreach (VendorAddress item in e.OldItems) - { - if (ReferenceEquals(item.AddressType, this)) - { - item.AddressType = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class AddressType + { + public virtual int AddressTypeID { get; set; } + + public virtual string Name { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection CustomerAddresses + { + get + { + if (_customerAddresses == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupCustomerAddresses; + _customerAddresses = newCollection; + } + return _customerAddresses; + } + set + { + if (!ReferenceEquals(_customerAddresses, value)) + { + var previousValue = _customerAddresses as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupCustomerAddresses; + } + _customerAddresses = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupCustomerAddresses; + } + } + } + } + + private ICollection _customerAddresses; + + public virtual ICollection VendorAddresses + { + get + { + if (_vendorAddresses == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupVendorAddresses; + _vendorAddresses = newCollection; + } + return _vendorAddresses; + } + set + { + if (!ReferenceEquals(_vendorAddresses, value)) + { + var previousValue = _vendorAddresses as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupVendorAddresses; + } + _vendorAddresses = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupVendorAddresses; + } + } + } + } + + private ICollection _vendorAddresses; + + private void FixupCustomerAddresses(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (CustomerAddress item in e.NewItems) + { + item.AddressType = this; + } + } + + if (e.OldItems != null) + { + foreach (CustomerAddress item in e.OldItems) + { + if (ReferenceEquals(item.AddressType, this)) + { + item.AddressType = null; + } + } + } + } + + private void FixupVendorAddresses(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (VendorAddress item in e.NewItems) + { + item.AddressType = this; + } + } + + if (e.OldItems != null) + { + foreach (VendorAddress item in e.OldItems) + { + if (ReferenceEquals(item.AddressType, this)) + { + item.AddressType = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/BillOfMaterials.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/BillOfMaterials.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/BillOfMaterials.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/BillOfMaterials.cs index 6275d7a6..7e5622a5 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/BillOfMaterials.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/BillOfMaterials.cs @@ -1,184 +1,184 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class BillOfMaterials - { - public virtual int BillOfMaterialsID { get; set; } - - public virtual int? ProductAssemblyID - { - get { return _productAssemblyID; } - set - { - try - { - _settingFK = true; - if (_productAssemblyID != value) - { - if (Product1 != null - && Product1.ProductID != value) - { - Product1 = null; - } - _productAssemblyID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int? _productAssemblyID; - - public virtual int ComponentID - { - get { return _componentID; } - set - { - try - { - _settingFK = true; - if (_componentID != value) - { - if (Product != null - && Product.ProductID != value) - { - Product = null; - } - _componentID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int _componentID; - - public virtual DateTime StartDate { get; set; } - - public virtual DateTime? EndDate { get; set; } - - public virtual string UnitMeasureCode - { - get { return _unitMeasureCode; } - set - { - try - { - _settingFK = true; - if (_unitMeasureCode != value) - { - if (UnitMeasure != null - && UnitMeasure.UnitMeasureCode != value) - { - UnitMeasure = null; - } - _unitMeasureCode = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private string _unitMeasureCode; - - public virtual short BOMLevel { get; set; } - - public virtual decimal PerAssemblyQty { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Product Product - { - get { return _product; } - set - { - if (!ReferenceEquals(_product, value)) - { - var previousValue = _product; - _product = value; - FixupProduct(previousValue); - } - } - } - - private Product _product; - - public virtual Product Product1 - { - get { return _product1; } - set - { - if (!ReferenceEquals(_product1, value)) - { - var previousValue = _product1; - _product1 = value; - FixupProduct1(previousValue); - } - } - } - - private Product _product1; - - public virtual UnitMeasure UnitMeasure { get; set; } - - private bool _settingFK; - - private void FixupProduct(Product previousValue) - { - if (previousValue != null - && previousValue.BillOfMaterials.Contains(this)) - { - previousValue.BillOfMaterials.Remove(this); - } - - if (Product != null) - { - if (!Product.BillOfMaterials.Contains(this)) - { - Product.BillOfMaterials.Add(this); - } - if (ComponentID != Product.ProductID) - { - ComponentID = Product.ProductID; - } - } - } - - private void FixupProduct1(Product previousValue) - { - if (previousValue != null - && previousValue.BillOfMaterials1.Contains(this)) - { - previousValue.BillOfMaterials1.Remove(this); - } - - if (Product1 != null) - { - if (!Product1.BillOfMaterials1.Contains(this)) - { - Product1.BillOfMaterials1.Add(this); - } - if (ProductAssemblyID != Product1.ProductID) - { - ProductAssemblyID = Product1.ProductID; - } - } - else if (!_settingFK) - { - ProductAssemblyID = null; - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class BillOfMaterials + { + public virtual int BillOfMaterialsID { get; set; } + + public virtual int? ProductAssemblyID + { + get { return _productAssemblyID; } + set + { + try + { + _settingFK = true; + if (_productAssemblyID != value) + { + if (Product1 != null + && Product1.ProductID != value) + { + Product1 = null; + } + _productAssemblyID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int? _productAssemblyID; + + public virtual int ComponentID + { + get { return _componentID; } + set + { + try + { + _settingFK = true; + if (_componentID != value) + { + if (Product != null + && Product.ProductID != value) + { + Product = null; + } + _componentID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int _componentID; + + public virtual DateTime StartDate { get; set; } + + public virtual DateTime? EndDate { get; set; } + + public virtual string UnitMeasureCode + { + get { return _unitMeasureCode; } + set + { + try + { + _settingFK = true; + if (_unitMeasureCode != value) + { + if (UnitMeasure != null + && UnitMeasure.UnitMeasureCode != value) + { + UnitMeasure = null; + } + _unitMeasureCode = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private string _unitMeasureCode; + + public virtual short BOMLevel { get; set; } + + public virtual decimal PerAssemblyQty { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Product Product + { + get { return _product; } + set + { + if (!ReferenceEquals(_product, value)) + { + var previousValue = _product; + _product = value; + FixupProduct(previousValue); + } + } + } + + private Product _product; + + public virtual Product Product1 + { + get { return _product1; } + set + { + if (!ReferenceEquals(_product1, value)) + { + var previousValue = _product1; + _product1 = value; + FixupProduct1(previousValue); + } + } + } + + private Product _product1; + + public virtual UnitMeasure UnitMeasure { get; set; } + + private bool _settingFK; + + private void FixupProduct(Product previousValue) + { + if (previousValue != null + && previousValue.BillOfMaterials.Contains(this)) + { + previousValue.BillOfMaterials.Remove(this); + } + + if (Product != null) + { + if (!Product.BillOfMaterials.Contains(this)) + { + Product.BillOfMaterials.Add(this); + } + if (ComponentID != Product.ProductID) + { + ComponentID = Product.ProductID; + } + } + } + + private void FixupProduct1(Product previousValue) + { + if (previousValue != null + && previousValue.BillOfMaterials1.Contains(this)) + { + previousValue.BillOfMaterials1.Remove(this); + } + + if (Product1 != null) + { + if (!Product1.BillOfMaterials1.Contains(this)) + { + Product1.BillOfMaterials1.Add(this); + } + if (ProductAssemblyID != Product1.ProductID) + { + ProductAssemblyID = Product1.ProductID; + } + } + else if (!_settingFK) + { + ProductAssemblyID = null; + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ColoredProduct.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ColoredProduct.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ColoredProduct.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ColoredProduct.cs index ba722507..f43a0fba 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ColoredProduct.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ColoredProduct.cs @@ -1,9 +1,9 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - public class ColoredProduct : StyledProduct - { - public virtual string Color { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + public class ColoredProduct : StyledProduct + { + public virtual string Color { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ConcreteType1_1_1.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ConcreteType1_1_1.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ConcreteType1_1_1.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ConcreteType1_1_1.cs index 12b261aa..be1cc63e 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ConcreteType1_1_1.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ConcreteType1_1_1.cs @@ -1,9 +1,9 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - public class ConcreteType1_1_1 : AbstractType1_1 - { - public virtual string Property5 { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + public class ConcreteType1_1_1 : AbstractType1_1 + { + public virtual string Property5 { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ConcreteType1_2.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ConcreteType1_2.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ConcreteType1_2.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ConcreteType1_2.cs index 33bef3f2..7dfcbf82 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ConcreteType1_2.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ConcreteType1_2.cs @@ -1,9 +1,9 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - public class ConcreteType1_2 : AbstractType1 - { - public virtual string Property4 { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + public class ConcreteType1_2 : AbstractType1 + { + public virtual string Property4 { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Contact.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Contact.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/Contact.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Contact.cs index a4fd7bd5..177de001 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Contact.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Contact.cs @@ -1,368 +1,368 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System.Collections.Generic; - using System.Collections.Specialized; - - public class Contact - { - public virtual int ContactID { get; set; } - - public virtual bool NameStyle { get; set; } - - public virtual string Title { get; set; } - - public virtual string FirstName { get; set; } - - public virtual string MiddleName { get; set; } - - public virtual string LastName { get; set; } - - public virtual string Suffix { get; set; } - - public virtual string EmailAddress { get; set; } - - public virtual int EmailPromotion { get; set; } - - public virtual string Phone { get; set; } - - public virtual string PasswordHash { get; set; } - - public virtual string PasswordSalt { get; set; } - - public virtual string AdditionalContactInfo { get; set; } - - public virtual RowDetails RowDetails { get; set; } - - public virtual ICollection Employees - { - get - { - if (_employees == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupEmployees; - _employees = newCollection; - } - return _employees; - } - set - { - if (!ReferenceEquals(_employees, value)) - { - var previousValue = _employees as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupEmployees; - } - _employees = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupEmployees; - } - } - } - } - - private ICollection _employees; - - public virtual ICollection ContactCreditCards - { - get - { - if (_contactCreditCards == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupContactCreditCards; - _contactCreditCards = newCollection; - } - return _contactCreditCards; - } - set - { - if (!ReferenceEquals(_contactCreditCards, value)) - { - var previousValue = _contactCreditCards as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupContactCreditCards; - } - _contactCreditCards = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupContactCreditCards; - } - } - } - } - - private ICollection _contactCreditCards; - - public virtual ICollection Individuals - { - get - { - if (_individuals == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupIndividuals; - _individuals = newCollection; - } - return _individuals; - } - set - { - if (!ReferenceEquals(_individuals, value)) - { - var previousValue = _individuals as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupIndividuals; - } - _individuals = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupIndividuals; - } - } - } - } - - private ICollection _individuals; - - public virtual ICollection SalesOrderHeaders - { - get - { - if (_salesOrderHeaders == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesOrderHeaders; - _salesOrderHeaders = newCollection; - } - return _salesOrderHeaders; - } - set - { - if (!ReferenceEquals(_salesOrderHeaders, value)) - { - var previousValue = _salesOrderHeaders as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesOrderHeaders; - } - _salesOrderHeaders = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesOrderHeaders; - } - } - } - } - - private ICollection _salesOrderHeaders; - - public virtual ICollection StoreContacts - { - get - { - if (_storeContacts == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupStoreContacts; - _storeContacts = newCollection; - } - return _storeContacts; - } - set - { - if (!ReferenceEquals(_storeContacts, value)) - { - var previousValue = _storeContacts as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupStoreContacts; - } - _storeContacts = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupStoreContacts; - } - } - } - } - - private ICollection _storeContacts; - - public virtual ICollection VendorContacts - { - get - { - if (_vendorContacts == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupVendorContacts; - _vendorContacts = newCollection; - } - return _vendorContacts; - } - set - { - if (!ReferenceEquals(_vendorContacts, value)) - { - var previousValue = _vendorContacts as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupVendorContacts; - } - _vendorContacts = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupVendorContacts; - } - } - } - } - - private ICollection _vendorContacts; - - private void FixupEmployees(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (Employee item in e.NewItems) - { - item.Contact = this; - } - } - - if (e.OldItems != null) - { - foreach (Employee item in e.OldItems) - { - if (ReferenceEquals(item.Contact, this)) - { - item.Contact = null; - } - } - } - } - - private void FixupContactCreditCards(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ContactCreditCard item in e.NewItems) - { - item.Contact = this; - } - } - - if (e.OldItems != null) - { - foreach (ContactCreditCard item in e.OldItems) - { - if (ReferenceEquals(item.Contact, this)) - { - item.Contact = null; - } - } - } - } - - private void FixupIndividuals(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (Individual item in e.NewItems) - { - item.Contact = this; - } - } - - if (e.OldItems != null) - { - foreach (Individual item in e.OldItems) - { - if (ReferenceEquals(item.Contact, this)) - { - item.Contact = null; - } - } - } - } - - private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesOrderHeader item in e.NewItems) - { - item.Contact = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesOrderHeader item in e.OldItems) - { - if (ReferenceEquals(item.Contact, this)) - { - item.Contact = null; - } - } - } - } - - private void FixupStoreContacts(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (StoreContact item in e.NewItems) - { - item.Contact = this; - } - } - - if (e.OldItems != null) - { - foreach (StoreContact item in e.OldItems) - { - if (ReferenceEquals(item.Contact, this)) - { - item.Contact = null; - } - } - } - } - - private void FixupVendorContacts(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (VendorContact item in e.NewItems) - { - item.Contact = this; - } - } - - if (e.OldItems != null) - { - foreach (VendorContact item in e.OldItems) - { - if (ReferenceEquals(item.Contact, this)) - { - item.Contact = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System.Collections.Generic; + using System.Collections.Specialized; + + public class Contact + { + public virtual int ContactID { get; set; } + + public virtual bool NameStyle { get; set; } + + public virtual string Title { get; set; } + + public virtual string FirstName { get; set; } + + public virtual string MiddleName { get; set; } + + public virtual string LastName { get; set; } + + public virtual string Suffix { get; set; } + + public virtual string EmailAddress { get; set; } + + public virtual int EmailPromotion { get; set; } + + public virtual string Phone { get; set; } + + public virtual string PasswordHash { get; set; } + + public virtual string PasswordSalt { get; set; } + + public virtual string AdditionalContactInfo { get; set; } + + public virtual RowDetails RowDetails { get; set; } + + public virtual ICollection Employees + { + get + { + if (_employees == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupEmployees; + _employees = newCollection; + } + return _employees; + } + set + { + if (!ReferenceEquals(_employees, value)) + { + var previousValue = _employees as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupEmployees; + } + _employees = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupEmployees; + } + } + } + } + + private ICollection _employees; + + public virtual ICollection ContactCreditCards + { + get + { + if (_contactCreditCards == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupContactCreditCards; + _contactCreditCards = newCollection; + } + return _contactCreditCards; + } + set + { + if (!ReferenceEquals(_contactCreditCards, value)) + { + var previousValue = _contactCreditCards as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupContactCreditCards; + } + _contactCreditCards = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupContactCreditCards; + } + } + } + } + + private ICollection _contactCreditCards; + + public virtual ICollection Individuals + { + get + { + if (_individuals == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupIndividuals; + _individuals = newCollection; + } + return _individuals; + } + set + { + if (!ReferenceEquals(_individuals, value)) + { + var previousValue = _individuals as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupIndividuals; + } + _individuals = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupIndividuals; + } + } + } + } + + private ICollection _individuals; + + public virtual ICollection SalesOrderHeaders + { + get + { + if (_salesOrderHeaders == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesOrderHeaders; + _salesOrderHeaders = newCollection; + } + return _salesOrderHeaders; + } + set + { + if (!ReferenceEquals(_salesOrderHeaders, value)) + { + var previousValue = _salesOrderHeaders as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesOrderHeaders; + } + _salesOrderHeaders = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesOrderHeaders; + } + } + } + } + + private ICollection _salesOrderHeaders; + + public virtual ICollection StoreContacts + { + get + { + if (_storeContacts == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupStoreContacts; + _storeContacts = newCollection; + } + return _storeContacts; + } + set + { + if (!ReferenceEquals(_storeContacts, value)) + { + var previousValue = _storeContacts as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupStoreContacts; + } + _storeContacts = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupStoreContacts; + } + } + } + } + + private ICollection _storeContacts; + + public virtual ICollection VendorContacts + { + get + { + if (_vendorContacts == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupVendorContacts; + _vendorContacts = newCollection; + } + return _vendorContacts; + } + set + { + if (!ReferenceEquals(_vendorContacts, value)) + { + var previousValue = _vendorContacts as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupVendorContacts; + } + _vendorContacts = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupVendorContacts; + } + } + } + } + + private ICollection _vendorContacts; + + private void FixupEmployees(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (Employee item in e.NewItems) + { + item.Contact = this; + } + } + + if (e.OldItems != null) + { + foreach (Employee item in e.OldItems) + { + if (ReferenceEquals(item.Contact, this)) + { + item.Contact = null; + } + } + } + } + + private void FixupContactCreditCards(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ContactCreditCard item in e.NewItems) + { + item.Contact = this; + } + } + + if (e.OldItems != null) + { + foreach (ContactCreditCard item in e.OldItems) + { + if (ReferenceEquals(item.Contact, this)) + { + item.Contact = null; + } + } + } + } + + private void FixupIndividuals(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (Individual item in e.NewItems) + { + item.Contact = this; + } + } + + if (e.OldItems != null) + { + foreach (Individual item in e.OldItems) + { + if (ReferenceEquals(item.Contact, this)) + { + item.Contact = null; + } + } + } + } + + private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesOrderHeader item in e.NewItems) + { + item.Contact = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesOrderHeader item in e.OldItems) + { + if (ReferenceEquals(item.Contact, this)) + { + item.Contact = null; + } + } + } + } + + private void FixupStoreContacts(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (StoreContact item in e.NewItems) + { + item.Contact = this; + } + } + + if (e.OldItems != null) + { + foreach (StoreContact item in e.OldItems) + { + if (ReferenceEquals(item.Contact, this)) + { + item.Contact = null; + } + } + } + } + + private void FixupVendorContacts(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (VendorContact item in e.NewItems) + { + item.Contact = this; + } + } + + if (e.OldItems != null) + { + foreach (VendorContact item in e.OldItems) + { + if (ReferenceEquals(item.Contact, this)) + { + item.Contact = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ContactCreditCard.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ContactCreditCard.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ContactCreditCard.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ContactCreditCard.cs index acd37ca9..4ee2608d 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ContactCreditCard.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ContactCreditCard.cs @@ -1,123 +1,123 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class ContactCreditCard - { - public virtual int ContactID - { - get { return _contactID; } - set - { - if (_contactID != value) - { - if (Contact != null - && Contact.ContactID != value) - { - Contact = null; - } - _contactID = value; - } - } - } - - private int _contactID; - - public virtual int CreditCardID - { - get { return _creditCardID; } - set - { - if (_creditCardID != value) - { - if (CreditCard != null - && CreditCard.CreditCardID != value) - { - CreditCard = null; - } - _creditCardID = value; - } - } - } - - private int _creditCardID; - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Contact Contact - { - get { return _contact; } - set - { - if (!ReferenceEquals(_contact, value)) - { - var previousValue = _contact; - _contact = value; - FixupContact(previousValue); - } - } - } - - private Contact _contact; - - public virtual CreditCard CreditCard - { - get { return _creditCard; } - set - { - if (!ReferenceEquals(_creditCard, value)) - { - var previousValue = _creditCard; - _creditCard = value; - FixupCreditCard(previousValue); - } - } - } - - private CreditCard _creditCard; - - private void FixupContact(Contact previousValue) - { - if (previousValue != null - && previousValue.ContactCreditCards.Contains(this)) - { - previousValue.ContactCreditCards.Remove(this); - } - - if (Contact != null) - { - if (!Contact.ContactCreditCards.Contains(this)) - { - Contact.ContactCreditCards.Add(this); - } - if (ContactID != Contact.ContactID) - { - ContactID = Contact.ContactID; - } - } - } - - private void FixupCreditCard(CreditCard previousValue) - { - if (previousValue != null - && previousValue.ContactCreditCards.Contains(this)) - { - previousValue.ContactCreditCards.Remove(this); - } - - if (CreditCard != null) - { - if (!CreditCard.ContactCreditCards.Contains(this)) - { - CreditCard.ContactCreditCards.Add(this); - } - if (CreditCardID != CreditCard.CreditCardID) - { - CreditCardID = CreditCard.CreditCardID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class ContactCreditCard + { + public virtual int ContactID + { + get { return _contactID; } + set + { + if (_contactID != value) + { + if (Contact != null + && Contact.ContactID != value) + { + Contact = null; + } + _contactID = value; + } + } + } + + private int _contactID; + + public virtual int CreditCardID + { + get { return _creditCardID; } + set + { + if (_creditCardID != value) + { + if (CreditCard != null + && CreditCard.CreditCardID != value) + { + CreditCard = null; + } + _creditCardID = value; + } + } + } + + private int _creditCardID; + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Contact Contact + { + get { return _contact; } + set + { + if (!ReferenceEquals(_contact, value)) + { + var previousValue = _contact; + _contact = value; + FixupContact(previousValue); + } + } + } + + private Contact _contact; + + public virtual CreditCard CreditCard + { + get { return _creditCard; } + set + { + if (!ReferenceEquals(_creditCard, value)) + { + var previousValue = _creditCard; + _creditCard = value; + FixupCreditCard(previousValue); + } + } + } + + private CreditCard _creditCard; + + private void FixupContact(Contact previousValue) + { + if (previousValue != null + && previousValue.ContactCreditCards.Contains(this)) + { + previousValue.ContactCreditCards.Remove(this); + } + + if (Contact != null) + { + if (!Contact.ContactCreditCards.Contains(this)) + { + Contact.ContactCreditCards.Add(this); + } + if (ContactID != Contact.ContactID) + { + ContactID = Contact.ContactID; + } + } + } + + private void FixupCreditCard(CreditCard previousValue) + { + if (previousValue != null + && previousValue.ContactCreditCards.Contains(this)) + { + previousValue.ContactCreditCards.Remove(this); + } + + if (CreditCard != null) + { + if (!CreditCard.ContactCreditCards.Contains(this)) + { + CreditCard.ContactCreditCards.Add(this); + } + if (CreditCardID != CreditCard.CreditCardID) + { + CreditCardID = CreditCard.CreditCardID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ContactType.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ContactType.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ContactType.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ContactType.cs index 5c90c629..9a18e535 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ContactType.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ContactType.cs @@ -1,127 +1,127 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class ContactType - { - public virtual int ContactTypeID { get; set; } - - public virtual string Name { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection StoreContacts - { - get - { - if (_storeContacts == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupStoreContacts; - _storeContacts = newCollection; - } - return _storeContacts; - } - set - { - if (!ReferenceEquals(_storeContacts, value)) - { - var previousValue = _storeContacts as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupStoreContacts; - } - _storeContacts = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupStoreContacts; - } - } - } - } - - private ICollection _storeContacts; - - public virtual ICollection VendorContacts - { - get - { - if (_vendorContacts == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupVendorContacts; - _vendorContacts = newCollection; - } - return _vendorContacts; - } - set - { - if (!ReferenceEquals(_vendorContacts, value)) - { - var previousValue = _vendorContacts as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupVendorContacts; - } - _vendorContacts = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupVendorContacts; - } - } - } - } - - private ICollection _vendorContacts; - - private void FixupStoreContacts(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (StoreContact item in e.NewItems) - { - item.ContactType = this; - } - } - - if (e.OldItems != null) - { - foreach (StoreContact item in e.OldItems) - { - if (ReferenceEquals(item.ContactType, this)) - { - item.ContactType = null; - } - } - } - } - - private void FixupVendorContacts(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (VendorContact item in e.NewItems) - { - item.ContactType = this; - } - } - - if (e.OldItems != null) - { - foreach (VendorContact item in e.OldItems) - { - if (ReferenceEquals(item.ContactType, this)) - { - item.ContactType = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class ContactType + { + public virtual int ContactTypeID { get; set; } + + public virtual string Name { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection StoreContacts + { + get + { + if (_storeContacts == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupStoreContacts; + _storeContacts = newCollection; + } + return _storeContacts; + } + set + { + if (!ReferenceEquals(_storeContacts, value)) + { + var previousValue = _storeContacts as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupStoreContacts; + } + _storeContacts = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupStoreContacts; + } + } + } + } + + private ICollection _storeContacts; + + public virtual ICollection VendorContacts + { + get + { + if (_vendorContacts == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupVendorContacts; + _vendorContacts = newCollection; + } + return _vendorContacts; + } + set + { + if (!ReferenceEquals(_vendorContacts, value)) + { + var previousValue = _vendorContacts as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupVendorContacts; + } + _vendorContacts = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupVendorContacts; + } + } + } + } + + private ICollection _vendorContacts; + + private void FixupStoreContacts(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (StoreContact item in e.NewItems) + { + item.ContactType = this; + } + } + + if (e.OldItems != null) + { + foreach (StoreContact item in e.OldItems) + { + if (ReferenceEquals(item.ContactType, this)) + { + item.ContactType = null; + } + } + } + } + + private void FixupVendorContacts(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (VendorContact item in e.NewItems) + { + item.ContactType = this; + } + } + + if (e.OldItems != null) + { + foreach (VendorContact item in e.OldItems) + { + if (ReferenceEquals(item.ContactType, this)) + { + item.ContactType = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/CountryRegion.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CountryRegion.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/CountryRegion.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CountryRegion.cs index 31c609c0..947231b3 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/CountryRegion.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CountryRegion.cs @@ -1,127 +1,127 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class CountryRegion - { - public virtual string CountryRegionCode { get; set; } - - public virtual string Name { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection CountryRegionCurrencies - { - get - { - if (_countryRegionCurrencies == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupCountryRegionCurrencies; - _countryRegionCurrencies = newCollection; - } - return _countryRegionCurrencies; - } - set - { - if (!ReferenceEquals(_countryRegionCurrencies, value)) - { - var previousValue = _countryRegionCurrencies as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupCountryRegionCurrencies; - } - _countryRegionCurrencies = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupCountryRegionCurrencies; - } - } - } - } - - private ICollection _countryRegionCurrencies; - - public virtual ICollection StateProvinces - { - get - { - if (_stateProvinces == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupStateProvinces; - _stateProvinces = newCollection; - } - return _stateProvinces; - } - set - { - if (!ReferenceEquals(_stateProvinces, value)) - { - var previousValue = _stateProvinces as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupStateProvinces; - } - _stateProvinces = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupStateProvinces; - } - } - } - } - - private ICollection _stateProvinces; - - private void FixupCountryRegionCurrencies(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (CountryRegionCurrency item in e.NewItems) - { - item.CountryRegion = this; - } - } - - if (e.OldItems != null) - { - foreach (CountryRegionCurrency item in e.OldItems) - { - if (ReferenceEquals(item.CountryRegion, this)) - { - item.CountryRegion = null; - } - } - } - } - - private void FixupStateProvinces(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (StateProvince item in e.NewItems) - { - item.CountryRegion = this; - } - } - - if (e.OldItems != null) - { - foreach (StateProvince item in e.OldItems) - { - if (ReferenceEquals(item.CountryRegion, this)) - { - item.CountryRegion = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class CountryRegion + { + public virtual string CountryRegionCode { get; set; } + + public virtual string Name { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection CountryRegionCurrencies + { + get + { + if (_countryRegionCurrencies == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupCountryRegionCurrencies; + _countryRegionCurrencies = newCollection; + } + return _countryRegionCurrencies; + } + set + { + if (!ReferenceEquals(_countryRegionCurrencies, value)) + { + var previousValue = _countryRegionCurrencies as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupCountryRegionCurrencies; + } + _countryRegionCurrencies = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupCountryRegionCurrencies; + } + } + } + } + + private ICollection _countryRegionCurrencies; + + public virtual ICollection StateProvinces + { + get + { + if (_stateProvinces == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupStateProvinces; + _stateProvinces = newCollection; + } + return _stateProvinces; + } + set + { + if (!ReferenceEquals(_stateProvinces, value)) + { + var previousValue = _stateProvinces as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupStateProvinces; + } + _stateProvinces = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupStateProvinces; + } + } + } + } + + private ICollection _stateProvinces; + + private void FixupCountryRegionCurrencies(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (CountryRegionCurrency item in e.NewItems) + { + item.CountryRegion = this; + } + } + + if (e.OldItems != null) + { + foreach (CountryRegionCurrency item in e.OldItems) + { + if (ReferenceEquals(item.CountryRegion, this)) + { + item.CountryRegion = null; + } + } + } + } + + private void FixupStateProvinces(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (StateProvince item in e.NewItems) + { + item.CountryRegion = this; + } + } + + if (e.OldItems != null) + { + foreach (StateProvince item in e.OldItems) + { + if (ReferenceEquals(item.CountryRegion, this)) + { + item.CountryRegion = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/CountryRegionCurrency.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CountryRegionCurrency.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/CountryRegionCurrency.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CountryRegionCurrency.cs index 7982c59b..ce1836ce 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/CountryRegionCurrency.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CountryRegionCurrency.cs @@ -1,123 +1,123 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class CountryRegionCurrency - { - public virtual string CountryRegionCode - { - get { return _countryRegionCode; } - set - { - if (_countryRegionCode != value) - { - if (CountryRegion != null - && CountryRegion.CountryRegionCode != value) - { - CountryRegion = null; - } - _countryRegionCode = value; - } - } - } - - private string _countryRegionCode; - - public virtual string CurrencyCode - { - get { return _currencyCode; } - set - { - if (_currencyCode != value) - { - if (Currency != null - && Currency.CurrencyCode != value) - { - Currency = null; - } - _currencyCode = value; - } - } - } - - private string _currencyCode; - - public virtual DateTime ModifiedDate { get; set; } - - public virtual CountryRegion CountryRegion - { - get { return _countryRegion; } - set - { - if (!ReferenceEquals(_countryRegion, value)) - { - var previousValue = _countryRegion; - _countryRegion = value; - FixupCountryRegion(previousValue); - } - } - } - - private CountryRegion _countryRegion; - - public virtual Currency Currency - { - get { return _currency; } - set - { - if (!ReferenceEquals(_currency, value)) - { - var previousValue = _currency; - _currency = value; - FixupCurrency(previousValue); - } - } - } - - private Currency _currency; - - private void FixupCountryRegion(CountryRegion previousValue) - { - if (previousValue != null - && previousValue.CountryRegionCurrencies.Contains(this)) - { - previousValue.CountryRegionCurrencies.Remove(this); - } - - if (CountryRegion != null) - { - if (!CountryRegion.CountryRegionCurrencies.Contains(this)) - { - CountryRegion.CountryRegionCurrencies.Add(this); - } - if (CountryRegionCode != CountryRegion.CountryRegionCode) - { - CountryRegionCode = CountryRegion.CountryRegionCode; - } - } - } - - private void FixupCurrency(Currency previousValue) - { - if (previousValue != null - && previousValue.CountryRegionCurrencies.Contains(this)) - { - previousValue.CountryRegionCurrencies.Remove(this); - } - - if (Currency != null) - { - if (!Currency.CountryRegionCurrencies.Contains(this)) - { - Currency.CountryRegionCurrencies.Add(this); - } - if (CurrencyCode != Currency.CurrencyCode) - { - CurrencyCode = Currency.CurrencyCode; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class CountryRegionCurrency + { + public virtual string CountryRegionCode + { + get { return _countryRegionCode; } + set + { + if (_countryRegionCode != value) + { + if (CountryRegion != null + && CountryRegion.CountryRegionCode != value) + { + CountryRegion = null; + } + _countryRegionCode = value; + } + } + } + + private string _countryRegionCode; + + public virtual string CurrencyCode + { + get { return _currencyCode; } + set + { + if (_currencyCode != value) + { + if (Currency != null + && Currency.CurrencyCode != value) + { + Currency = null; + } + _currencyCode = value; + } + } + } + + private string _currencyCode; + + public virtual DateTime ModifiedDate { get; set; } + + public virtual CountryRegion CountryRegion + { + get { return _countryRegion; } + set + { + if (!ReferenceEquals(_countryRegion, value)) + { + var previousValue = _countryRegion; + _countryRegion = value; + FixupCountryRegion(previousValue); + } + } + } + + private CountryRegion _countryRegion; + + public virtual Currency Currency + { + get { return _currency; } + set + { + if (!ReferenceEquals(_currency, value)) + { + var previousValue = _currency; + _currency = value; + FixupCurrency(previousValue); + } + } + } + + private Currency _currency; + + private void FixupCountryRegion(CountryRegion previousValue) + { + if (previousValue != null + && previousValue.CountryRegionCurrencies.Contains(this)) + { + previousValue.CountryRegionCurrencies.Remove(this); + } + + if (CountryRegion != null) + { + if (!CountryRegion.CountryRegionCurrencies.Contains(this)) + { + CountryRegion.CountryRegionCurrencies.Add(this); + } + if (CountryRegionCode != CountryRegion.CountryRegionCode) + { + CountryRegionCode = CountryRegion.CountryRegionCode; + } + } + } + + private void FixupCurrency(Currency previousValue) + { + if (previousValue != null + && previousValue.CountryRegionCurrencies.Contains(this)) + { + previousValue.CountryRegionCurrencies.Remove(this); + } + + if (Currency != null) + { + if (!Currency.CountryRegionCurrencies.Contains(this)) + { + Currency.CountryRegionCurrencies.Add(this); + } + if (CurrencyCode != Currency.CurrencyCode) + { + CurrencyCode = Currency.CurrencyCode; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/CreditCard.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CreditCard.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/CreditCard.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CreditCard.cs index 7db55a11..ee565c26 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/CreditCard.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CreditCard.cs @@ -1,142 +1,142 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - using System.Data.Entity.ModelConfiguration; - - public class CreditCard - { - public class CreditCardConfiguration : EntityTypeConfiguration - { - public CreditCardConfiguration() - { - Property(cc => cc.CardNumber); - } - } - - public virtual int CreditCardID { get; set; } - - public virtual string CardType { get; set; } - - private string CardNumber { get; set; } - - public virtual byte ExpMonth { get; set; } - - public virtual short ExpYear { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection ContactCreditCards - { - get - { - if (_contactCreditCards == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupContactCreditCards; - _contactCreditCards = newCollection; - } - return _contactCreditCards; - } - set - { - if (!ReferenceEquals(_contactCreditCards, value)) - { - var previousValue = _contactCreditCards as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupContactCreditCards; - } - _contactCreditCards = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupContactCreditCards; - } - } - } - } - - private ICollection _contactCreditCards; - - public virtual ICollection SalesOrderHeaders - { - get - { - if (_salesOrderHeaders == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesOrderHeaders; - _salesOrderHeaders = newCollection; - } - return _salesOrderHeaders; - } - set - { - if (!ReferenceEquals(_salesOrderHeaders, value)) - { - var previousValue = _salesOrderHeaders as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesOrderHeaders; - } - _salesOrderHeaders = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesOrderHeaders; - } - } - } - } - - private ICollection _salesOrderHeaders; - - private void FixupContactCreditCards(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ContactCreditCard item in e.NewItems) - { - item.CreditCard = this; - } - } - - if (e.OldItems != null) - { - foreach (ContactCreditCard item in e.OldItems) - { - if (ReferenceEquals(item.CreditCard, this)) - { - item.CreditCard = null; - } - } - } - } - - private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesOrderHeader item in e.NewItems) - { - item.CreditCard = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesOrderHeader item in e.OldItems) - { - if (ReferenceEquals(item.CreditCard, this)) - { - item.CreditCard = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + using System.Data.Entity.ModelConfiguration; + + public class CreditCard + { + public class CreditCardConfiguration : EntityTypeConfiguration + { + public CreditCardConfiguration() + { + Property(cc => cc.CardNumber); + } + } + + public virtual int CreditCardID { get; set; } + + public virtual string CardType { get; set; } + + private string CardNumber { get; set; } + + public virtual byte ExpMonth { get; set; } + + public virtual short ExpYear { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection ContactCreditCards + { + get + { + if (_contactCreditCards == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupContactCreditCards; + _contactCreditCards = newCollection; + } + return _contactCreditCards; + } + set + { + if (!ReferenceEquals(_contactCreditCards, value)) + { + var previousValue = _contactCreditCards as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupContactCreditCards; + } + _contactCreditCards = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupContactCreditCards; + } + } + } + } + + private ICollection _contactCreditCards; + + public virtual ICollection SalesOrderHeaders + { + get + { + if (_salesOrderHeaders == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesOrderHeaders; + _salesOrderHeaders = newCollection; + } + return _salesOrderHeaders; + } + set + { + if (!ReferenceEquals(_salesOrderHeaders, value)) + { + var previousValue = _salesOrderHeaders as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesOrderHeaders; + } + _salesOrderHeaders = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesOrderHeaders; + } + } + } + } + + private ICollection _salesOrderHeaders; + + private void FixupContactCreditCards(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ContactCreditCard item in e.NewItems) + { + item.CreditCard = this; + } + } + + if (e.OldItems != null) + { + foreach (ContactCreditCard item in e.OldItems) + { + if (ReferenceEquals(item.CreditCard, this)) + { + item.CreditCard = null; + } + } + } + } + + private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesOrderHeader item in e.NewItems) + { + item.CreditCard = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesOrderHeader item in e.OldItems) + { + if (ReferenceEquals(item.CreditCard, this)) + { + item.CreditCard = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Culture.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Culture.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/Culture.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Culture.cs index 7a910398..dce35ba0 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Culture.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Culture.cs @@ -1,72 +1,72 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class Culture - { - public virtual string CultureID { get; set; } - - public virtual string Name { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection ProductModelProductDescriptionCultures - { - get - { - if (_productModelProductDescriptionCultures == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductModelProductDescriptionCultures; - _productModelProductDescriptionCultures = newCollection; - } - return _productModelProductDescriptionCultures; - } - set - { - if (!ReferenceEquals(_productModelProductDescriptionCultures, value)) - { - var previousValue = _productModelProductDescriptionCultures as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductModelProductDescriptionCultures; - } - _productModelProductDescriptionCultures = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductModelProductDescriptionCultures; - } - } - } - } - - private ICollection _productModelProductDescriptionCultures; - - private void FixupProductModelProductDescriptionCultures(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductModelProductDescriptionCulture item in e.NewItems) - { - item.Culture = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductModelProductDescriptionCulture item in e.OldItems) - { - if (ReferenceEquals(item.Culture, this)) - { - item.Culture = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class Culture + { + public virtual string CultureID { get; set; } + + public virtual string Name { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection ProductModelProductDescriptionCultures + { + get + { + if (_productModelProductDescriptionCultures == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductModelProductDescriptionCultures; + _productModelProductDescriptionCultures = newCollection; + } + return _productModelProductDescriptionCultures; + } + set + { + if (!ReferenceEquals(_productModelProductDescriptionCultures, value)) + { + var previousValue = _productModelProductDescriptionCultures as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductModelProductDescriptionCultures; + } + _productModelProductDescriptionCultures = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductModelProductDescriptionCultures; + } + } + } + } + + private ICollection _productModelProductDescriptionCultures; + + private void FixupProductModelProductDescriptionCultures(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductModelProductDescriptionCulture item in e.NewItems) + { + item.Culture = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductModelProductDescriptionCulture item in e.OldItems) + { + if (ReferenceEquals(item.Culture, this)) + { + item.Culture = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Currency.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Currency.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/Currency.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Currency.cs index 5172528b..211701fb 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Currency.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Currency.cs @@ -1,182 +1,182 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class Currency - { - public virtual string CurrencyCode { get; set; } - - public virtual string Name { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection CountryRegionCurrencies - { - get - { - if (_countryRegionCurrencies == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupCountryRegionCurrencies; - _countryRegionCurrencies = newCollection; - } - return _countryRegionCurrencies; - } - set - { - if (!ReferenceEquals(_countryRegionCurrencies, value)) - { - var previousValue = _countryRegionCurrencies as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupCountryRegionCurrencies; - } - _countryRegionCurrencies = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupCountryRegionCurrencies; - } - } - } - } - - private ICollection _countryRegionCurrencies; - - public virtual ICollection CurrencyRates - { - get - { - if (_currencyRates == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupCurrencyRates; - _currencyRates = newCollection; - } - return _currencyRates; - } - set - { - if (!ReferenceEquals(_currencyRates, value)) - { - var previousValue = _currencyRates as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupCurrencyRates; - } - _currencyRates = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupCurrencyRates; - } - } - } - } - - private ICollection _currencyRates; - - public virtual ICollection CurrencyRates1 - { - get - { - if (_currencyRates1 == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupCurrencyRates1; - _currencyRates1 = newCollection; - } - return _currencyRates1; - } - set - { - if (!ReferenceEquals(_currencyRates1, value)) - { - var previousValue = _currencyRates1 as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupCurrencyRates1; - } - _currencyRates1 = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupCurrencyRates1; - } - } - } - } - - private ICollection _currencyRates1; - - private void FixupCountryRegionCurrencies(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (CountryRegionCurrency item in e.NewItems) - { - item.Currency = this; - } - } - - if (e.OldItems != null) - { - foreach (CountryRegionCurrency item in e.OldItems) - { - if (ReferenceEquals(item.Currency, this)) - { - item.Currency = null; - } - } - } - } - - private void FixupCurrencyRates(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (CurrencyRate item in e.NewItems) - { - item.Currency = this; - } - } - - if (e.OldItems != null) - { - foreach (CurrencyRate item in e.OldItems) - { - if (ReferenceEquals(item.Currency, this)) - { - item.Currency = null; - } - } - } - } - - private void FixupCurrencyRates1(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (CurrencyRate item in e.NewItems) - { - item.Currency1 = this; - } - } - - if (e.OldItems != null) - { - foreach (CurrencyRate item in e.OldItems) - { - if (ReferenceEquals(item.Currency1, this)) - { - item.Currency1 = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class Currency + { + public virtual string CurrencyCode { get; set; } + + public virtual string Name { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection CountryRegionCurrencies + { + get + { + if (_countryRegionCurrencies == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupCountryRegionCurrencies; + _countryRegionCurrencies = newCollection; + } + return _countryRegionCurrencies; + } + set + { + if (!ReferenceEquals(_countryRegionCurrencies, value)) + { + var previousValue = _countryRegionCurrencies as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupCountryRegionCurrencies; + } + _countryRegionCurrencies = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupCountryRegionCurrencies; + } + } + } + } + + private ICollection _countryRegionCurrencies; + + public virtual ICollection CurrencyRates + { + get + { + if (_currencyRates == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupCurrencyRates; + _currencyRates = newCollection; + } + return _currencyRates; + } + set + { + if (!ReferenceEquals(_currencyRates, value)) + { + var previousValue = _currencyRates as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupCurrencyRates; + } + _currencyRates = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupCurrencyRates; + } + } + } + } + + private ICollection _currencyRates; + + public virtual ICollection CurrencyRates1 + { + get + { + if (_currencyRates1 == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupCurrencyRates1; + _currencyRates1 = newCollection; + } + return _currencyRates1; + } + set + { + if (!ReferenceEquals(_currencyRates1, value)) + { + var previousValue = _currencyRates1 as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupCurrencyRates1; + } + _currencyRates1 = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupCurrencyRates1; + } + } + } + } + + private ICollection _currencyRates1; + + private void FixupCountryRegionCurrencies(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (CountryRegionCurrency item in e.NewItems) + { + item.Currency = this; + } + } + + if (e.OldItems != null) + { + foreach (CountryRegionCurrency item in e.OldItems) + { + if (ReferenceEquals(item.Currency, this)) + { + item.Currency = null; + } + } + } + } + + private void FixupCurrencyRates(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (CurrencyRate item in e.NewItems) + { + item.Currency = this; + } + } + + if (e.OldItems != null) + { + foreach (CurrencyRate item in e.OldItems) + { + if (ReferenceEquals(item.Currency, this)) + { + item.Currency = null; + } + } + } + } + + private void FixupCurrencyRates1(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (CurrencyRate item in e.NewItems) + { + item.Currency1 = this; + } + } + + if (e.OldItems != null) + { + foreach (CurrencyRate item in e.OldItems) + { + if (ReferenceEquals(item.Currency1, this)) + { + item.Currency1 = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/CurrencyRate.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CurrencyRate.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/CurrencyRate.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CurrencyRate.cs index f3b9db7f..6b9a0b72 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/CurrencyRate.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CurrencyRate.cs @@ -1,188 +1,188 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class CurrencyRate - { - public virtual int CurrencyRateID { get; set; } - - public virtual DateTime CurrencyRateDate { get; set; } - - public virtual string FromCurrencyCode - { - get { return _fromCurrencyCode; } - set - { - if (_fromCurrencyCode != value) - { - if (Currency != null - && Currency.CurrencyCode != value) - { - Currency = null; - } - _fromCurrencyCode = value; - } - } - } - - private string _fromCurrencyCode; - - public virtual string ToCurrencyCode - { - get { return _toCurrencyCode; } - set - { - if (_toCurrencyCode != value) - { - if (Currency1 != null - && Currency1.CurrencyCode != value) - { - Currency1 = null; - } - _toCurrencyCode = value; - } - } - } - - private string _toCurrencyCode; - - public virtual decimal AverageRate { get; set; } - - public virtual decimal EndOfDayRate { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Currency Currency - { - get { return _currency; } - set - { - if (!ReferenceEquals(_currency, value)) - { - var previousValue = _currency; - _currency = value; - FixupCurrency(previousValue); - } - } - } - - private Currency _currency; - - public virtual Currency Currency1 - { - get { return _currency1; } - set - { - if (!ReferenceEquals(_currency1, value)) - { - var previousValue = _currency1; - _currency1 = value; - FixupCurrency1(previousValue); - } - } - } - - private Currency _currency1; - - public virtual ICollection SalesOrderHeaders - { - get - { - if (_salesOrderHeaders == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesOrderHeaders; - _salesOrderHeaders = newCollection; - } - return _salesOrderHeaders; - } - set - { - if (!ReferenceEquals(_salesOrderHeaders, value)) - { - var previousValue = _salesOrderHeaders as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesOrderHeaders; - } - _salesOrderHeaders = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesOrderHeaders; - } - } - } - } - - private ICollection _salesOrderHeaders; - - private void FixupCurrency(Currency previousValue) - { - if (previousValue != null - && previousValue.CurrencyRates.Contains(this)) - { - previousValue.CurrencyRates.Remove(this); - } - - if (Currency != null) - { - if (!Currency.CurrencyRates.Contains(this)) - { - Currency.CurrencyRates.Add(this); - } - if (FromCurrencyCode != Currency.CurrencyCode) - { - FromCurrencyCode = Currency.CurrencyCode; - } - } - } - - private void FixupCurrency1(Currency previousValue) - { - if (previousValue != null - && previousValue.CurrencyRates1.Contains(this)) - { - previousValue.CurrencyRates1.Remove(this); - } - - if (Currency1 != null) - { - if (!Currency1.CurrencyRates1.Contains(this)) - { - Currency1.CurrencyRates1.Add(this); - } - if (ToCurrencyCode != Currency1.CurrencyCode) - { - ToCurrencyCode = Currency1.CurrencyCode; - } - } - } - - private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesOrderHeader item in e.NewItems) - { - item.CurrencyRate = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesOrderHeader item in e.OldItems) - { - if (ReferenceEquals(item.CurrencyRate, this)) - { - item.CurrencyRate = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class CurrencyRate + { + public virtual int CurrencyRateID { get; set; } + + public virtual DateTime CurrencyRateDate { get; set; } + + public virtual string FromCurrencyCode + { + get { return _fromCurrencyCode; } + set + { + if (_fromCurrencyCode != value) + { + if (Currency != null + && Currency.CurrencyCode != value) + { + Currency = null; + } + _fromCurrencyCode = value; + } + } + } + + private string _fromCurrencyCode; + + public virtual string ToCurrencyCode + { + get { return _toCurrencyCode; } + set + { + if (_toCurrencyCode != value) + { + if (Currency1 != null + && Currency1.CurrencyCode != value) + { + Currency1 = null; + } + _toCurrencyCode = value; + } + } + } + + private string _toCurrencyCode; + + public virtual decimal AverageRate { get; set; } + + public virtual decimal EndOfDayRate { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Currency Currency + { + get { return _currency; } + set + { + if (!ReferenceEquals(_currency, value)) + { + var previousValue = _currency; + _currency = value; + FixupCurrency(previousValue); + } + } + } + + private Currency _currency; + + public virtual Currency Currency1 + { + get { return _currency1; } + set + { + if (!ReferenceEquals(_currency1, value)) + { + var previousValue = _currency1; + _currency1 = value; + FixupCurrency1(previousValue); + } + } + } + + private Currency _currency1; + + public virtual ICollection SalesOrderHeaders + { + get + { + if (_salesOrderHeaders == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesOrderHeaders; + _salesOrderHeaders = newCollection; + } + return _salesOrderHeaders; + } + set + { + if (!ReferenceEquals(_salesOrderHeaders, value)) + { + var previousValue = _salesOrderHeaders as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesOrderHeaders; + } + _salesOrderHeaders = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesOrderHeaders; + } + } + } + } + + private ICollection _salesOrderHeaders; + + private void FixupCurrency(Currency previousValue) + { + if (previousValue != null + && previousValue.CurrencyRates.Contains(this)) + { + previousValue.CurrencyRates.Remove(this); + } + + if (Currency != null) + { + if (!Currency.CurrencyRates.Contains(this)) + { + Currency.CurrencyRates.Add(this); + } + if (FromCurrencyCode != Currency.CurrencyCode) + { + FromCurrencyCode = Currency.CurrencyCode; + } + } + } + + private void FixupCurrency1(Currency previousValue) + { + if (previousValue != null + && previousValue.CurrencyRates1.Contains(this)) + { + previousValue.CurrencyRates1.Remove(this); + } + + if (Currency1 != null) + { + if (!Currency1.CurrencyRates1.Contains(this)) + { + Currency1.CurrencyRates1.Add(this); + } + if (ToCurrencyCode != Currency1.CurrencyCode) + { + ToCurrencyCode = Currency1.CurrencyCode; + } + } + } + + private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesOrderHeader item in e.NewItems) + { + item.CurrencyRate = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesOrderHeader item in e.OldItems) + { + if (ReferenceEquals(item.CurrencyRate, this)) + { + item.CurrencyRate = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Customer.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Customer.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/Customer.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Customer.cs index ba303eca..b5dc7e38 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Customer.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Customer.cs @@ -1,263 +1,263 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class Customer - { - public virtual int CustomerID { get; set; } - - public virtual int? TerritoryID - { - get { return _territoryID; } - set - { - try - { - _settingFK = true; - if (_territoryID != value) - { - if (SalesTerritory != null - && SalesTerritory.TerritoryID != value) - { - SalesTerritory = null; - } - _territoryID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int? _territoryID; - - public virtual string AccountNumber { get; set; } - - public virtual string CustomerType { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual CustomerDiscount CustomerDiscount { get; set; } - - public virtual SalesTerritory SalesTerritory - { - get { return _salesTerritory; } - set - { - if (!ReferenceEquals(_salesTerritory, value)) - { - var previousValue = _salesTerritory; - _salesTerritory = value; - FixupSalesTerritory(previousValue); - } - } - } - - private SalesTerritory _salesTerritory; - - public virtual ICollection CustomerAddresses - { - get - { - if (_customerAddresses == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupCustomerAddresses; - _customerAddresses = newCollection; - } - return _customerAddresses; - } - set - { - if (!ReferenceEquals(_customerAddresses, value)) - { - var previousValue = _customerAddresses as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupCustomerAddresses; - } - _customerAddresses = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupCustomerAddresses; - } - } - } - } - - private ICollection _customerAddresses; - - public virtual Individual Individual - { - get { return _individual; } - set - { - if (!ReferenceEquals(_individual, value)) - { - var previousValue = _individual; - _individual = value; - FixupIndividual(previousValue); - } - } - } - - private Individual _individual; - - public virtual ICollection SalesOrderHeaders - { - get - { - if (_salesOrderHeaders == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesOrderHeaders; - _salesOrderHeaders = newCollection; - } - return _salesOrderHeaders; - } - set - { - if (!ReferenceEquals(_salesOrderHeaders, value)) - { - var previousValue = _salesOrderHeaders as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesOrderHeaders; - } - _salesOrderHeaders = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesOrderHeaders; - } - } - } - } - - private ICollection _salesOrderHeaders; - - public virtual Store Store - { - get { return _store; } - set - { - if (!ReferenceEquals(_store, value)) - { - var previousValue = _store; - _store = value; - FixupStore(previousValue); - } - } - } - - private Store _store; - - private bool _settingFK; - - private void FixupSalesTerritory(SalesTerritory previousValue) - { - if (previousValue != null - && previousValue.Customers.Contains(this)) - { - previousValue.Customers.Remove(this); - } - - if (SalesTerritory != null) - { - if (!SalesTerritory.Customers.Contains(this)) - { - SalesTerritory.Customers.Add(this); - } - if (TerritoryID != SalesTerritory.TerritoryID) - { - TerritoryID = SalesTerritory.TerritoryID; - } - } - else if (!_settingFK) - { - TerritoryID = null; - } - } - - private void FixupIndividual(Individual previousValue) - { - if (previousValue != null - && ReferenceEquals(previousValue.Customer, this)) - { - previousValue.Customer = null; - } - - if (Individual != null) - { - Individual.Customer = this; - } - } - - private void FixupStore(Store previousValue) - { - if (previousValue != null - && ReferenceEquals(previousValue.Customer, this)) - { - previousValue.Customer = null; - } - - if (Store != null) - { - Store.Customer = this; - } - } - - private void FixupCustomerAddresses(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (CustomerAddress item in e.NewItems) - { - item.Customer = this; - } - } - - if (e.OldItems != null) - { - foreach (CustomerAddress item in e.OldItems) - { - if (ReferenceEquals(item.Customer, this)) - { - item.Customer = null; - } - } - } - } - - private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesOrderHeader item in e.NewItems) - { - item.Customer = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesOrderHeader item in e.OldItems) - { - if (ReferenceEquals(item.Customer, this)) - { - item.Customer = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class Customer + { + public virtual int CustomerID { get; set; } + + public virtual int? TerritoryID + { + get { return _territoryID; } + set + { + try + { + _settingFK = true; + if (_territoryID != value) + { + if (SalesTerritory != null + && SalesTerritory.TerritoryID != value) + { + SalesTerritory = null; + } + _territoryID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int? _territoryID; + + public virtual string AccountNumber { get; set; } + + public virtual string CustomerType { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual CustomerDiscount CustomerDiscount { get; set; } + + public virtual SalesTerritory SalesTerritory + { + get { return _salesTerritory; } + set + { + if (!ReferenceEquals(_salesTerritory, value)) + { + var previousValue = _salesTerritory; + _salesTerritory = value; + FixupSalesTerritory(previousValue); + } + } + } + + private SalesTerritory _salesTerritory; + + public virtual ICollection CustomerAddresses + { + get + { + if (_customerAddresses == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupCustomerAddresses; + _customerAddresses = newCollection; + } + return _customerAddresses; + } + set + { + if (!ReferenceEquals(_customerAddresses, value)) + { + var previousValue = _customerAddresses as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupCustomerAddresses; + } + _customerAddresses = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupCustomerAddresses; + } + } + } + } + + private ICollection _customerAddresses; + + public virtual Individual Individual + { + get { return _individual; } + set + { + if (!ReferenceEquals(_individual, value)) + { + var previousValue = _individual; + _individual = value; + FixupIndividual(previousValue); + } + } + } + + private Individual _individual; + + public virtual ICollection SalesOrderHeaders + { + get + { + if (_salesOrderHeaders == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesOrderHeaders; + _salesOrderHeaders = newCollection; + } + return _salesOrderHeaders; + } + set + { + if (!ReferenceEquals(_salesOrderHeaders, value)) + { + var previousValue = _salesOrderHeaders as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesOrderHeaders; + } + _salesOrderHeaders = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesOrderHeaders; + } + } + } + } + + private ICollection _salesOrderHeaders; + + public virtual Store Store + { + get { return _store; } + set + { + if (!ReferenceEquals(_store, value)) + { + var previousValue = _store; + _store = value; + FixupStore(previousValue); + } + } + } + + private Store _store; + + private bool _settingFK; + + private void FixupSalesTerritory(SalesTerritory previousValue) + { + if (previousValue != null + && previousValue.Customers.Contains(this)) + { + previousValue.Customers.Remove(this); + } + + if (SalesTerritory != null) + { + if (!SalesTerritory.Customers.Contains(this)) + { + SalesTerritory.Customers.Add(this); + } + if (TerritoryID != SalesTerritory.TerritoryID) + { + TerritoryID = SalesTerritory.TerritoryID; + } + } + else if (!_settingFK) + { + TerritoryID = null; + } + } + + private void FixupIndividual(Individual previousValue) + { + if (previousValue != null + && ReferenceEquals(previousValue.Customer, this)) + { + previousValue.Customer = null; + } + + if (Individual != null) + { + Individual.Customer = this; + } + } + + private void FixupStore(Store previousValue) + { + if (previousValue != null + && ReferenceEquals(previousValue.Customer, this)) + { + previousValue.Customer = null; + } + + if (Store != null) + { + Store.Customer = this; + } + } + + private void FixupCustomerAddresses(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (CustomerAddress item in e.NewItems) + { + item.Customer = this; + } + } + + if (e.OldItems != null) + { + foreach (CustomerAddress item in e.OldItems) + { + if (ReferenceEquals(item.Customer, this)) + { + item.Customer = null; + } + } + } + } + + private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesOrderHeader item in e.NewItems) + { + item.Customer = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesOrderHeader item in e.OldItems) + { + if (ReferenceEquals(item.Customer, this)) + { + item.Customer = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/CustomerAddress.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CustomerAddress.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/CustomerAddress.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CustomerAddress.cs index 4d7cd068..790751dc 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/CustomerAddress.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CustomerAddress.cs @@ -1,181 +1,181 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class CustomerAddress - { - public virtual int CustomerID - { - get { return _customerID; } - set - { - if (_customerID != value) - { - if (Customer != null - && Customer.CustomerID != value) - { - Customer = null; - } - _customerID = value; - } - } - } - - private int _customerID; - - public virtual int AddressID - { - get { return _addressID; } - set - { - if (_addressID != value) - { - if (Address != null - && Address.AddressID != value) - { - Address = null; - } - _addressID = value; - } - } - } - - private int _addressID; - - public virtual int AddressTypeID - { - get { return _addressTypeID; } - set - { - if (_addressTypeID != value) - { - if (AddressType != null - && AddressType.AddressTypeID != value) - { - AddressType = null; - } - _addressTypeID = value; - } - } - } - - private int _addressTypeID; - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Address Address - { - get { return _address; } - set - { - if (!ReferenceEquals(_address, value)) - { - var previousValue = _address; - _address = value; - FixupAddress(previousValue); - } - } - } - - private Address _address; - - public virtual AddressType AddressType - { - get { return _addressType; } - set - { - if (!ReferenceEquals(_addressType, value)) - { - var previousValue = _addressType; - _addressType = value; - FixupAddressType(previousValue); - } - } - } - - private AddressType _addressType; - - public virtual Customer Customer - { - get { return _customer; } - set - { - if (!ReferenceEquals(_customer, value)) - { - var previousValue = _customer; - _customer = value; - FixupCustomer(previousValue); - } - } - } - - private Customer _customer; - - private void FixupAddress(Address previousValue) - { - if (previousValue != null - && previousValue.CustomerAddresses.Contains(this)) - { - previousValue.CustomerAddresses.Remove(this); - } - - if (Address != null) - { - if (!Address.CustomerAddresses.Contains(this)) - { - Address.CustomerAddresses.Add(this); - } - if (AddressID != Address.AddressID) - { - AddressID = Address.AddressID; - } - } - } - - private void FixupAddressType(AddressType previousValue) - { - if (previousValue != null - && previousValue.CustomerAddresses.Contains(this)) - { - previousValue.CustomerAddresses.Remove(this); - } - - if (AddressType != null) - { - if (!AddressType.CustomerAddresses.Contains(this)) - { - AddressType.CustomerAddresses.Add(this); - } - if (AddressTypeID != AddressType.AddressTypeID) - { - AddressTypeID = AddressType.AddressTypeID; - } - } - } - - private void FixupCustomer(Customer previousValue) - { - if (previousValue != null - && previousValue.CustomerAddresses.Contains(this)) - { - previousValue.CustomerAddresses.Remove(this); - } - - if (Customer != null) - { - if (!Customer.CustomerAddresses.Contains(this)) - { - Customer.CustomerAddresses.Add(this); - } - if (CustomerID != Customer.CustomerID) - { - CustomerID = Customer.CustomerID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class CustomerAddress + { + public virtual int CustomerID + { + get { return _customerID; } + set + { + if (_customerID != value) + { + if (Customer != null + && Customer.CustomerID != value) + { + Customer = null; + } + _customerID = value; + } + } + } + + private int _customerID; + + public virtual int AddressID + { + get { return _addressID; } + set + { + if (_addressID != value) + { + if (Address != null + && Address.AddressID != value) + { + Address = null; + } + _addressID = value; + } + } + } + + private int _addressID; + + public virtual int AddressTypeID + { + get { return _addressTypeID; } + set + { + if (_addressTypeID != value) + { + if (AddressType != null + && AddressType.AddressTypeID != value) + { + AddressType = null; + } + _addressTypeID = value; + } + } + } + + private int _addressTypeID; + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Address Address + { + get { return _address; } + set + { + if (!ReferenceEquals(_address, value)) + { + var previousValue = _address; + _address = value; + FixupAddress(previousValue); + } + } + } + + private Address _address; + + public virtual AddressType AddressType + { + get { return _addressType; } + set + { + if (!ReferenceEquals(_addressType, value)) + { + var previousValue = _addressType; + _addressType = value; + FixupAddressType(previousValue); + } + } + } + + private AddressType _addressType; + + public virtual Customer Customer + { + get { return _customer; } + set + { + if (!ReferenceEquals(_customer, value)) + { + var previousValue = _customer; + _customer = value; + FixupCustomer(previousValue); + } + } + } + + private Customer _customer; + + private void FixupAddress(Address previousValue) + { + if (previousValue != null + && previousValue.CustomerAddresses.Contains(this)) + { + previousValue.CustomerAddresses.Remove(this); + } + + if (Address != null) + { + if (!Address.CustomerAddresses.Contains(this)) + { + Address.CustomerAddresses.Add(this); + } + if (AddressID != Address.AddressID) + { + AddressID = Address.AddressID; + } + } + } + + private void FixupAddressType(AddressType previousValue) + { + if (previousValue != null + && previousValue.CustomerAddresses.Contains(this)) + { + previousValue.CustomerAddresses.Remove(this); + } + + if (AddressType != null) + { + if (!AddressType.CustomerAddresses.Contains(this)) + { + AddressType.CustomerAddresses.Add(this); + } + if (AddressTypeID != AddressType.AddressTypeID) + { + AddressTypeID = AddressType.AddressTypeID; + } + } + } + + private void FixupCustomer(Customer previousValue) + { + if (previousValue != null + && previousValue.CustomerAddresses.Contains(this)) + { + previousValue.CustomerAddresses.Remove(this); + } + + if (Customer != null) + { + if (!Customer.CustomerAddresses.Contains(this)) + { + Customer.CustomerAddresses.Add(this); + } + if (CustomerID != Customer.CustomerID) + { + CustomerID = Customer.CustomerID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/CustomerDiscount.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CustomerDiscount.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/CustomerDiscount.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CustomerDiscount.cs index de05534d..bde38e0d 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/CustomerDiscount.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/CustomerDiscount.cs @@ -1,19 +1,19 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class CustomerDiscount - { - public virtual int CustomerID { get; set; } - - public virtual Customer Customer { get; set; } - - public virtual decimal Discount { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class CustomerDiscount + { + public virtual int CustomerID { get; set; } + + public virtual Customer Customer { get; set; } + + public virtual decimal Discount { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Department.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Department.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/Department.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Department.cs index 365ad16c..22f91437 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Department.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Department.cs @@ -1,74 +1,74 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class Department - { - public virtual short DepartmentID { get; set; } - - public virtual string Name { get; set; } - - public virtual string GroupName { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection EmployeeDepartmentHistories - { - get - { - if (_employeeDepartmentHistories == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupEmployeeDepartmentHistories; - _employeeDepartmentHistories = newCollection; - } - return _employeeDepartmentHistories; - } - set - { - if (!ReferenceEquals(_employeeDepartmentHistories, value)) - { - var previousValue = _employeeDepartmentHistories as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupEmployeeDepartmentHistories; - } - _employeeDepartmentHistories = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupEmployeeDepartmentHistories; - } - } - } - } - - private ICollection _employeeDepartmentHistories; - - private void FixupEmployeeDepartmentHistories(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (EmployeeDepartmentHistory item in e.NewItems) - { - item.Department = this; - } - } - - if (e.OldItems != null) - { - foreach (EmployeeDepartmentHistory item in e.OldItems) - { - if (ReferenceEquals(item.Department, this)) - { - item.Department = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class Department + { + public virtual short DepartmentID { get; set; } + + public virtual string Name { get; set; } + + public virtual string GroupName { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection EmployeeDepartmentHistories + { + get + { + if (_employeeDepartmentHistories == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupEmployeeDepartmentHistories; + _employeeDepartmentHistories = newCollection; + } + return _employeeDepartmentHistories; + } + set + { + if (!ReferenceEquals(_employeeDepartmentHistories, value)) + { + var previousValue = _employeeDepartmentHistories as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupEmployeeDepartmentHistories; + } + _employeeDepartmentHistories = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupEmployeeDepartmentHistories; + } + } + } + } + + private ICollection _employeeDepartmentHistories; + + private void FixupEmployeeDepartmentHistories(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (EmployeeDepartmentHistory item in e.NewItems) + { + item.Department = this; + } + } + + if (e.OldItems != null) + { + foreach (EmployeeDepartmentHistory item in e.OldItems) + { + if (ReferenceEquals(item.Department, this)) + { + item.Department = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/DiscontinuedProduct.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/DiscontinuedProduct.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/DiscontinuedProduct.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/DiscontinuedProduct.cs index 09c91aac..b47cb878 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/DiscontinuedProduct.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/DiscontinuedProduct.cs @@ -1,11 +1,11 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class DiscontinuedProduct : Product - { - public virtual DateTime DiscontinuedDate { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class DiscontinuedProduct : Product + { + public virtual DateTime DiscontinuedDate { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Document.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Document.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/Document.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Document.cs index 2d23cfe2..48d01103 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Document.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Document.cs @@ -1,86 +1,86 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class Document - { - public virtual int DocumentID { get; set; } - - public virtual string Title { get; set; } - - public virtual string FileName { get; set; } - - public virtual string FileExtension { get; set; } - - public virtual string Revision { get; set; } - - public virtual int ChangeNumber { get; set; } - - public virtual byte Status { get; set; } - - public virtual string DocumentSummary { get; set; } - - public virtual byte[] Document1 { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection ProductDocuments - { - get - { - if (_productDocuments == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductDocuments; - _productDocuments = newCollection; - } - return _productDocuments; - } - set - { - if (!ReferenceEquals(_productDocuments, value)) - { - var previousValue = _productDocuments as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductDocuments; - } - _productDocuments = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductDocuments; - } - } - } - } - - private ICollection _productDocuments; - - private void FixupProductDocuments(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductDocument item in e.NewItems) - { - item.Document = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductDocument item in e.OldItems) - { - if (ReferenceEquals(item.Document, this)) - { - item.Document = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class Document + { + public virtual int DocumentID { get; set; } + + public virtual string Title { get; set; } + + public virtual string FileName { get; set; } + + public virtual string FileExtension { get; set; } + + public virtual string Revision { get; set; } + + public virtual int ChangeNumber { get; set; } + + public virtual byte Status { get; set; } + + public virtual string DocumentSummary { get; set; } + + public virtual byte[] Document1 { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection ProductDocuments + { + get + { + if (_productDocuments == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductDocuments; + _productDocuments = newCollection; + } + return _productDocuments; + } + set + { + if (!ReferenceEquals(_productDocuments, value)) + { + var previousValue = _productDocuments as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductDocuments; + } + _productDocuments = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductDocuments; + } + } + } + } + + private ICollection _productDocuments; + + private void FixupProductDocuments(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductDocument item in e.NewItems) + { + item.Document = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductDocument item in e.OldItems) + { + if (ReferenceEquals(item.Document, this)) + { + item.Document = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Employee.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Employee.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/Employee.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Employee.cs index 6011c129..c56acf6d 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Employee.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Employee.cs @@ -1,535 +1,535 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - using System.ComponentModel.DataAnnotations.Schema; - - public class Employee - { - public virtual int EmployeeID { get; set; } - - public virtual string NationalIDNumber { get; set; } - - public virtual int ContactID - { - get { return _contactID; } - set - { - try - { - _settingFK = true; - if (_contactID != value) - { - if (Contact != null - && Contact.ContactID != value) - { - Contact = null; - } - _contactID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int _contactID; - - public virtual string LoginID { get; set; } - - public virtual int? ManagerID - { - get { return _managerID; } - set - { - try - { - _settingFK = true; - if (_managerID != value) - { - if (Manager != null - && Manager.EmployeeID != value) - { - Manager = null; - } - _managerID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int? _managerID; - - public virtual string Title { get; set; } - - public virtual DateTime BirthDate { get; set; } - - public virtual string MaritalStatus { get; set; } - - public virtual string Gender { get; set; } - - public virtual DateTime HireDate { get; set; } - - public virtual bool SalariedFlag { get; set; } - - public virtual short VacationHours { get; set; } - - public virtual short SickLeaveHours { get; set; } - - public virtual bool CurrentFlag { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Contact Contact - { - get { return _contact; } - set - { - if (!ReferenceEquals(_contact, value)) - { - var previousValue = _contact; - _contact = value; - FixupContact(previousValue); - } - } - } - - private Contact _contact; - - public virtual ICollection Employees - { - get - { - if (_employees == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupEmployee1; - _employees = newCollection; - } - return _employees; - } - set - { - if (!ReferenceEquals(_employees, value)) - { - var previousValue = _employees as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupEmployee1; - } - _employees = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupEmployee1; - } - } - } - } - - private ICollection _employees; - - [ForeignKey("ManagerID")] - public virtual Employee Manager - { - get { return _manager; } - set - { - if (!ReferenceEquals(_manager, value)) - { - var previousValue = _manager; - _manager = value; - FixupEmployee2(previousValue); - } - } - } - - private Employee _manager; - - public virtual ICollection EmployeeAddresses - { - get - { - if (_employeeAddresses == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupEmployeeAddresses; - _employeeAddresses = newCollection; - } - return _employeeAddresses; - } - set - { - if (!ReferenceEquals(_employeeAddresses, value)) - { - var previousValue = _employeeAddresses as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupEmployeeAddresses; - } - _employeeAddresses = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupEmployeeAddresses; - } - } - } - } - - private ICollection _employeeAddresses; - - public virtual ICollection EmployeeDepartmentHistories - { - get - { - if (_employeeDepartmentHistories == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupEmployeeDepartmentHistories; - _employeeDepartmentHistories = newCollection; - } - return _employeeDepartmentHistories; - } - set - { - if (!ReferenceEquals(_employeeDepartmentHistories, value)) - { - var previousValue = _employeeDepartmentHistories as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupEmployeeDepartmentHistories; - } - _employeeDepartmentHistories = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupEmployeeDepartmentHistories; - } - } - } - } - - private ICollection _employeeDepartmentHistories; - - public virtual ICollection EmployeePayHistories - { - get - { - if (_employeePayHistories == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupEmployeePayHistories; - _employeePayHistories = newCollection; - } - return _employeePayHistories; - } - set - { - if (!ReferenceEquals(_employeePayHistories, value)) - { - var previousValue = _employeePayHistories as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupEmployeePayHistories; - } - _employeePayHistories = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupEmployeePayHistories; - } - } - } - } - - private ICollection _employeePayHistories; - - public virtual ICollection JobCandidates - { - get - { - if (_jobCandidates == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupJobCandidates; - _jobCandidates = newCollection; - } - return _jobCandidates; - } - set - { - if (!ReferenceEquals(_jobCandidates, value)) - { - var previousValue = _jobCandidates as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupJobCandidates; - } - _jobCandidates = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupJobCandidates; - } - } - } - } - - private ICollection _jobCandidates; - - public virtual ICollection PurchaseOrderHeaders - { - get - { - if (_purchaseOrderHeaders == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupPurchaseOrderHeaders; - _purchaseOrderHeaders = newCollection; - } - return _purchaseOrderHeaders; - } - set - { - if (!ReferenceEquals(_purchaseOrderHeaders, value)) - { - var previousValue = _purchaseOrderHeaders as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupPurchaseOrderHeaders; - } - _purchaseOrderHeaders = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupPurchaseOrderHeaders; - } - } - } - } - - private ICollection _purchaseOrderHeaders; - - public virtual SalesPerson SalesPerson - { - get { return _salesPerson; } - set - { - if (!ReferenceEquals(_salesPerson, value)) - { - var previousValue = _salesPerson; - _salesPerson = value; - FixupSalesPerson(previousValue); - } - } - } - - private SalesPerson _salesPerson; - - private bool _settingFK; - - private void FixupContact(Contact previousValue) - { - if (previousValue != null - && previousValue.Employees.Contains(this)) - { - previousValue.Employees.Remove(this); - } - - if (Contact != null) - { - if (!Contact.Employees.Contains(this)) - { - Contact.Employees.Add(this); - } - if (ContactID != Contact.ContactID) - { - ContactID = Contact.ContactID; - } - } - } - - private void FixupEmployee2(Employee previousValue) - { - if (previousValue != null - && previousValue.Employees.Contains(this)) - { - previousValue.Employees.Remove(this); - } - - if (Manager != null) - { - if (!Manager.Employees.Contains(this)) - { - Manager.Employees.Add(this); - } - if (ManagerID != Manager.EmployeeID) - { - ManagerID = Manager.EmployeeID; - } - } - else if (!_settingFK) - { - ManagerID = null; - } - } - - private void FixupSalesPerson(SalesPerson previousValue) - { - if (previousValue != null - && ReferenceEquals(previousValue.Employee, this)) - { - previousValue.Employee = null; - } - - if (SalesPerson != null) - { - SalesPerson.Employee = this; - } - } - - private void FixupEmployee1(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (Employee item in e.NewItems) - { - item.Manager = this; - } - } - - if (e.OldItems != null) - { - foreach (Employee item in e.OldItems) - { - if (ReferenceEquals(item.Manager, this)) - { - item.Manager = null; - } - } - } - } - - private void FixupEmployeeAddresses(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (EmployeeAddress item in e.NewItems) - { - item.Employee = this; - } - } - - if (e.OldItems != null) - { - foreach (EmployeeAddress item in e.OldItems) - { - if (ReferenceEquals(item.Employee, this)) - { - item.Employee = null; - } - } - } - } - - private void FixupEmployeeDepartmentHistories(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (EmployeeDepartmentHistory item in e.NewItems) - { - item.Employee = this; - } - } - - if (e.OldItems != null) - { - foreach (EmployeeDepartmentHistory item in e.OldItems) - { - if (ReferenceEquals(item.Employee, this)) - { - item.Employee = null; - } - } - } - } - - private void FixupEmployeePayHistories(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (EmployeePayHistory item in e.NewItems) - { - item.Employee = this; - } - } - - if (e.OldItems != null) - { - foreach (EmployeePayHistory item in e.OldItems) - { - if (ReferenceEquals(item.Employee, this)) - { - item.Employee = null; - } - } - } - } - - private void FixupJobCandidates(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (JobCandidate item in e.NewItems) - { - item.Employee = this; - } - } - - if (e.OldItems != null) - { - foreach (JobCandidate item in e.OldItems) - { - if (ReferenceEquals(item.Employee, this)) - { - item.Employee = null; - } - } - } - } - - private void FixupPurchaseOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (PurchaseOrderHeader item in e.NewItems) - { - item.Employee = this; - } - } - - if (e.OldItems != null) - { - foreach (PurchaseOrderHeader item in e.OldItems) - { - if (ReferenceEquals(item.Employee, this)) - { - item.Employee = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + using System.ComponentModel.DataAnnotations.Schema; + + public class Employee + { + public virtual int EmployeeID { get; set; } + + public virtual string NationalIDNumber { get; set; } + + public virtual int ContactID + { + get { return _contactID; } + set + { + try + { + _settingFK = true; + if (_contactID != value) + { + if (Contact != null + && Contact.ContactID != value) + { + Contact = null; + } + _contactID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int _contactID; + + public virtual string LoginID { get; set; } + + public virtual int? ManagerID + { + get { return _managerID; } + set + { + try + { + _settingFK = true; + if (_managerID != value) + { + if (Manager != null + && Manager.EmployeeID != value) + { + Manager = null; + } + _managerID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int? _managerID; + + public virtual string Title { get; set; } + + public virtual DateTime BirthDate { get; set; } + + public virtual string MaritalStatus { get; set; } + + public virtual string Gender { get; set; } + + public virtual DateTime HireDate { get; set; } + + public virtual bool SalariedFlag { get; set; } + + public virtual short VacationHours { get; set; } + + public virtual short SickLeaveHours { get; set; } + + public virtual bool CurrentFlag { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Contact Contact + { + get { return _contact; } + set + { + if (!ReferenceEquals(_contact, value)) + { + var previousValue = _contact; + _contact = value; + FixupContact(previousValue); + } + } + } + + private Contact _contact; + + public virtual ICollection Employees + { + get + { + if (_employees == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupEmployee1; + _employees = newCollection; + } + return _employees; + } + set + { + if (!ReferenceEquals(_employees, value)) + { + var previousValue = _employees as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupEmployee1; + } + _employees = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupEmployee1; + } + } + } + } + + private ICollection _employees; + + [ForeignKey("ManagerID")] + public virtual Employee Manager + { + get { return _manager; } + set + { + if (!ReferenceEquals(_manager, value)) + { + var previousValue = _manager; + _manager = value; + FixupEmployee2(previousValue); + } + } + } + + private Employee _manager; + + public virtual ICollection EmployeeAddresses + { + get + { + if (_employeeAddresses == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupEmployeeAddresses; + _employeeAddresses = newCollection; + } + return _employeeAddresses; + } + set + { + if (!ReferenceEquals(_employeeAddresses, value)) + { + var previousValue = _employeeAddresses as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupEmployeeAddresses; + } + _employeeAddresses = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupEmployeeAddresses; + } + } + } + } + + private ICollection _employeeAddresses; + + public virtual ICollection EmployeeDepartmentHistories + { + get + { + if (_employeeDepartmentHistories == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupEmployeeDepartmentHistories; + _employeeDepartmentHistories = newCollection; + } + return _employeeDepartmentHistories; + } + set + { + if (!ReferenceEquals(_employeeDepartmentHistories, value)) + { + var previousValue = _employeeDepartmentHistories as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupEmployeeDepartmentHistories; + } + _employeeDepartmentHistories = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupEmployeeDepartmentHistories; + } + } + } + } + + private ICollection _employeeDepartmentHistories; + + public virtual ICollection EmployeePayHistories + { + get + { + if (_employeePayHistories == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupEmployeePayHistories; + _employeePayHistories = newCollection; + } + return _employeePayHistories; + } + set + { + if (!ReferenceEquals(_employeePayHistories, value)) + { + var previousValue = _employeePayHistories as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupEmployeePayHistories; + } + _employeePayHistories = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupEmployeePayHistories; + } + } + } + } + + private ICollection _employeePayHistories; + + public virtual ICollection JobCandidates + { + get + { + if (_jobCandidates == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupJobCandidates; + _jobCandidates = newCollection; + } + return _jobCandidates; + } + set + { + if (!ReferenceEquals(_jobCandidates, value)) + { + var previousValue = _jobCandidates as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupJobCandidates; + } + _jobCandidates = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupJobCandidates; + } + } + } + } + + private ICollection _jobCandidates; + + public virtual ICollection PurchaseOrderHeaders + { + get + { + if (_purchaseOrderHeaders == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupPurchaseOrderHeaders; + _purchaseOrderHeaders = newCollection; + } + return _purchaseOrderHeaders; + } + set + { + if (!ReferenceEquals(_purchaseOrderHeaders, value)) + { + var previousValue = _purchaseOrderHeaders as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupPurchaseOrderHeaders; + } + _purchaseOrderHeaders = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupPurchaseOrderHeaders; + } + } + } + } + + private ICollection _purchaseOrderHeaders; + + public virtual SalesPerson SalesPerson + { + get { return _salesPerson; } + set + { + if (!ReferenceEquals(_salesPerson, value)) + { + var previousValue = _salesPerson; + _salesPerson = value; + FixupSalesPerson(previousValue); + } + } + } + + private SalesPerson _salesPerson; + + private bool _settingFK; + + private void FixupContact(Contact previousValue) + { + if (previousValue != null + && previousValue.Employees.Contains(this)) + { + previousValue.Employees.Remove(this); + } + + if (Contact != null) + { + if (!Contact.Employees.Contains(this)) + { + Contact.Employees.Add(this); + } + if (ContactID != Contact.ContactID) + { + ContactID = Contact.ContactID; + } + } + } + + private void FixupEmployee2(Employee previousValue) + { + if (previousValue != null + && previousValue.Employees.Contains(this)) + { + previousValue.Employees.Remove(this); + } + + if (Manager != null) + { + if (!Manager.Employees.Contains(this)) + { + Manager.Employees.Add(this); + } + if (ManagerID != Manager.EmployeeID) + { + ManagerID = Manager.EmployeeID; + } + } + else if (!_settingFK) + { + ManagerID = null; + } + } + + private void FixupSalesPerson(SalesPerson previousValue) + { + if (previousValue != null + && ReferenceEquals(previousValue.Employee, this)) + { + previousValue.Employee = null; + } + + if (SalesPerson != null) + { + SalesPerson.Employee = this; + } + } + + private void FixupEmployee1(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (Employee item in e.NewItems) + { + item.Manager = this; + } + } + + if (e.OldItems != null) + { + foreach (Employee item in e.OldItems) + { + if (ReferenceEquals(item.Manager, this)) + { + item.Manager = null; + } + } + } + } + + private void FixupEmployeeAddresses(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (EmployeeAddress item in e.NewItems) + { + item.Employee = this; + } + } + + if (e.OldItems != null) + { + foreach (EmployeeAddress item in e.OldItems) + { + if (ReferenceEquals(item.Employee, this)) + { + item.Employee = null; + } + } + } + } + + private void FixupEmployeeDepartmentHistories(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (EmployeeDepartmentHistory item in e.NewItems) + { + item.Employee = this; + } + } + + if (e.OldItems != null) + { + foreach (EmployeeDepartmentHistory item in e.OldItems) + { + if (ReferenceEquals(item.Employee, this)) + { + item.Employee = null; + } + } + } + } + + private void FixupEmployeePayHistories(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (EmployeePayHistory item in e.NewItems) + { + item.Employee = this; + } + } + + if (e.OldItems != null) + { + foreach (EmployeePayHistory item in e.OldItems) + { + if (ReferenceEquals(item.Employee, this)) + { + item.Employee = null; + } + } + } + } + + private void FixupJobCandidates(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (JobCandidate item in e.NewItems) + { + item.Employee = this; + } + } + + if (e.OldItems != null) + { + foreach (JobCandidate item in e.OldItems) + { + if (ReferenceEquals(item.Employee, this)) + { + item.Employee = null; + } + } + } + } + + private void FixupPurchaseOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (PurchaseOrderHeader item in e.NewItems) + { + item.Employee = this; + } + } + + if (e.OldItems != null) + { + foreach (PurchaseOrderHeader item in e.OldItems) + { + if (ReferenceEquals(item.Employee, this)) + { + item.Employee = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/EmployeeAddress.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/EmployeeAddress.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/EmployeeAddress.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/EmployeeAddress.cs index 51b39750..acf99850 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/EmployeeAddress.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/EmployeeAddress.cs @@ -1,127 +1,127 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.ComponentModel.DataAnnotations; - - public class EmployeeAddress - { - [Key] - public virtual int EmployeeID - { - get { return _employeeID; } - set - { - if (_employeeID != value) - { -// if (Employee != null && Employee.EmployeeID != value) -// { -// Employee = null; -// } - _employeeID = value; - } - } - } - - private int _employeeID; - - [Key] - public virtual int AddressID - { - get { return _addressID; } - set - { - if (_addressID != value) - { - if (Address != null - && Address.AddressID != value) - { - Address = null; - } - _addressID = value; - } - } - } - - private int _addressID; - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Employee Employee - { - get { return _employee; } - set - { - if (!ReferenceEquals(_employee, value)) - { - var previousValue = _employee; - _employee = value; - FixupEmployee(previousValue); - } - } - } - - private Employee _employee; - - public virtual Address Address - { - get { return _address; } - set - { - if (!ReferenceEquals(_address, value)) - { - var previousValue = _address; - _address = value; - FixupAddress(previousValue); - } - } - } - - private Address _address; - - private void FixupEmployee(Employee previousValue) - { - if (previousValue != null - && previousValue.EmployeeAddresses.Contains(this)) - { - previousValue.EmployeeAddresses.Remove(this); - } - - if (Employee != null) - { - if (!Employee.EmployeeAddresses.Contains(this)) - { - Employee.EmployeeAddresses.Add(this); - } - if (EmployeeID != Employee.EmployeeID) - { - EmployeeID = Employee.EmployeeID; - } - } - } - - private void FixupAddress(Address previousValue) - { - if (previousValue != null - && previousValue.EmployeeAddresses.Contains(this)) - { - previousValue.EmployeeAddresses.Remove(this); - } - - if (Address != null) - { - if (!Address.EmployeeAddresses.Contains(this)) - { - Address.EmployeeAddresses.Add(this); - } - if (AddressID != Address.AddressID) - { - AddressID = Address.AddressID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.ComponentModel.DataAnnotations; + + public class EmployeeAddress + { + [Key] + public virtual int EmployeeID + { + get { return _employeeID; } + set + { + if (_employeeID != value) + { +// if (Employee != null && Employee.EmployeeID != value) +// { +// Employee = null; +// } + _employeeID = value; + } + } + } + + private int _employeeID; + + [Key] + public virtual int AddressID + { + get { return _addressID; } + set + { + if (_addressID != value) + { + if (Address != null + && Address.AddressID != value) + { + Address = null; + } + _addressID = value; + } + } + } + + private int _addressID; + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Employee Employee + { + get { return _employee; } + set + { + if (!ReferenceEquals(_employee, value)) + { + var previousValue = _employee; + _employee = value; + FixupEmployee(previousValue); + } + } + } + + private Employee _employee; + + public virtual Address Address + { + get { return _address; } + set + { + if (!ReferenceEquals(_address, value)) + { + var previousValue = _address; + _address = value; + FixupAddress(previousValue); + } + } + } + + private Address _address; + + private void FixupEmployee(Employee previousValue) + { + if (previousValue != null + && previousValue.EmployeeAddresses.Contains(this)) + { + previousValue.EmployeeAddresses.Remove(this); + } + + if (Employee != null) + { + if (!Employee.EmployeeAddresses.Contains(this)) + { + Employee.EmployeeAddresses.Add(this); + } + if (EmployeeID != Employee.EmployeeID) + { + EmployeeID = Employee.EmployeeID; + } + } + } + + private void FixupAddress(Address previousValue) + { + if (previousValue != null + && previousValue.EmployeeAddresses.Contains(this)) + { + previousValue.EmployeeAddresses.Remove(this); + } + + if (Address != null) + { + if (!Address.EmployeeAddresses.Contains(this)) + { + Address.EmployeeAddresses.Add(this); + } + if (AddressID != Address.AddressID) + { + AddressID = Address.AddressID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/EmployeeDepartmentHistory.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/EmployeeDepartmentHistory.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/EmployeeDepartmentHistory.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/EmployeeDepartmentHistory.cs index d3d07f61..8e5ea010 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/EmployeeDepartmentHistory.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/EmployeeDepartmentHistory.cs @@ -1,183 +1,183 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class EmployeeDepartmentHistory - { - public virtual int EmployeeID - { - get { return _employeeID; } - set - { - if (_employeeID != value) - { - if (Employee != null - && Employee.EmployeeID != value) - { - Employee = null; - } - _employeeID = value; - } - } - } - - private int _employeeID; - - public virtual short DepartmentID - { - get { return _departmentID; } - set - { - if (_departmentID != value) - { - if (Department != null - && Department.DepartmentID != value) - { - Department = null; - } - _departmentID = value; - } - } - } - - private short _departmentID; - - public virtual byte ShiftID - { - get { return _shiftID; } - set - { - if (_shiftID != value) - { - if (Shift != null - && Shift.ShiftID != value) - { - Shift = null; - } - _shiftID = value; - } - } - } - - private byte _shiftID; - - public virtual DateTime StartDate { get; set; } - - public virtual DateTime? EndDate { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Department Department - { - get { return _department; } - set - { - if (!ReferenceEquals(_department, value)) - { - var previousValue = _department; - _department = value; - FixupDepartment(previousValue); - } - } - } - - private Department _department; - - public virtual Employee Employee - { - get { return _employee; } - set - { - if (!ReferenceEquals(_employee, value)) - { - var previousValue = _employee; - _employee = value; - FixupEmployee(previousValue); - } - } - } - - private Employee _employee; - - public virtual Shift Shift - { - get { return _shift; } - set - { - if (!ReferenceEquals(_shift, value)) - { - var previousValue = _shift; - _shift = value; - FixupShift(previousValue); - } - } - } - - private Shift _shift; - - private void FixupDepartment(Department previousValue) - { - if (previousValue != null - && previousValue.EmployeeDepartmentHistories.Contains(this)) - { - previousValue.EmployeeDepartmentHistories.Remove(this); - } - - if (Department != null) - { - if (!Department.EmployeeDepartmentHistories.Contains(this)) - { - Department.EmployeeDepartmentHistories.Add(this); - } - if (DepartmentID != Department.DepartmentID) - { - DepartmentID = Department.DepartmentID; - } - } - } - - private void FixupEmployee(Employee previousValue) - { - if (previousValue != null - && previousValue.EmployeeDepartmentHistories.Contains(this)) - { - previousValue.EmployeeDepartmentHistories.Remove(this); - } - - if (Employee != null) - { - if (!Employee.EmployeeDepartmentHistories.Contains(this)) - { - Employee.EmployeeDepartmentHistories.Add(this); - } - if (EmployeeID != Employee.EmployeeID) - { - EmployeeID = Employee.EmployeeID; - } - } - } - - private void FixupShift(Shift previousValue) - { - if (previousValue != null - && previousValue.EmployeeDepartmentHistories.Contains(this)) - { - previousValue.EmployeeDepartmentHistories.Remove(this); - } - - if (Shift != null) - { - if (!Shift.EmployeeDepartmentHistories.Contains(this)) - { - Shift.EmployeeDepartmentHistories.Add(this); - } - if (ShiftID != Shift.ShiftID) - { - ShiftID = Shift.ShiftID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class EmployeeDepartmentHistory + { + public virtual int EmployeeID + { + get { return _employeeID; } + set + { + if (_employeeID != value) + { + if (Employee != null + && Employee.EmployeeID != value) + { + Employee = null; + } + _employeeID = value; + } + } + } + + private int _employeeID; + + public virtual short DepartmentID + { + get { return _departmentID; } + set + { + if (_departmentID != value) + { + if (Department != null + && Department.DepartmentID != value) + { + Department = null; + } + _departmentID = value; + } + } + } + + private short _departmentID; + + public virtual byte ShiftID + { + get { return _shiftID; } + set + { + if (_shiftID != value) + { + if (Shift != null + && Shift.ShiftID != value) + { + Shift = null; + } + _shiftID = value; + } + } + } + + private byte _shiftID; + + public virtual DateTime StartDate { get; set; } + + public virtual DateTime? EndDate { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Department Department + { + get { return _department; } + set + { + if (!ReferenceEquals(_department, value)) + { + var previousValue = _department; + _department = value; + FixupDepartment(previousValue); + } + } + } + + private Department _department; + + public virtual Employee Employee + { + get { return _employee; } + set + { + if (!ReferenceEquals(_employee, value)) + { + var previousValue = _employee; + _employee = value; + FixupEmployee(previousValue); + } + } + } + + private Employee _employee; + + public virtual Shift Shift + { + get { return _shift; } + set + { + if (!ReferenceEquals(_shift, value)) + { + var previousValue = _shift; + _shift = value; + FixupShift(previousValue); + } + } + } + + private Shift _shift; + + private void FixupDepartment(Department previousValue) + { + if (previousValue != null + && previousValue.EmployeeDepartmentHistories.Contains(this)) + { + previousValue.EmployeeDepartmentHistories.Remove(this); + } + + if (Department != null) + { + if (!Department.EmployeeDepartmentHistories.Contains(this)) + { + Department.EmployeeDepartmentHistories.Add(this); + } + if (DepartmentID != Department.DepartmentID) + { + DepartmentID = Department.DepartmentID; + } + } + } + + private void FixupEmployee(Employee previousValue) + { + if (previousValue != null + && previousValue.EmployeeDepartmentHistories.Contains(this)) + { + previousValue.EmployeeDepartmentHistories.Remove(this); + } + + if (Employee != null) + { + if (!Employee.EmployeeDepartmentHistories.Contains(this)) + { + Employee.EmployeeDepartmentHistories.Add(this); + } + if (EmployeeID != Employee.EmployeeID) + { + EmployeeID = Employee.EmployeeID; + } + } + } + + private void FixupShift(Shift previousValue) + { + if (previousValue != null + && previousValue.EmployeeDepartmentHistories.Contains(this)) + { + previousValue.EmployeeDepartmentHistories.Remove(this); + } + + if (Shift != null) + { + if (!Shift.EmployeeDepartmentHistories.Contains(this)) + { + Shift.EmployeeDepartmentHistories.Add(this); + } + if (ShiftID != Shift.ShiftID) + { + ShiftID = Shift.ShiftID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/EmployeePayHistory.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/EmployeePayHistory.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/EmployeePayHistory.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/EmployeePayHistory.cs index f5764318..afd8ffb9 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/EmployeePayHistory.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/EmployeePayHistory.cs @@ -1,73 +1,73 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class EmployeePayHistory - { - public virtual int EmployeeID - { - get { return _employeeID; } - set - { - if (_employeeID != value) - { - if (Employee != null - && Employee.EmployeeID != value) - { - Employee = null; - } - _employeeID = value; - } - } - } - - private int _employeeID; - - public virtual DateTime RateChangeDate { get; set; } - - public virtual decimal Rate { get; set; } - - public virtual byte PayFrequency { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Employee Employee - { - get { return _employee; } - set - { - if (!ReferenceEquals(_employee, value)) - { - var previousValue = _employee; - _employee = value; - FixupEmployee(previousValue); - } - } - } - - private Employee _employee; - - private void FixupEmployee(Employee previousValue) - { - if (previousValue != null - && previousValue.EmployeePayHistories.Contains(this)) - { - previousValue.EmployeePayHistories.Remove(this); - } - - if (Employee != null) - { - if (!Employee.EmployeePayHistories.Contains(this)) - { - Employee.EmployeePayHistories.Add(this); - } - if (EmployeeID != Employee.EmployeeID) - { - EmployeeID = Employee.EmployeeID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class EmployeePayHistory + { + public virtual int EmployeeID + { + get { return _employeeID; } + set + { + if (_employeeID != value) + { + if (Employee != null + && Employee.EmployeeID != value) + { + Employee = null; + } + _employeeID = value; + } + } + } + + private int _employeeID; + + public virtual DateTime RateChangeDate { get; set; } + + public virtual decimal Rate { get; set; } + + public virtual byte PayFrequency { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Employee Employee + { + get { return _employee; } + set + { + if (!ReferenceEquals(_employee, value)) + { + var previousValue = _employee; + _employee = value; + FixupEmployee(previousValue); + } + } + } + + private Employee _employee; + + private void FixupEmployee(Employee previousValue) + { + if (previousValue != null + && previousValue.EmployeePayHistories.Contains(this)) + { + previousValue.EmployeePayHistories.Remove(this); + } + + if (Employee != null) + { + if (!Employee.EmployeePayHistories.Contains(this)) + { + Employee.EmployeePayHistories.Add(this); + } + if (EmployeeID != Employee.EmployeeID) + { + EmployeeID = Employee.EmployeeID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/FixupCollection'.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/FixupCollection'.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/FixupCollection'.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/FixupCollection'.cs index 59dfe04c..c248aaf8 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/FixupCollection'.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/FixupCollection'.cs @@ -1,25 +1,25 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System.Collections.Generic; - using System.Collections.ObjectModel; - - // An System.Collections.ObjectModel.ObservableCollection that raises - // individual item removal notifications on clear and prevents adding duplicates. - public class FixupCollection : ObservableCollection - { - protected override void ClearItems() - { - new List(this).ForEach(t => Remove(t)); - } - - protected override void InsertItem(int index, T item) - { - if (!Contains(item)) - { - base.InsertItem(index, item); - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System.Collections.Generic; + using System.Collections.ObjectModel; + + // An System.Collections.ObjectModel.ObservableCollection that raises + // individual item removal notifications on clear and prevents adding duplicates. + public class FixupCollection : ObservableCollection + { + protected override void ClearItems() + { + new List(this).ForEach(t => Remove(t)); + } + + protected override void InsertItem(int index, T item) + { + if (!Contains(item)) + { + base.InsertItem(index, item); + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Illustration.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Illustration.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/Illustration.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Illustration.cs index 3393e93f..2d64a74c 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Illustration.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Illustration.cs @@ -1,72 +1,72 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class Illustration - { - public virtual int IllustrationID { get; set; } - - public virtual string Diagram { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection ProductModelIllustrations - { - get - { - if (_productModelIllustrations == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductModelIllustrations; - _productModelIllustrations = newCollection; - } - return _productModelIllustrations; - } - set - { - if (!ReferenceEquals(_productModelIllustrations, value)) - { - var previousValue = _productModelIllustrations as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductModelIllustrations; - } - _productModelIllustrations = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductModelIllustrations; - } - } - } - } - - private ICollection _productModelIllustrations; - - private void FixupProductModelIllustrations(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductModelIllustration item in e.NewItems) - { - item.Illustration = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductModelIllustration item in e.OldItems) - { - if (ReferenceEquals(item.Illustration, this)) - { - item.Illustration = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class Illustration + { + public virtual int IllustrationID { get; set; } + + public virtual string Diagram { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection ProductModelIllustrations + { + get + { + if (_productModelIllustrations == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductModelIllustrations; + _productModelIllustrations = newCollection; + } + return _productModelIllustrations; + } + set + { + if (!ReferenceEquals(_productModelIllustrations, value)) + { + var previousValue = _productModelIllustrations as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductModelIllustrations; + } + _productModelIllustrations = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductModelIllustrations; + } + } + } + } + + private ICollection _productModelIllustrations; + + private void FixupProductModelIllustrations(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductModelIllustration item in e.NewItems) + { + item.Illustration = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductModelIllustration item in e.OldItems) + { + if (ReferenceEquals(item.Illustration, this)) + { + item.Illustration = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Individual.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Individual.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/Individual.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Individual.cs index beb3216f..e9a125a1 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Individual.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Individual.cs @@ -1,122 +1,122 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class Individual - { - public virtual int CustomerID - { - get { return _customerID; } - set - { - if (_customerID != value) - { - if (Customer != null - && Customer.CustomerID != value) - { - Customer = null; - } - _customerID = value; - } - } - } - - private int _customerID; - - public virtual int ContactID - { - get { return _contactID; } - set - { - if (_contactID != value) - { - if (Contact != null - && Contact.ContactID != value) - { - Contact = null; - } - _contactID = value; - } - } - } - - private int _contactID; - - public virtual string Demographics { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Contact Contact - { - get { return _contact; } - set - { - if (!ReferenceEquals(_contact, value)) - { - var previousValue = _contact; - _contact = value; - FixupContact(previousValue); - } - } - } - - private Contact _contact; - - public virtual Customer Customer - { - get { return _customer; } - set - { - if (!ReferenceEquals(_customer, value)) - { - var previousValue = _customer; - _customer = value; - FixupCustomer(previousValue); - } - } - } - - private Customer _customer; - - private void FixupContact(Contact previousValue) - { - if (previousValue != null - && previousValue.Individuals.Contains(this)) - { - previousValue.Individuals.Remove(this); - } - - if (Contact != null) - { - if (!Contact.Individuals.Contains(this)) - { - Contact.Individuals.Add(this); - } - if (ContactID != Contact.ContactID) - { - ContactID = Contact.ContactID; - } - } - } - - private void FixupCustomer(Customer previousValue) - { - if (previousValue != null - && ReferenceEquals(previousValue.Individual, this)) - { - previousValue.Individual = null; - } - - if (Customer != null) - { - Customer.Individual = this; - if (CustomerID != Customer.CustomerID) - { - CustomerID = Customer.CustomerID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class Individual + { + public virtual int CustomerID + { + get { return _customerID; } + set + { + if (_customerID != value) + { + if (Customer != null + && Customer.CustomerID != value) + { + Customer = null; + } + _customerID = value; + } + } + } + + private int _customerID; + + public virtual int ContactID + { + get { return _contactID; } + set + { + if (_contactID != value) + { + if (Contact != null + && Contact.ContactID != value) + { + Contact = null; + } + _contactID = value; + } + } + } + + private int _contactID; + + public virtual string Demographics { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Contact Contact + { + get { return _contact; } + set + { + if (!ReferenceEquals(_contact, value)) + { + var previousValue = _contact; + _contact = value; + FixupContact(previousValue); + } + } + } + + private Contact _contact; + + public virtual Customer Customer + { + get { return _customer; } + set + { + if (!ReferenceEquals(_customer, value)) + { + var previousValue = _customer; + _customer = value; + FixupCustomer(previousValue); + } + } + } + + private Customer _customer; + + private void FixupContact(Contact previousValue) + { + if (previousValue != null + && previousValue.Individuals.Contains(this)) + { + previousValue.Individuals.Remove(this); + } + + if (Contact != null) + { + if (!Contact.Individuals.Contains(this)) + { + Contact.Individuals.Add(this); + } + if (ContactID != Contact.ContactID) + { + ContactID = Contact.ContactID; + } + } + } + + private void FixupCustomer(Customer previousValue) + { + if (previousValue != null + && ReferenceEquals(previousValue.Individual, this)) + { + previousValue.Individual = null; + } + + if (Customer != null) + { + Customer.Individual = this; + if (CustomerID != Customer.CustomerID) + { + CustomerID = Customer.CustomerID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/JobCandidate.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/JobCandidate.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/JobCandidate.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/JobCandidate.cs index e19b510b..2551733c 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/JobCandidate.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/JobCandidate.cs @@ -1,85 +1,85 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class JobCandidate - { - public virtual int JobCandidateID { get; set; } - - public virtual int? EmployeeID - { - get { return _employeeID; } - set - { - try - { - _settingFK = true; - if (_employeeID != value) - { - if (Employee != null - && Employee.EmployeeID != value) - { - Employee = null; - } - _employeeID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int? _employeeID; - - public virtual string Resume { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Employee Employee - { - get { return _employee; } - set - { - if (!ReferenceEquals(_employee, value)) - { - var previousValue = _employee; - _employee = value; - FixupEmployee(previousValue); - } - } - } - - private Employee _employee; - - private bool _settingFK; - - private void FixupEmployee(Employee previousValue) - { - if (previousValue != null - && previousValue.JobCandidates.Contains(this)) - { - previousValue.JobCandidates.Remove(this); - } - - if (Employee != null) - { - if (!Employee.JobCandidates.Contains(this)) - { - Employee.JobCandidates.Add(this); - } - if (EmployeeID != Employee.EmployeeID) - { - EmployeeID = Employee.EmployeeID; - } - } - else if (!_settingFK) - { - EmployeeID = null; - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class JobCandidate + { + public virtual int JobCandidateID { get; set; } + + public virtual int? EmployeeID + { + get { return _employeeID; } + set + { + try + { + _settingFK = true; + if (_employeeID != value) + { + if (Employee != null + && Employee.EmployeeID != value) + { + Employee = null; + } + _employeeID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int? _employeeID; + + public virtual string Resume { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Employee Employee + { + get { return _employee; } + set + { + if (!ReferenceEquals(_employee, value)) + { + var previousValue = _employee; + _employee = value; + FixupEmployee(previousValue); + } + } + } + + private Employee _employee; + + private bool _settingFK; + + private void FixupEmployee(Employee previousValue) + { + if (previousValue != null + && previousValue.JobCandidates.Contains(this)) + { + previousValue.JobCandidates.Remove(this); + } + + if (Employee != null) + { + if (!Employee.JobCandidates.Contains(this)) + { + Employee.JobCandidates.Add(this); + } + if (EmployeeID != Employee.EmployeeID) + { + EmployeeID = Employee.EmployeeID; + } + } + else if (!_settingFK) + { + EmployeeID = null; + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Location.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Location.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/Location.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Location.cs index af3284fc..42e3368d 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Location.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Location.cs @@ -1,131 +1,131 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class Location - { - public virtual short? LocationID { get; set; } - - public virtual string Name { get; set; } - - public virtual decimal CostRate { get; set; } - - public virtual decimal Availability { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection ProductInventories - { - get - { - if (_productInventories == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductInventories; - _productInventories = newCollection; - } - return _productInventories; - } - set - { - if (!ReferenceEquals(_productInventories, value)) - { - var previousValue = _productInventories as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductInventories; - } - _productInventories = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductInventories; - } - } - } - } - - private ICollection _productInventories; - - public virtual ICollection WorkOrderRoutings - { - get - { - if (_workOrderRoutings == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupWorkOrderRoutings; - _workOrderRoutings = newCollection; - } - return _workOrderRoutings; - } - set - { - if (!ReferenceEquals(_workOrderRoutings, value)) - { - var previousValue = _workOrderRoutings as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupWorkOrderRoutings; - } - _workOrderRoutings = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupWorkOrderRoutings; - } - } - } - } - - private ICollection _workOrderRoutings; - - private void FixupProductInventories(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductInventory item in e.NewItems) - { - item.Location = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductInventory item in e.OldItems) - { - if (ReferenceEquals(item.Location, this)) - { - item.Location = null; - } - } - } - } - - private void FixupWorkOrderRoutings(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (WorkOrderRouting item in e.NewItems) - { - item.Location = this; - } - } - - if (e.OldItems != null) - { - foreach (WorkOrderRouting item in e.OldItems) - { - if (ReferenceEquals(item.Location, this)) - { - item.Location = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class Location + { + public virtual short? LocationID { get; set; } + + public virtual string Name { get; set; } + + public virtual decimal CostRate { get; set; } + + public virtual decimal Availability { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection ProductInventories + { + get + { + if (_productInventories == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductInventories; + _productInventories = newCollection; + } + return _productInventories; + } + set + { + if (!ReferenceEquals(_productInventories, value)) + { + var previousValue = _productInventories as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductInventories; + } + _productInventories = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductInventories; + } + } + } + } + + private ICollection _productInventories; + + public virtual ICollection WorkOrderRoutings + { + get + { + if (_workOrderRoutings == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupWorkOrderRoutings; + _workOrderRoutings = newCollection; + } + return _workOrderRoutings; + } + set + { + if (!ReferenceEquals(_workOrderRoutings, value)) + { + var previousValue = _workOrderRoutings as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupWorkOrderRoutings; + } + _workOrderRoutings = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupWorkOrderRoutings; + } + } + } + } + + private ICollection _workOrderRoutings; + + private void FixupProductInventories(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductInventory item in e.NewItems) + { + item.Location = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductInventory item in e.OldItems) + { + if (ReferenceEquals(item.Location, this)) + { + item.Location = null; + } + } + } + } + + private void FixupWorkOrderRoutings(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (WorkOrderRouting item in e.NewItems) + { + item.Location = this; + } + } + + if (e.OldItems != null) + { + foreach (WorkOrderRouting item in e.OldItems) + { + if (ReferenceEquals(item.Location, this)) + { + item.Location = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Product.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Product.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/Product.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Product.cs index 451781df..312b43dd 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Product.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Product.cs @@ -1,960 +1,960 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - using System.ComponentModel.DataAnnotations; - - public class Product - { - public virtual int ProductID { get; set; } - - public virtual string Name { get; set; } - - public virtual string ProductNumber { get; set; } - - public virtual bool MakeFlag { get; set; } - - public virtual bool FinishedGoodsFlag { get; set; } - - public virtual short SafetyStockLevel { get; set; } - - public virtual short ReorderPoint { get; set; } - - public virtual decimal StandardCost { get; set; } - - public virtual decimal ListPrice { get; set; } - - public virtual string Size { get; set; } - - public virtual decimal? Weight { get; set; } - - public virtual int DaysToManufacture { get; set; } - - public virtual string ProductLine { get; set; } - - public virtual string Class { get; set; } - - public virtual int? ProductSubcategoryID - { - get { return _productSubcategoryID; } - set - { - try - { - _settingFK = true; - if (_productSubcategoryID != value) - { - if (ProductSubcategory != null - && ProductSubcategory.ProductSubcategoryID != value) - { - ProductSubcategory = null; - } - _productSubcategoryID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int? _productSubcategoryID; - - public virtual int? ProductModelID - { - get { return _productModelID; } - set - { - try - { - _settingFK = true; - if (_productModelID != value) - { - if (ProductModel != null - && ProductModel.ProductModelID != value) - { - ProductModel = null; - } - _productModelID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int? _productModelID; - - public virtual DateTime SellStartDate { get; set; } - - [Required] - public virtual DateTime? SellEndDate { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection BillOfMaterials - { - get - { - if (_billOfMaterials == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupBillOfMaterials; - _billOfMaterials = newCollection; - } - return _billOfMaterials; - } - set - { - if (!ReferenceEquals(_billOfMaterials, value)) - { - var previousValue = _billOfMaterials as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupBillOfMaterials; - } - _billOfMaterials = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupBillOfMaterials; - } - } - } - } - - private ICollection _billOfMaterials; - - public virtual ICollection BillOfMaterials1 - { - get - { - if (_billOfMaterials1 == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupBillOfMaterials1; - _billOfMaterials1 = newCollection; - } - return _billOfMaterials1; - } - set - { - if (!ReferenceEquals(_billOfMaterials1, value)) - { - var previousValue = _billOfMaterials1 as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupBillOfMaterials1; - } - _billOfMaterials1 = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupBillOfMaterials1; - } - } - } - } - - private ICollection _billOfMaterials1; - - public virtual ProductModel ProductModel - { - get { return _productModel; } - set - { - if (!ReferenceEquals(_productModel, value)) - { - var previousValue = _productModel; - _productModel = value; - FixupProductModel(previousValue); - } - } - } - - private ProductModel _productModel; - - public virtual ProductSubcategory ProductSubcategory - { - get { return _productSubcategory; } - set - { - if (!ReferenceEquals(_productSubcategory, value)) - { - var previousValue = _productSubcategory; - _productSubcategory = value; - FixupProductSubcategory(previousValue); - } - } - } - - private ProductSubcategory _productSubcategory; - - public virtual UnitMeasure SizeUnitMeasure { get; set; } - public virtual UnitMeasure WeightUnitMeasure { get; set; } - - public virtual ICollection ProductCostHistories - { - get - { - if (_productCostHistories == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductCostHistories; - _productCostHistories = newCollection; - } - return _productCostHistories; - } - set - { - if (!ReferenceEquals(_productCostHistories, value)) - { - var previousValue = _productCostHistories as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductCostHistories; - } - _productCostHistories = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductCostHistories; - } - } - } - } - - private ICollection _productCostHistories; - - public virtual ICollection ProductDocuments - { - get - { - if (_productDocuments == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductDocuments; - _productDocuments = newCollection; - } - return _productDocuments; - } - set - { - if (!ReferenceEquals(_productDocuments, value)) - { - var previousValue = _productDocuments as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductDocuments; - } - _productDocuments = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductDocuments; - } - } - } - } - - private ICollection _productDocuments; - - public virtual ICollection ProductInventories - { - get - { - if (_productInventories == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductInventories; - _productInventories = newCollection; - } - return _productInventories; - } - set - { - if (!ReferenceEquals(_productInventories, value)) - { - var previousValue = _productInventories as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductInventories; - } - _productInventories = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductInventories; - } - } - } - } - - private ICollection _productInventories; - - public virtual ICollection ProductListPriceHistories - { - get - { - if (_productListPriceHistories == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductListPriceHistories; - _productListPriceHistories = newCollection; - } - return _productListPriceHistories; - } - set - { - if (!ReferenceEquals(_productListPriceHistories, value)) - { - var previousValue = _productListPriceHistories as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductListPriceHistories; - } - _productListPriceHistories = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductListPriceHistories; - } - } - } - } - - private ICollection _productListPriceHistories; - - public virtual ICollection ProductProductPhotoes - { - get - { - if (_productProductPhotoes == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductProductPhotoes; - _productProductPhotoes = newCollection; - } - return _productProductPhotoes; - } - set - { - if (!ReferenceEquals(_productProductPhotoes, value)) - { - var previousValue = _productProductPhotoes as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductProductPhotoes; - } - _productProductPhotoes = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductProductPhotoes; - } - } - } - } - - private ICollection _productProductPhotoes; - - public virtual ICollection ProductReviews - { - get - { - if (_productReviews == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductReviews; - _productReviews = newCollection; - } - return _productReviews; - } - set - { - if (!ReferenceEquals(_productReviews, value)) - { - var previousValue = _productReviews as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductReviews; - } - _productReviews = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductReviews; - } - } - } - } - - private ICollection _productReviews; - - public virtual ICollection ProductVendors - { - get - { - if (_productVendors == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductVendors; - _productVendors = newCollection; - } - return _productVendors; - } - set - { - if (!ReferenceEquals(_productVendors, value)) - { - var previousValue = _productVendors as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductVendors; - } - _productVendors = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductVendors; - } - } - } - } - - private ICollection _productVendors; - - public virtual ICollection PurchaseOrderDetails - { - get - { - if (_purchaseOrderDetails == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupPurchaseOrderDetails; - _purchaseOrderDetails = newCollection; - } - return _purchaseOrderDetails; - } - set - { - if (!ReferenceEquals(_purchaseOrderDetails, value)) - { - var previousValue = _purchaseOrderDetails as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupPurchaseOrderDetails; - } - _purchaseOrderDetails = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupPurchaseOrderDetails; - } - } - } - } - - private ICollection _purchaseOrderDetails; - - public virtual ICollection ShoppingCartItems - { - get - { - if (_shoppingCartItems == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupShoppingCartItems; - _shoppingCartItems = newCollection; - } - return _shoppingCartItems; - } - set - { - if (!ReferenceEquals(_shoppingCartItems, value)) - { - var previousValue = _shoppingCartItems as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupShoppingCartItems; - } - _shoppingCartItems = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupShoppingCartItems; - } - } - } - } - - private ICollection _shoppingCartItems; - - public virtual ICollection SpecialOfferProducts - { - get - { - if (_specialOfferProducts == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSpecialOfferProducts; - _specialOfferProducts = newCollection; - } - return _specialOfferProducts; - } - set - { - if (!ReferenceEquals(_specialOfferProducts, value)) - { - var previousValue = _specialOfferProducts as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSpecialOfferProducts; - } - _specialOfferProducts = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSpecialOfferProducts; - } - } - } - } - - private ICollection _specialOfferProducts; - - public virtual ICollection TransactionHistories - { - get - { - if (_transactionHistories == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupTransactionHistories; - _transactionHistories = newCollection; - } - return _transactionHistories; - } - set - { - if (!ReferenceEquals(_transactionHistories, value)) - { - var previousValue = _transactionHistories as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupTransactionHistories; - } - _transactionHistories = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupTransactionHistories; - } - } - } - } - - private ICollection _transactionHistories; - - public virtual ICollection WorkOrders - { - get - { - if (_workOrders == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupWorkOrders; - _workOrders = newCollection; - } - return _workOrders; - } - set - { - if (!ReferenceEquals(_workOrders, value)) - { - var previousValue = _workOrders as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupWorkOrders; - } - _workOrders = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupWorkOrders; - } - } - } - } - - private ICollection _workOrders; - - private bool _settingFK; - - private void FixupProductModel(ProductModel previousValue) - { - if (previousValue != null - && previousValue.Products.Contains(this)) - { - previousValue.Products.Remove(this); - } - - if (ProductModel != null) - { - if (!ProductModel.Products.Contains(this)) - { - ProductModel.Products.Add(this); - } - if (ProductModelID != ProductModel.ProductModelID) - { - ProductModelID = ProductModel.ProductModelID; - } - } - else if (!_settingFK) - { - ProductModelID = null; - } - } - - private void FixupProductSubcategory(ProductSubcategory previousValue) - { - if (previousValue != null - && previousValue.Products.Contains(this)) - { - previousValue.Products.Remove(this); - } - - if (ProductSubcategory != null) - { - if (!ProductSubcategory.Products.Contains(this)) - { - ProductSubcategory.Products.Add(this); - } - if (ProductSubcategoryID != ProductSubcategory.ProductSubcategoryID) - { - ProductSubcategoryID = ProductSubcategory.ProductSubcategoryID; - } - } - else if (!_settingFK) - { - ProductSubcategoryID = null; - } - } - - private void FixupBillOfMaterials(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (BillOfMaterials item in e.NewItems) - { - item.Product = this; - } - } - - if (e.OldItems != null) - { - foreach (BillOfMaterials item in e.OldItems) - { - if (ReferenceEquals(item.Product, this)) - { - item.Product = null; - } - } - } - } - - private void FixupBillOfMaterials1(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (BillOfMaterials item in e.NewItems) - { - item.Product1 = this; - } - } - - if (e.OldItems != null) - { - foreach (BillOfMaterials item in e.OldItems) - { - if (ReferenceEquals(item.Product1, this)) - { - item.Product1 = null; - } - } - } - } - - private void FixupProductCostHistories(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductCostHistory item in e.NewItems) - { - item.Product = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductCostHistory item in e.OldItems) - { - if (ReferenceEquals(item.Product, this)) - { - item.Product = null; - } - } - } - } - - private void FixupProductDocuments(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductDocument item in e.NewItems) - { - item.Product = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductDocument item in e.OldItems) - { - if (ReferenceEquals(item.Product, this)) - { - item.Product = null; - } - } - } - } - - private void FixupProductInventories(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductInventory item in e.NewItems) - { - item.Product = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductInventory item in e.OldItems) - { - if (ReferenceEquals(item.Product, this)) - { - item.Product = null; - } - } - } - } - - private void FixupProductListPriceHistories(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductListPriceHistory item in e.NewItems) - { - item.Product = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductListPriceHistory item in e.OldItems) - { - if (ReferenceEquals(item.Product, this)) - { - item.Product = null; - } - } - } - } - - private void FixupProductProductPhotoes(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductProductPhoto item in e.NewItems) - { - item.Product = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductProductPhoto item in e.OldItems) - { - if (ReferenceEquals(item.Product, this)) - { - item.Product = null; - } - } - } - } - - private void FixupProductReviews(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductReview item in e.NewItems) - { - item.Product = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductReview item in e.OldItems) - { - if (ReferenceEquals(item.Product, this)) - { - item.Product = null; - } - } - } - } - - private void FixupProductVendors(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductVendor item in e.NewItems) - { - item.Product = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductVendor item in e.OldItems) - { - if (ReferenceEquals(item.Product, this)) - { - item.Product = null; - } - } - } - } - - private void FixupPurchaseOrderDetails(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (PurchaseOrderDetail item in e.NewItems) - { - item.Product = this; - } - } - - if (e.OldItems != null) - { - foreach (PurchaseOrderDetail item in e.OldItems) - { - if (ReferenceEquals(item.Product, this)) - { - item.Product = null; - } - } - } - } - - private void FixupShoppingCartItems(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ShoppingCartItem item in e.NewItems) - { - item.Product = this; - } - } - - if (e.OldItems != null) - { - foreach (ShoppingCartItem item in e.OldItems) - { - if (ReferenceEquals(item.Product, this)) - { - item.Product = null; - } - } - } - } - - private void FixupSpecialOfferProducts(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SpecialOfferProduct item in e.NewItems) - { - item.Product = this; - } - } - - if (e.OldItems != null) - { - foreach (SpecialOfferProduct item in e.OldItems) - { - if (ReferenceEquals(item.Product, this)) - { - item.Product = null; - } - } - } - } - - private void FixupTransactionHistories(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (TransactionHistory item in e.NewItems) - { - item.Product = this; - } - } - - if (e.OldItems != null) - { - foreach (TransactionHistory item in e.OldItems) - { - if (ReferenceEquals(item.Product, this)) - { - item.Product = null; - } - } - } - } - - private void FixupWorkOrders(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (WorkOrder item in e.NewItems) - { - item.Product = this; - } - } - - if (e.OldItems != null) - { - foreach (WorkOrder item in e.OldItems) - { - if (ReferenceEquals(item.Product, this)) - { - item.Product = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + using System.ComponentModel.DataAnnotations; + + public class Product + { + public virtual int ProductID { get; set; } + + public virtual string Name { get; set; } + + public virtual string ProductNumber { get; set; } + + public virtual bool MakeFlag { get; set; } + + public virtual bool FinishedGoodsFlag { get; set; } + + public virtual short SafetyStockLevel { get; set; } + + public virtual short ReorderPoint { get; set; } + + public virtual decimal StandardCost { get; set; } + + public virtual decimal ListPrice { get; set; } + + public virtual string Size { get; set; } + + public virtual decimal? Weight { get; set; } + + public virtual int DaysToManufacture { get; set; } + + public virtual string ProductLine { get; set; } + + public virtual string Class { get; set; } + + public virtual int? ProductSubcategoryID + { + get { return _productSubcategoryID; } + set + { + try + { + _settingFK = true; + if (_productSubcategoryID != value) + { + if (ProductSubcategory != null + && ProductSubcategory.ProductSubcategoryID != value) + { + ProductSubcategory = null; + } + _productSubcategoryID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int? _productSubcategoryID; + + public virtual int? ProductModelID + { + get { return _productModelID; } + set + { + try + { + _settingFK = true; + if (_productModelID != value) + { + if (ProductModel != null + && ProductModel.ProductModelID != value) + { + ProductModel = null; + } + _productModelID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int? _productModelID; + + public virtual DateTime SellStartDate { get; set; } + + [Required] + public virtual DateTime? SellEndDate { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection BillOfMaterials + { + get + { + if (_billOfMaterials == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupBillOfMaterials; + _billOfMaterials = newCollection; + } + return _billOfMaterials; + } + set + { + if (!ReferenceEquals(_billOfMaterials, value)) + { + var previousValue = _billOfMaterials as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupBillOfMaterials; + } + _billOfMaterials = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupBillOfMaterials; + } + } + } + } + + private ICollection _billOfMaterials; + + public virtual ICollection BillOfMaterials1 + { + get + { + if (_billOfMaterials1 == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupBillOfMaterials1; + _billOfMaterials1 = newCollection; + } + return _billOfMaterials1; + } + set + { + if (!ReferenceEquals(_billOfMaterials1, value)) + { + var previousValue = _billOfMaterials1 as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupBillOfMaterials1; + } + _billOfMaterials1 = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupBillOfMaterials1; + } + } + } + } + + private ICollection _billOfMaterials1; + + public virtual ProductModel ProductModel + { + get { return _productModel; } + set + { + if (!ReferenceEquals(_productModel, value)) + { + var previousValue = _productModel; + _productModel = value; + FixupProductModel(previousValue); + } + } + } + + private ProductModel _productModel; + + public virtual ProductSubcategory ProductSubcategory + { + get { return _productSubcategory; } + set + { + if (!ReferenceEquals(_productSubcategory, value)) + { + var previousValue = _productSubcategory; + _productSubcategory = value; + FixupProductSubcategory(previousValue); + } + } + } + + private ProductSubcategory _productSubcategory; + + public virtual UnitMeasure SizeUnitMeasure { get; set; } + public virtual UnitMeasure WeightUnitMeasure { get; set; } + + public virtual ICollection ProductCostHistories + { + get + { + if (_productCostHistories == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductCostHistories; + _productCostHistories = newCollection; + } + return _productCostHistories; + } + set + { + if (!ReferenceEquals(_productCostHistories, value)) + { + var previousValue = _productCostHistories as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductCostHistories; + } + _productCostHistories = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductCostHistories; + } + } + } + } + + private ICollection _productCostHistories; + + public virtual ICollection ProductDocuments + { + get + { + if (_productDocuments == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductDocuments; + _productDocuments = newCollection; + } + return _productDocuments; + } + set + { + if (!ReferenceEquals(_productDocuments, value)) + { + var previousValue = _productDocuments as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductDocuments; + } + _productDocuments = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductDocuments; + } + } + } + } + + private ICollection _productDocuments; + + public virtual ICollection ProductInventories + { + get + { + if (_productInventories == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductInventories; + _productInventories = newCollection; + } + return _productInventories; + } + set + { + if (!ReferenceEquals(_productInventories, value)) + { + var previousValue = _productInventories as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductInventories; + } + _productInventories = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductInventories; + } + } + } + } + + private ICollection _productInventories; + + public virtual ICollection ProductListPriceHistories + { + get + { + if (_productListPriceHistories == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductListPriceHistories; + _productListPriceHistories = newCollection; + } + return _productListPriceHistories; + } + set + { + if (!ReferenceEquals(_productListPriceHistories, value)) + { + var previousValue = _productListPriceHistories as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductListPriceHistories; + } + _productListPriceHistories = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductListPriceHistories; + } + } + } + } + + private ICollection _productListPriceHistories; + + public virtual ICollection ProductProductPhotoes + { + get + { + if (_productProductPhotoes == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductProductPhotoes; + _productProductPhotoes = newCollection; + } + return _productProductPhotoes; + } + set + { + if (!ReferenceEquals(_productProductPhotoes, value)) + { + var previousValue = _productProductPhotoes as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductProductPhotoes; + } + _productProductPhotoes = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductProductPhotoes; + } + } + } + } + + private ICollection _productProductPhotoes; + + public virtual ICollection ProductReviews + { + get + { + if (_productReviews == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductReviews; + _productReviews = newCollection; + } + return _productReviews; + } + set + { + if (!ReferenceEquals(_productReviews, value)) + { + var previousValue = _productReviews as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductReviews; + } + _productReviews = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductReviews; + } + } + } + } + + private ICollection _productReviews; + + public virtual ICollection ProductVendors + { + get + { + if (_productVendors == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductVendors; + _productVendors = newCollection; + } + return _productVendors; + } + set + { + if (!ReferenceEquals(_productVendors, value)) + { + var previousValue = _productVendors as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductVendors; + } + _productVendors = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductVendors; + } + } + } + } + + private ICollection _productVendors; + + public virtual ICollection PurchaseOrderDetails + { + get + { + if (_purchaseOrderDetails == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupPurchaseOrderDetails; + _purchaseOrderDetails = newCollection; + } + return _purchaseOrderDetails; + } + set + { + if (!ReferenceEquals(_purchaseOrderDetails, value)) + { + var previousValue = _purchaseOrderDetails as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupPurchaseOrderDetails; + } + _purchaseOrderDetails = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupPurchaseOrderDetails; + } + } + } + } + + private ICollection _purchaseOrderDetails; + + public virtual ICollection ShoppingCartItems + { + get + { + if (_shoppingCartItems == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupShoppingCartItems; + _shoppingCartItems = newCollection; + } + return _shoppingCartItems; + } + set + { + if (!ReferenceEquals(_shoppingCartItems, value)) + { + var previousValue = _shoppingCartItems as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupShoppingCartItems; + } + _shoppingCartItems = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupShoppingCartItems; + } + } + } + } + + private ICollection _shoppingCartItems; + + public virtual ICollection SpecialOfferProducts + { + get + { + if (_specialOfferProducts == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSpecialOfferProducts; + _specialOfferProducts = newCollection; + } + return _specialOfferProducts; + } + set + { + if (!ReferenceEquals(_specialOfferProducts, value)) + { + var previousValue = _specialOfferProducts as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSpecialOfferProducts; + } + _specialOfferProducts = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSpecialOfferProducts; + } + } + } + } + + private ICollection _specialOfferProducts; + + public virtual ICollection TransactionHistories + { + get + { + if (_transactionHistories == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupTransactionHistories; + _transactionHistories = newCollection; + } + return _transactionHistories; + } + set + { + if (!ReferenceEquals(_transactionHistories, value)) + { + var previousValue = _transactionHistories as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupTransactionHistories; + } + _transactionHistories = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupTransactionHistories; + } + } + } + } + + private ICollection _transactionHistories; + + public virtual ICollection WorkOrders + { + get + { + if (_workOrders == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupWorkOrders; + _workOrders = newCollection; + } + return _workOrders; + } + set + { + if (!ReferenceEquals(_workOrders, value)) + { + var previousValue = _workOrders as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupWorkOrders; + } + _workOrders = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupWorkOrders; + } + } + } + } + + private ICollection _workOrders; + + private bool _settingFK; + + private void FixupProductModel(ProductModel previousValue) + { + if (previousValue != null + && previousValue.Products.Contains(this)) + { + previousValue.Products.Remove(this); + } + + if (ProductModel != null) + { + if (!ProductModel.Products.Contains(this)) + { + ProductModel.Products.Add(this); + } + if (ProductModelID != ProductModel.ProductModelID) + { + ProductModelID = ProductModel.ProductModelID; + } + } + else if (!_settingFK) + { + ProductModelID = null; + } + } + + private void FixupProductSubcategory(ProductSubcategory previousValue) + { + if (previousValue != null + && previousValue.Products.Contains(this)) + { + previousValue.Products.Remove(this); + } + + if (ProductSubcategory != null) + { + if (!ProductSubcategory.Products.Contains(this)) + { + ProductSubcategory.Products.Add(this); + } + if (ProductSubcategoryID != ProductSubcategory.ProductSubcategoryID) + { + ProductSubcategoryID = ProductSubcategory.ProductSubcategoryID; + } + } + else if (!_settingFK) + { + ProductSubcategoryID = null; + } + } + + private void FixupBillOfMaterials(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (BillOfMaterials item in e.NewItems) + { + item.Product = this; + } + } + + if (e.OldItems != null) + { + foreach (BillOfMaterials item in e.OldItems) + { + if (ReferenceEquals(item.Product, this)) + { + item.Product = null; + } + } + } + } + + private void FixupBillOfMaterials1(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (BillOfMaterials item in e.NewItems) + { + item.Product1 = this; + } + } + + if (e.OldItems != null) + { + foreach (BillOfMaterials item in e.OldItems) + { + if (ReferenceEquals(item.Product1, this)) + { + item.Product1 = null; + } + } + } + } + + private void FixupProductCostHistories(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductCostHistory item in e.NewItems) + { + item.Product = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductCostHistory item in e.OldItems) + { + if (ReferenceEquals(item.Product, this)) + { + item.Product = null; + } + } + } + } + + private void FixupProductDocuments(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductDocument item in e.NewItems) + { + item.Product = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductDocument item in e.OldItems) + { + if (ReferenceEquals(item.Product, this)) + { + item.Product = null; + } + } + } + } + + private void FixupProductInventories(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductInventory item in e.NewItems) + { + item.Product = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductInventory item in e.OldItems) + { + if (ReferenceEquals(item.Product, this)) + { + item.Product = null; + } + } + } + } + + private void FixupProductListPriceHistories(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductListPriceHistory item in e.NewItems) + { + item.Product = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductListPriceHistory item in e.OldItems) + { + if (ReferenceEquals(item.Product, this)) + { + item.Product = null; + } + } + } + } + + private void FixupProductProductPhotoes(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductProductPhoto item in e.NewItems) + { + item.Product = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductProductPhoto item in e.OldItems) + { + if (ReferenceEquals(item.Product, this)) + { + item.Product = null; + } + } + } + } + + private void FixupProductReviews(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductReview item in e.NewItems) + { + item.Product = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductReview item in e.OldItems) + { + if (ReferenceEquals(item.Product, this)) + { + item.Product = null; + } + } + } + } + + private void FixupProductVendors(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductVendor item in e.NewItems) + { + item.Product = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductVendor item in e.OldItems) + { + if (ReferenceEquals(item.Product, this)) + { + item.Product = null; + } + } + } + } + + private void FixupPurchaseOrderDetails(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (PurchaseOrderDetail item in e.NewItems) + { + item.Product = this; + } + } + + if (e.OldItems != null) + { + foreach (PurchaseOrderDetail item in e.OldItems) + { + if (ReferenceEquals(item.Product, this)) + { + item.Product = null; + } + } + } + } + + private void FixupShoppingCartItems(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ShoppingCartItem item in e.NewItems) + { + item.Product = this; + } + } + + if (e.OldItems != null) + { + foreach (ShoppingCartItem item in e.OldItems) + { + if (ReferenceEquals(item.Product, this)) + { + item.Product = null; + } + } + } + } + + private void FixupSpecialOfferProducts(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SpecialOfferProduct item in e.NewItems) + { + item.Product = this; + } + } + + if (e.OldItems != null) + { + foreach (SpecialOfferProduct item in e.OldItems) + { + if (ReferenceEquals(item.Product, this)) + { + item.Product = null; + } + } + } + } + + private void FixupTransactionHistories(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (TransactionHistory item in e.NewItems) + { + item.Product = this; + } + } + + if (e.OldItems != null) + { + foreach (TransactionHistory item in e.OldItems) + { + if (ReferenceEquals(item.Product, this)) + { + item.Product = null; + } + } + } + } + + private void FixupWorkOrders(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (WorkOrder item in e.NewItems) + { + item.Product = this; + } + } + + if (e.OldItems != null) + { + foreach (WorkOrder item in e.OldItems) + { + if (ReferenceEquals(item.Product, this)) + { + item.Product = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductCategory.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductCategory.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductCategory.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductCategory.cs index ca3f5b71..75631ac5 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductCategory.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductCategory.cs @@ -1,74 +1,74 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class ProductCategory - { - public virtual int ProductCategoryID { get; set; } - - public virtual string Name { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection ProductSubcategories - { - get - { - if (_productSubcategories == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductSubcategories; - _productSubcategories = newCollection; - } - return _productSubcategories; - } - set - { - if (!ReferenceEquals(_productSubcategories, value)) - { - var previousValue = _productSubcategories as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductSubcategories; - } - _productSubcategories = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductSubcategories; - } - } - } - } - - private ICollection _productSubcategories; - - private void FixupProductSubcategories(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductSubcategory item in e.NewItems) - { - item.ProductCategory = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductSubcategory item in e.OldItems) - { - if (ReferenceEquals(item.ProductCategory, this)) - { - item.ProductCategory = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class ProductCategory + { + public virtual int ProductCategoryID { get; set; } + + public virtual string Name { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection ProductSubcategories + { + get + { + if (_productSubcategories == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductSubcategories; + _productSubcategories = newCollection; + } + return _productSubcategories; + } + set + { + if (!ReferenceEquals(_productSubcategories, value)) + { + var previousValue = _productSubcategories as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductSubcategories; + } + _productSubcategories = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductSubcategories; + } + } + } + } + + private ICollection _productSubcategories; + + private void FixupProductSubcategories(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductSubcategory item in e.NewItems) + { + item.ProductCategory = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductSubcategory item in e.OldItems) + { + if (ReferenceEquals(item.ProductCategory, this)) + { + item.ProductCategory = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductCostHistory.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductCostHistory.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductCostHistory.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductCostHistory.cs index 04ab4dbd..d41da146 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductCostHistory.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductCostHistory.cs @@ -1,73 +1,73 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class ProductCostHistory - { - public virtual int ProductID - { - get { return _productID; } - set - { - if (_productID != value) - { - if (Product != null - && Product.ProductID != value) - { - Product = null; - } - _productID = value; - } - } - } - - private int _productID; - - public virtual DateTime StartDate { get; set; } - - public virtual DateTime? EndDate { get; set; } - - public virtual decimal StandardCost { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Product Product - { - get { return _product; } - set - { - if (!ReferenceEquals(_product, value)) - { - var previousValue = _product; - _product = value; - FixupProduct(previousValue); - } - } - } - - private Product _product; - - private void FixupProduct(Product previousValue) - { - if (previousValue != null - && previousValue.ProductCostHistories.Contains(this)) - { - previousValue.ProductCostHistories.Remove(this); - } - - if (Product != null) - { - if (!Product.ProductCostHistories.Contains(this)) - { - Product.ProductCostHistories.Add(this); - } - if (ProductID != Product.ProductID) - { - ProductID = Product.ProductID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class ProductCostHistory + { + public virtual int ProductID + { + get { return _productID; } + set + { + if (_productID != value) + { + if (Product != null + && Product.ProductID != value) + { + Product = null; + } + _productID = value; + } + } + } + + private int _productID; + + public virtual DateTime StartDate { get; set; } + + public virtual DateTime? EndDate { get; set; } + + public virtual decimal StandardCost { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Product Product + { + get { return _product; } + set + { + if (!ReferenceEquals(_product, value)) + { + var previousValue = _product; + _product = value; + FixupProduct(previousValue); + } + } + } + + private Product _product; + + private void FixupProduct(Product previousValue) + { + if (previousValue != null + && previousValue.ProductCostHistories.Contains(this)) + { + previousValue.ProductCostHistories.Remove(this); + } + + if (Product != null) + { + if (!Product.ProductCostHistories.Contains(this)) + { + Product.ProductCostHistories.Add(this); + } + if (ProductID != Product.ProductID) + { + ProductID = Product.ProductID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductDescription.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductDescription.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductDescription.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductDescription.cs index 6a2970cf..21ee605e 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductDescription.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductDescription.cs @@ -1,18 +1,18 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System.Collections.Generic; - using System.ComponentModel.DataAnnotations; - - public class ProductDescription - { - public virtual int ProductDescriptionID { get; set; } - public virtual string Description { get; set; } - - [Required] - public virtual RowDetails RowDetails { get; set; } - - public virtual ICollection ProductModelProductDescriptionCultures { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + + public class ProductDescription + { + public virtual int ProductDescriptionID { get; set; } + public virtual string Description { get; set; } + + [Required] + public virtual RowDetails RowDetails { get; set; } + + public virtual ICollection ProductModelProductDescriptionCultures { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductDocument.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductDocument.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductDocument.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductDocument.cs index f2d35d12..d90fbb6b 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductDocument.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductDocument.cs @@ -1,123 +1,123 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class ProductDocument - { - public virtual int ProductID - { - get { return _productID; } - set - { - if (_productID != value) - { - if (Product != null - && Product.ProductID != value) - { - Product = null; - } - _productID = value; - } - } - } - - private int _productID; - - public virtual int DocumentID - { - get { return _documentID; } - set - { - if (_documentID != value) - { - if (Document != null - && Document.DocumentID != value) - { - Document = null; - } - _documentID = value; - } - } - } - - private int _documentID; - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Document Document - { - get { return _document; } - set - { - if (!ReferenceEquals(_document, value)) - { - var previousValue = _document; - _document = value; - FixupDocument(previousValue); - } - } - } - - private Document _document; - - public virtual Product Product - { - get { return _product; } - set - { - if (!ReferenceEquals(_product, value)) - { - var previousValue = _product; - _product = value; - FixupProduct(previousValue); - } - } - } - - private Product _product; - - private void FixupDocument(Document previousValue) - { - if (previousValue != null - && previousValue.ProductDocuments.Contains(this)) - { - previousValue.ProductDocuments.Remove(this); - } - - if (Document != null) - { - if (!Document.ProductDocuments.Contains(this)) - { - Document.ProductDocuments.Add(this); - } - if (DocumentID != Document.DocumentID) - { - DocumentID = Document.DocumentID; - } - } - } - - private void FixupProduct(Product previousValue) - { - if (previousValue != null - && previousValue.ProductDocuments.Contains(this)) - { - previousValue.ProductDocuments.Remove(this); - } - - if (Product != null) - { - if (!Product.ProductDocuments.Contains(this)) - { - Product.ProductDocuments.Add(this); - } - if (ProductID != Product.ProductID) - { - ProductID = Product.ProductID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class ProductDocument + { + public virtual int ProductID + { + get { return _productID; } + set + { + if (_productID != value) + { + if (Product != null + && Product.ProductID != value) + { + Product = null; + } + _productID = value; + } + } + } + + private int _productID; + + public virtual int DocumentID + { + get { return _documentID; } + set + { + if (_documentID != value) + { + if (Document != null + && Document.DocumentID != value) + { + Document = null; + } + _documentID = value; + } + } + } + + private int _documentID; + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Document Document + { + get { return _document; } + set + { + if (!ReferenceEquals(_document, value)) + { + var previousValue = _document; + _document = value; + FixupDocument(previousValue); + } + } + } + + private Document _document; + + public virtual Product Product + { + get { return _product; } + set + { + if (!ReferenceEquals(_product, value)) + { + var previousValue = _product; + _product = value; + FixupProduct(previousValue); + } + } + } + + private Product _product; + + private void FixupDocument(Document previousValue) + { + if (previousValue != null + && previousValue.ProductDocuments.Contains(this)) + { + previousValue.ProductDocuments.Remove(this); + } + + if (Document != null) + { + if (!Document.ProductDocuments.Contains(this)) + { + Document.ProductDocuments.Add(this); + } + if (DocumentID != Document.DocumentID) + { + DocumentID = Document.DocumentID; + } + } + } + + private void FixupProduct(Product previousValue) + { + if (previousValue != null + && previousValue.ProductDocuments.Contains(this)) + { + previousValue.ProductDocuments.Remove(this); + } + + if (Product != null) + { + if (!Product.ProductDocuments.Contains(this)) + { + Product.ProductDocuments.Add(this); + } + if (ProductID != Product.ProductID) + { + ProductID = Product.ProductID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductInventory.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductInventory.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductInventory.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductInventory.cs index a8b56c6e..25a876bf 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductInventory.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductInventory.cs @@ -1,131 +1,131 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class ProductInventory - { - public virtual int ProductID - { - get { return _productID; } - set - { - if (_productID != value) - { - if (Product != null - && Product.ProductID != value) - { - Product = null; - } - _productID = value; - } - } - } - - private int _productID; - - public virtual short LocationID - { - get { return _locationID; } - set - { - if (_locationID != value) - { - if (Location != null - && Location.LocationID != value) - { - Location = null; - } - _locationID = value; - } - } - } - - private short _locationID; - - public virtual string Shelf { get; set; } - - public virtual byte Bin { get; set; } - - public virtual short Quantity { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Location Location - { - get { return _location; } - set - { - if (!ReferenceEquals(_location, value)) - { - var previousValue = _location; - _location = value; - FixupLocation(previousValue); - } - } - } - - private Location _location; - - public virtual Product Product - { - get { return _product; } - set - { - if (!ReferenceEquals(_product, value)) - { - var previousValue = _product; - _product = value; - FixupProduct(previousValue); - } - } - } - - private Product _product; - - private void FixupLocation(Location previousValue) - { - if (previousValue != null - && previousValue.ProductInventories.Contains(this)) - { - previousValue.ProductInventories.Remove(this); - } - - if (Location != null) - { - if (!Location.ProductInventories.Contains(this)) - { - Location.ProductInventories.Add(this); - } - if (LocationID != Location.LocationID) - { - LocationID = Location.LocationID.Value; - } - } - } - - private void FixupProduct(Product previousValue) - { - if (previousValue != null - && previousValue.ProductInventories.Contains(this)) - { - previousValue.ProductInventories.Remove(this); - } - - if (Product != null) - { - if (!Product.ProductInventories.Contains(this)) - { - Product.ProductInventories.Add(this); - } - if (ProductID != Product.ProductID) - { - ProductID = Product.ProductID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class ProductInventory + { + public virtual int ProductID + { + get { return _productID; } + set + { + if (_productID != value) + { + if (Product != null + && Product.ProductID != value) + { + Product = null; + } + _productID = value; + } + } + } + + private int _productID; + + public virtual short LocationID + { + get { return _locationID; } + set + { + if (_locationID != value) + { + if (Location != null + && Location.LocationID != value) + { + Location = null; + } + _locationID = value; + } + } + } + + private short _locationID; + + public virtual string Shelf { get; set; } + + public virtual byte Bin { get; set; } + + public virtual short Quantity { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Location Location + { + get { return _location; } + set + { + if (!ReferenceEquals(_location, value)) + { + var previousValue = _location; + _location = value; + FixupLocation(previousValue); + } + } + } + + private Location _location; + + public virtual Product Product + { + get { return _product; } + set + { + if (!ReferenceEquals(_product, value)) + { + var previousValue = _product; + _product = value; + FixupProduct(previousValue); + } + } + } + + private Product _product; + + private void FixupLocation(Location previousValue) + { + if (previousValue != null + && previousValue.ProductInventories.Contains(this)) + { + previousValue.ProductInventories.Remove(this); + } + + if (Location != null) + { + if (!Location.ProductInventories.Contains(this)) + { + Location.ProductInventories.Add(this); + } + if (LocationID != Location.LocationID) + { + LocationID = Location.LocationID.Value; + } + } + } + + private void FixupProduct(Product previousValue) + { + if (previousValue != null + && previousValue.ProductInventories.Contains(this)) + { + previousValue.ProductInventories.Remove(this); + } + + if (Product != null) + { + if (!Product.ProductInventories.Contains(this)) + { + Product.ProductInventories.Add(this); + } + if (ProductID != Product.ProductID) + { + ProductID = Product.ProductID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductListPriceHistory.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductListPriceHistory.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductListPriceHistory.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductListPriceHistory.cs index d0ba3c51..ec698da6 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductListPriceHistory.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductListPriceHistory.cs @@ -1,73 +1,73 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class ProductListPriceHistory - { - public virtual int ProductID - { - get { return _productID; } - set - { - if (_productID != value) - { - if (Product != null - && Product.ProductID != value) - { - Product = null; - } - _productID = value; - } - } - } - - private int _productID; - - public virtual DateTime StartDate { get; set; } - - public virtual DateTime? EndDate { get; set; } - - public virtual decimal ListPrice { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Product Product - { - get { return _product; } - set - { - if (!ReferenceEquals(_product, value)) - { - var previousValue = _product; - _product = value; - FixupProduct(previousValue); - } - } - } - - private Product _product; - - private void FixupProduct(Product previousValue) - { - if (previousValue != null - && previousValue.ProductListPriceHistories.Contains(this)) - { - previousValue.ProductListPriceHistories.Remove(this); - } - - if (Product != null) - { - if (!Product.ProductListPriceHistories.Contains(this)) - { - Product.ProductListPriceHistories.Add(this); - } - if (ProductID != Product.ProductID) - { - ProductID = Product.ProductID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class ProductListPriceHistory + { + public virtual int ProductID + { + get { return _productID; } + set + { + if (_productID != value) + { + if (Product != null + && Product.ProductID != value) + { + Product = null; + } + _productID = value; + } + } + } + + private int _productID; + + public virtual DateTime StartDate { get; set; } + + public virtual DateTime? EndDate { get; set; } + + public virtual decimal ListPrice { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Product Product + { + get { return _product; } + set + { + if (!ReferenceEquals(_product, value)) + { + var previousValue = _product; + _product = value; + FixupProduct(previousValue); + } + } + } + + private Product _product; + + private void FixupProduct(Product previousValue) + { + if (previousValue != null + && previousValue.ProductListPriceHistories.Contains(this)) + { + previousValue.ProductListPriceHistories.Remove(this); + } + + if (Product != null) + { + if (!Product.ProductListPriceHistories.Contains(this)) + { + Product.ProductListPriceHistories.Add(this); + } + if (ProductID != Product.ProductID) + { + ProductID = Product.ProductID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductModel.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductModel.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductModel.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductModel.cs index a14c4f8c..b0f0bcf8 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductModel.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductModel.cs @@ -1,188 +1,188 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class ProductModel - { - public virtual int ProductModelID { get; set; } - - public virtual string Name { get; set; } - - public virtual string CatalogDescription { get; set; } - - public virtual string Instructions { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection Products - { - get - { - if (_products == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProducts; - _products = newCollection; - } - return _products; - } - set - { - if (!ReferenceEquals(_products, value)) - { - var previousValue = _products as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProducts; - } - _products = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProducts; - } - } - } - } - - private ICollection _products; - - public virtual ICollection ProductModelIllustrations - { - get - { - if (_productModelIllustrations == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductModelIllustrations; - _productModelIllustrations = newCollection; - } - return _productModelIllustrations; - } - set - { - if (!ReferenceEquals(_productModelIllustrations, value)) - { - var previousValue = _productModelIllustrations as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductModelIllustrations; - } - _productModelIllustrations = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductModelIllustrations; - } - } - } - } - - private ICollection _productModelIllustrations; - - public virtual ICollection ProductModelProductDescriptionCultures - { - get - { - if (_productModelProductDescriptionCultures == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductModelProductDescriptionCultures; - _productModelProductDescriptionCultures = newCollection; - } - return _productModelProductDescriptionCultures; - } - set - { - if (!ReferenceEquals(_productModelProductDescriptionCultures, value)) - { - var previousValue = _productModelProductDescriptionCultures as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductModelProductDescriptionCultures; - } - _productModelProductDescriptionCultures = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductModelProductDescriptionCultures; - } - } - } - } - - private ICollection _productModelProductDescriptionCultures; - - private void FixupProducts(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (Product item in e.NewItems) - { - item.ProductModel = this; - } - } - - if (e.OldItems != null) - { - foreach (Product item in e.OldItems) - { - if (ReferenceEquals(item.ProductModel, this)) - { - item.ProductModel = null; - } - } - } - } - - private void FixupProductModelIllustrations(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductModelIllustration item in e.NewItems) - { - item.ProductModel = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductModelIllustration item in e.OldItems) - { - if (ReferenceEquals(item.ProductModel, this)) - { - item.ProductModel = null; - } - } - } - } - - private void FixupProductModelProductDescriptionCultures(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductModelProductDescriptionCulture item in e.NewItems) - { - item.ProductModel = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductModelProductDescriptionCulture item in e.OldItems) - { - if (ReferenceEquals(item.ProductModel, this)) - { - item.ProductModel = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class ProductModel + { + public virtual int ProductModelID { get; set; } + + public virtual string Name { get; set; } + + public virtual string CatalogDescription { get; set; } + + public virtual string Instructions { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection Products + { + get + { + if (_products == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProducts; + _products = newCollection; + } + return _products; + } + set + { + if (!ReferenceEquals(_products, value)) + { + var previousValue = _products as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProducts; + } + _products = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProducts; + } + } + } + } + + private ICollection _products; + + public virtual ICollection ProductModelIllustrations + { + get + { + if (_productModelIllustrations == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductModelIllustrations; + _productModelIllustrations = newCollection; + } + return _productModelIllustrations; + } + set + { + if (!ReferenceEquals(_productModelIllustrations, value)) + { + var previousValue = _productModelIllustrations as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductModelIllustrations; + } + _productModelIllustrations = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductModelIllustrations; + } + } + } + } + + private ICollection _productModelIllustrations; + + public virtual ICollection ProductModelProductDescriptionCultures + { + get + { + if (_productModelProductDescriptionCultures == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductModelProductDescriptionCultures; + _productModelProductDescriptionCultures = newCollection; + } + return _productModelProductDescriptionCultures; + } + set + { + if (!ReferenceEquals(_productModelProductDescriptionCultures, value)) + { + var previousValue = _productModelProductDescriptionCultures as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductModelProductDescriptionCultures; + } + _productModelProductDescriptionCultures = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductModelProductDescriptionCultures; + } + } + } + } + + private ICollection _productModelProductDescriptionCultures; + + private void FixupProducts(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (Product item in e.NewItems) + { + item.ProductModel = this; + } + } + + if (e.OldItems != null) + { + foreach (Product item in e.OldItems) + { + if (ReferenceEquals(item.ProductModel, this)) + { + item.ProductModel = null; + } + } + } + } + + private void FixupProductModelIllustrations(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductModelIllustration item in e.NewItems) + { + item.ProductModel = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductModelIllustration item in e.OldItems) + { + if (ReferenceEquals(item.ProductModel, this)) + { + item.ProductModel = null; + } + } + } + } + + private void FixupProductModelProductDescriptionCultures(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductModelProductDescriptionCulture item in e.NewItems) + { + item.ProductModel = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductModelProductDescriptionCulture item in e.OldItems) + { + if (ReferenceEquals(item.ProductModel, this)) + { + item.ProductModel = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductModelIllustration.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductModelIllustration.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductModelIllustration.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductModelIllustration.cs index 8a4f8926..fa318780 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductModelIllustration.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductModelIllustration.cs @@ -1,123 +1,123 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class ProductModelIllustration - { - public virtual int ProductModelID - { - get { return _productModelID; } - set - { - if (_productModelID != value) - { - if (ProductModel != null - && ProductModel.ProductModelID != value) - { - ProductModel = null; - } - _productModelID = value; - } - } - } - - private int _productModelID; - - public virtual int IllustrationID - { - get { return _illustrationID; } - set - { - if (_illustrationID != value) - { - if (Illustration != null - && Illustration.IllustrationID != value) - { - Illustration = null; - } - _illustrationID = value; - } - } - } - - private int _illustrationID; - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Illustration Illustration - { - get { return _illustration; } - set - { - if (!ReferenceEquals(_illustration, value)) - { - var previousValue = _illustration; - _illustration = value; - FixupIllustration(previousValue); - } - } - } - - private Illustration _illustration; - - public virtual ProductModel ProductModel - { - get { return _productModel; } - set - { - if (!ReferenceEquals(_productModel, value)) - { - var previousValue = _productModel; - _productModel = value; - FixupProductModel(previousValue); - } - } - } - - private ProductModel _productModel; - - private void FixupIllustration(Illustration previousValue) - { - if (previousValue != null - && previousValue.ProductModelIllustrations.Contains(this)) - { - previousValue.ProductModelIllustrations.Remove(this); - } - - if (Illustration != null) - { - if (!Illustration.ProductModelIllustrations.Contains(this)) - { - Illustration.ProductModelIllustrations.Add(this); - } - if (IllustrationID != Illustration.IllustrationID) - { - IllustrationID = Illustration.IllustrationID; - } - } - } - - private void FixupProductModel(ProductModel previousValue) - { - if (previousValue != null - && previousValue.ProductModelIllustrations.Contains(this)) - { - previousValue.ProductModelIllustrations.Remove(this); - } - - if (ProductModel != null) - { - if (!ProductModel.ProductModelIllustrations.Contains(this)) - { - ProductModel.ProductModelIllustrations.Add(this); - } - if (ProductModelID != ProductModel.ProductModelID) - { - ProductModelID = ProductModel.ProductModelID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class ProductModelIllustration + { + public virtual int ProductModelID + { + get { return _productModelID; } + set + { + if (_productModelID != value) + { + if (ProductModel != null + && ProductModel.ProductModelID != value) + { + ProductModel = null; + } + _productModelID = value; + } + } + } + + private int _productModelID; + + public virtual int IllustrationID + { + get { return _illustrationID; } + set + { + if (_illustrationID != value) + { + if (Illustration != null + && Illustration.IllustrationID != value) + { + Illustration = null; + } + _illustrationID = value; + } + } + } + + private int _illustrationID; + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Illustration Illustration + { + get { return _illustration; } + set + { + if (!ReferenceEquals(_illustration, value)) + { + var previousValue = _illustration; + _illustration = value; + FixupIllustration(previousValue); + } + } + } + + private Illustration _illustration; + + public virtual ProductModel ProductModel + { + get { return _productModel; } + set + { + if (!ReferenceEquals(_productModel, value)) + { + var previousValue = _productModel; + _productModel = value; + FixupProductModel(previousValue); + } + } + } + + private ProductModel _productModel; + + private void FixupIllustration(Illustration previousValue) + { + if (previousValue != null + && previousValue.ProductModelIllustrations.Contains(this)) + { + previousValue.ProductModelIllustrations.Remove(this); + } + + if (Illustration != null) + { + if (!Illustration.ProductModelIllustrations.Contains(this)) + { + Illustration.ProductModelIllustrations.Add(this); + } + if (IllustrationID != Illustration.IllustrationID) + { + IllustrationID = Illustration.IllustrationID; + } + } + } + + private void FixupProductModel(ProductModel previousValue) + { + if (previousValue != null + && previousValue.ProductModelIllustrations.Contains(this)) + { + previousValue.ProductModelIllustrations.Remove(this); + } + + if (ProductModel != null) + { + if (!ProductModel.ProductModelIllustrations.Contains(this)) + { + ProductModel.ProductModelIllustrations.Add(this); + } + if (ProductModelID != ProductModel.ProductModelID) + { + ProductModelID = ProductModel.ProductModelID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductModelProductDescriptionCulture.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductModelProductDescriptionCulture.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductModelProductDescriptionCulture.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductModelProductDescriptionCulture.cs index f3965840..e57ec08f 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductModelProductDescriptionCulture.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductModelProductDescriptionCulture.cs @@ -1,179 +1,179 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class ProductModelProductDescriptionCulture - { - public virtual int ProductModelID - { - get { return _productModelID; } - set - { - if (_productModelID != value) - { - if (ProductModel != null - && ProductModel.ProductModelID != value) - { - ProductModel = null; - } - _productModelID = value; - } - } - } - - private int _productModelID; - - public virtual int ProductDescriptionID - { - get { return _productDescriptionID; } - set - { - if (_productDescriptionID != value) - { - if (ProductDescription != null - && ProductDescription.ProductDescriptionID != value) - { - ProductDescription = null; - } - _productDescriptionID = value; - } - } - } - - private int _productDescriptionID; - - public virtual string CultureID - { - get { return _cultureID; } - set - { - if (_cultureID != value) - { - if (Culture != null - && Culture.CultureID != value) - { - Culture = null; - } - _cultureID = value; - } - } - } - - private string _cultureID; - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Culture Culture - { - get { return _culture; } - set - { - if (!ReferenceEquals(_culture, value)) - { - var previousValue = _culture; - _culture = value; - FixupCulture(previousValue); - } - } - } - - private Culture _culture; - - public virtual ProductDescription ProductDescription - { - get { return _productDescription; } - set - { - if (!ReferenceEquals(_productDescription, value)) - { - var previousValue = _productDescription; - _productDescription = value; - FixupProductDescription(previousValue); - } - } - } - - private ProductDescription _productDescription; - - public virtual ProductModel ProductModel - { - get { return _productModel; } - set - { - if (!ReferenceEquals(_productModel, value)) - { - var previousValue = _productModel; - _productModel = value; - FixupProductModel(previousValue); - } - } - } - - private ProductModel _productModel; - - private void FixupCulture(Culture previousValue) - { - if (previousValue != null - && previousValue.ProductModelProductDescriptionCultures.Contains(this)) - { - previousValue.ProductModelProductDescriptionCultures.Remove(this); - } - - if (Culture != null) - { - if (!Culture.ProductModelProductDescriptionCultures.Contains(this)) - { - Culture.ProductModelProductDescriptionCultures.Add(this); - } - if (CultureID != Culture.CultureID) - { - CultureID = Culture.CultureID; - } - } - } - - private void FixupProductDescription(ProductDescription previousValue) - { - if (previousValue != null - && previousValue.ProductModelProductDescriptionCultures.Contains(this)) - { - previousValue.ProductModelProductDescriptionCultures.Remove(this); - } - - if (ProductDescription != null) - { - if (!ProductDescription.ProductModelProductDescriptionCultures.Contains(this)) - { - ProductDescription.ProductModelProductDescriptionCultures.Add(this); - } - if (ProductDescriptionID != ProductDescription.ProductDescriptionID) - { - ProductDescriptionID = ProductDescription.ProductDescriptionID; - } - } - } - - private void FixupProductModel(ProductModel previousValue) - { - if (previousValue != null - && previousValue.ProductModelProductDescriptionCultures.Contains(this)) - { - previousValue.ProductModelProductDescriptionCultures.Remove(this); - } - - if (ProductModel != null) - { - if (!ProductModel.ProductModelProductDescriptionCultures.Contains(this)) - { - ProductModel.ProductModelProductDescriptionCultures.Add(this); - } - if (ProductModelID != ProductModel.ProductModelID) - { - ProductModelID = ProductModel.ProductModelID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class ProductModelProductDescriptionCulture + { + public virtual int ProductModelID + { + get { return _productModelID; } + set + { + if (_productModelID != value) + { + if (ProductModel != null + && ProductModel.ProductModelID != value) + { + ProductModel = null; + } + _productModelID = value; + } + } + } + + private int _productModelID; + + public virtual int ProductDescriptionID + { + get { return _productDescriptionID; } + set + { + if (_productDescriptionID != value) + { + if (ProductDescription != null + && ProductDescription.ProductDescriptionID != value) + { + ProductDescription = null; + } + _productDescriptionID = value; + } + } + } + + private int _productDescriptionID; + + public virtual string CultureID + { + get { return _cultureID; } + set + { + if (_cultureID != value) + { + if (Culture != null + && Culture.CultureID != value) + { + Culture = null; + } + _cultureID = value; + } + } + } + + private string _cultureID; + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Culture Culture + { + get { return _culture; } + set + { + if (!ReferenceEquals(_culture, value)) + { + var previousValue = _culture; + _culture = value; + FixupCulture(previousValue); + } + } + } + + private Culture _culture; + + public virtual ProductDescription ProductDescription + { + get { return _productDescription; } + set + { + if (!ReferenceEquals(_productDescription, value)) + { + var previousValue = _productDescription; + _productDescription = value; + FixupProductDescription(previousValue); + } + } + } + + private ProductDescription _productDescription; + + public virtual ProductModel ProductModel + { + get { return _productModel; } + set + { + if (!ReferenceEquals(_productModel, value)) + { + var previousValue = _productModel; + _productModel = value; + FixupProductModel(previousValue); + } + } + } + + private ProductModel _productModel; + + private void FixupCulture(Culture previousValue) + { + if (previousValue != null + && previousValue.ProductModelProductDescriptionCultures.Contains(this)) + { + previousValue.ProductModelProductDescriptionCultures.Remove(this); + } + + if (Culture != null) + { + if (!Culture.ProductModelProductDescriptionCultures.Contains(this)) + { + Culture.ProductModelProductDescriptionCultures.Add(this); + } + if (CultureID != Culture.CultureID) + { + CultureID = Culture.CultureID; + } + } + } + + private void FixupProductDescription(ProductDescription previousValue) + { + if (previousValue != null + && previousValue.ProductModelProductDescriptionCultures.Contains(this)) + { + previousValue.ProductModelProductDescriptionCultures.Remove(this); + } + + if (ProductDescription != null) + { + if (!ProductDescription.ProductModelProductDescriptionCultures.Contains(this)) + { + ProductDescription.ProductModelProductDescriptionCultures.Add(this); + } + if (ProductDescriptionID != ProductDescription.ProductDescriptionID) + { + ProductDescriptionID = ProductDescription.ProductDescriptionID; + } + } + } + + private void FixupProductModel(ProductModel previousValue) + { + if (previousValue != null + && previousValue.ProductModelProductDescriptionCultures.Contains(this)) + { + previousValue.ProductModelProductDescriptionCultures.Remove(this); + } + + if (ProductModel != null) + { + if (!ProductModel.ProductModelProductDescriptionCultures.Contains(this)) + { + ProductModel.ProductModelProductDescriptionCultures.Add(this); + } + if (ProductModelID != ProductModel.ProductModelID) + { + ProductModelID = ProductModel.ProductModelID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductPhoto.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductPhoto.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductPhoto.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductPhoto.cs index d1b67b64..f6655960 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductPhoto.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductPhoto.cs @@ -1,83 +1,83 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class LargePhoto - { - public virtual byte[] Photo { get; set; } - } - - public class ProductPhoto - { - public virtual int ProductPhotoID { get; set; } - - public virtual byte[] ThumbNailPhoto { get; set; } - - public virtual string ThumbnailPhotoFileName { get; set; } - - public virtual LargePhoto LargePhoto { get; set; } - - public virtual string LargePhotoFileName { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection ProductProductPhotoes - { - get - { - if (_productProductPhotoes == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductProductPhotoes; - _productProductPhotoes = newCollection; - } - return _productProductPhotoes; - } - set - { - if (!ReferenceEquals(_productProductPhotoes, value)) - { - var previousValue = _productProductPhotoes as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductProductPhotoes; - } - _productProductPhotoes = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductProductPhotoes; - } - } - } - } - - private ICollection _productProductPhotoes; - - private void FixupProductProductPhotoes(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductProductPhoto item in e.NewItems) - { - item.ProductPhoto = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductProductPhoto item in e.OldItems) - { - if (ReferenceEquals(item.ProductPhoto, this)) - { - item.ProductPhoto = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class LargePhoto + { + public virtual byte[] Photo { get; set; } + } + + public class ProductPhoto + { + public virtual int ProductPhotoID { get; set; } + + public virtual byte[] ThumbNailPhoto { get; set; } + + public virtual string ThumbnailPhotoFileName { get; set; } + + public virtual LargePhoto LargePhoto { get; set; } + + public virtual string LargePhotoFileName { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection ProductProductPhotoes + { + get + { + if (_productProductPhotoes == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductProductPhotoes; + _productProductPhotoes = newCollection; + } + return _productProductPhotoes; + } + set + { + if (!ReferenceEquals(_productProductPhotoes, value)) + { + var previousValue = _productProductPhotoes as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductProductPhotoes; + } + _productProductPhotoes = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductProductPhotoes; + } + } + } + } + + private ICollection _productProductPhotoes; + + private void FixupProductProductPhotoes(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductProductPhoto item in e.NewItems) + { + item.ProductPhoto = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductProductPhoto item in e.OldItems) + { + if (ReferenceEquals(item.ProductPhoto, this)) + { + item.ProductPhoto = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductProductPhoto.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductProductPhoto.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductProductPhoto.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductProductPhoto.cs index 4aedb92a..dbea99bd 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductProductPhoto.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductProductPhoto.cs @@ -1,125 +1,125 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class ProductProductPhoto - { - public virtual int ProductID - { - get { return _productID; } - set - { - if (_productID != value) - { - if (Product != null - && Product.ProductID != value) - { - Product = null; - } - _productID = value; - } - } - } - - private int _productID; - - public virtual int ProductPhotoID - { - get { return _productPhotoID; } - set - { - if (_productPhotoID != value) - { - if (ProductPhoto != null - && ProductPhoto.ProductPhotoID != value) - { - ProductPhoto = null; - } - _productPhotoID = value; - } - } - } - - private int _productPhotoID; - - public virtual bool Primary { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Product Product - { - get { return _product; } - set - { - if (!ReferenceEquals(_product, value)) - { - var previousValue = _product; - _product = value; - FixupProduct(previousValue); - } - } - } - - private Product _product; - - public virtual ProductPhoto ProductPhoto - { - get { return _productPhoto; } - set - { - if (!ReferenceEquals(_productPhoto, value)) - { - var previousValue = _productPhoto; - _productPhoto = value; - FixupProductPhoto(previousValue); - } - } - } - - private ProductPhoto _productPhoto; - - private void FixupProduct(Product previousValue) - { - if (previousValue != null - && previousValue.ProductProductPhotoes.Contains(this)) - { - previousValue.ProductProductPhotoes.Remove(this); - } - - if (Product != null) - { - if (!Product.ProductProductPhotoes.Contains(this)) - { - Product.ProductProductPhotoes.Add(this); - } - if (ProductID != Product.ProductID) - { - ProductID = Product.ProductID; - } - } - } - - private void FixupProductPhoto(ProductPhoto previousValue) - { - if (previousValue != null - && previousValue.ProductProductPhotoes.Contains(this)) - { - previousValue.ProductProductPhotoes.Remove(this); - } - - if (ProductPhoto != null) - { - if (!ProductPhoto.ProductProductPhotoes.Contains(this)) - { - ProductPhoto.ProductProductPhotoes.Add(this); - } - if (ProductPhotoID != ProductPhoto.ProductPhotoID) - { - ProductPhotoID = ProductPhoto.ProductPhotoID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class ProductProductPhoto + { + public virtual int ProductID + { + get { return _productID; } + set + { + if (_productID != value) + { + if (Product != null + && Product.ProductID != value) + { + Product = null; + } + _productID = value; + } + } + } + + private int _productID; + + public virtual int ProductPhotoID + { + get { return _productPhotoID; } + set + { + if (_productPhotoID != value) + { + if (ProductPhoto != null + && ProductPhoto.ProductPhotoID != value) + { + ProductPhoto = null; + } + _productPhotoID = value; + } + } + } + + private int _productPhotoID; + + public virtual bool Primary { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Product Product + { + get { return _product; } + set + { + if (!ReferenceEquals(_product, value)) + { + var previousValue = _product; + _product = value; + FixupProduct(previousValue); + } + } + } + + private Product _product; + + public virtual ProductPhoto ProductPhoto + { + get { return _productPhoto; } + set + { + if (!ReferenceEquals(_productPhoto, value)) + { + var previousValue = _productPhoto; + _productPhoto = value; + FixupProductPhoto(previousValue); + } + } + } + + private ProductPhoto _productPhoto; + + private void FixupProduct(Product previousValue) + { + if (previousValue != null + && previousValue.ProductProductPhotoes.Contains(this)) + { + previousValue.ProductProductPhotoes.Remove(this); + } + + if (Product != null) + { + if (!Product.ProductProductPhotoes.Contains(this)) + { + Product.ProductProductPhotoes.Add(this); + } + if (ProductID != Product.ProductID) + { + ProductID = Product.ProductID; + } + } + } + + private void FixupProductPhoto(ProductPhoto previousValue) + { + if (previousValue != null + && previousValue.ProductProductPhotoes.Contains(this)) + { + previousValue.ProductProductPhotoes.Remove(this); + } + + if (ProductPhoto != null) + { + if (!ProductPhoto.ProductProductPhotoes.Contains(this)) + { + ProductPhoto.ProductProductPhotoes.Add(this); + } + if (ProductPhotoID != ProductPhoto.ProductPhotoID) + { + ProductPhotoID = ProductPhoto.ProductPhotoID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductReview.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductReview.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductReview.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductReview.cs index 7a579fe7..236d1033 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductReview.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductReview.cs @@ -1,79 +1,79 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class ProductReview - { - public virtual int ProductReviewID { get; set; } - - public virtual int ProductID - { - get { return _productID; } - set - { - if (_productID != value) - { - if (Product != null - && Product.ProductID != value) - { - Product = null; - } - _productID = value; - } - } - } - - private int _productID; - - public virtual string ReviewerName { get; set; } - - public virtual DateTime ReviewDate { get; set; } - - public virtual string EmailAddress { get; set; } - - public virtual int Rating { get; set; } - - public virtual string Comments { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Product Product - { - get { return _product; } - set - { - if (!ReferenceEquals(_product, value)) - { - var previousValue = _product; - _product = value; - FixupProduct(previousValue); - } - } - } - - private Product _product; - - private void FixupProduct(Product previousValue) - { - if (previousValue != null - && previousValue.ProductReviews.Contains(this)) - { - previousValue.ProductReviews.Remove(this); - } - - if (Product != null) - { - if (!Product.ProductReviews.Contains(this)) - { - Product.ProductReviews.Add(this); - } - if (ProductID != Product.ProductID) - { - ProductID = Product.ProductID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class ProductReview + { + public virtual int ProductReviewID { get; set; } + + public virtual int ProductID + { + get { return _productID; } + set + { + if (_productID != value) + { + if (Product != null + && Product.ProductID != value) + { + Product = null; + } + _productID = value; + } + } + } + + private int _productID; + + public virtual string ReviewerName { get; set; } + + public virtual DateTime ReviewDate { get; set; } + + public virtual string EmailAddress { get; set; } + + public virtual int Rating { get; set; } + + public virtual string Comments { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Product Product + { + get { return _product; } + set + { + if (!ReferenceEquals(_product, value)) + { + var previousValue = _product; + _product = value; + FixupProduct(previousValue); + } + } + } + + private Product _product; + + private void FixupProduct(Product previousValue) + { + if (previousValue != null + && previousValue.ProductReviews.Contains(this)) + { + previousValue.ProductReviews.Remove(this); + } + + if (Product != null) + { + if (!Product.ProductReviews.Contains(this)) + { + Product.ProductReviews.Add(this); + } + if (ProductID != Product.ProductID) + { + ProductID = Product.ProductID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductSubcategory.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductSubcategory.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductSubcategory.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductSubcategory.cs index e3aeabff..c4fd38bf 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductSubcategory.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductSubcategory.cs @@ -1,130 +1,130 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class ProductSubcategory - { - public virtual int ProductSubcategoryID { get; set; } - - public virtual int ProductCategoryID - { - get { return _productCategoryID; } - set - { - if (_productCategoryID != value) - { - if (ProductCategory != null - && ProductCategory.ProductCategoryID != value) - { - ProductCategory = null; - } - _productCategoryID = value; - } - } - } - - private int _productCategoryID; - - public virtual string Name { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection Products - { - get - { - if (_products == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProducts; - _products = newCollection; - } - return _products; - } - set - { - if (!ReferenceEquals(_products, value)) - { - var previousValue = _products as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProducts; - } - _products = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProducts; - } - } - } - } - - private ICollection _products; - - public virtual ProductCategory ProductCategory - { - get { return _productCategory; } - set - { - if (!ReferenceEquals(_productCategory, value)) - { - var previousValue = _productCategory; - _productCategory = value; - FixupProductCategory(previousValue); - } - } - } - - private ProductCategory _productCategory; - - private void FixupProductCategory(ProductCategory previousValue) - { - if (previousValue != null - && previousValue.ProductSubcategories.Contains(this)) - { - previousValue.ProductSubcategories.Remove(this); - } - - if (ProductCategory != null) - { - if (!ProductCategory.ProductSubcategories.Contains(this)) - { - ProductCategory.ProductSubcategories.Add(this); - } - if (ProductCategoryID != ProductCategory.ProductCategoryID) - { - ProductCategoryID = ProductCategory.ProductCategoryID; - } - } - } - - private void FixupProducts(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (Product item in e.NewItems) - { - item.ProductSubcategory = this; - } - } - - if (e.OldItems != null) - { - foreach (Product item in e.OldItems) - { - if (ReferenceEquals(item.ProductSubcategory, this)) - { - item.ProductSubcategory = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class ProductSubcategory + { + public virtual int ProductSubcategoryID { get; set; } + + public virtual int ProductCategoryID + { + get { return _productCategoryID; } + set + { + if (_productCategoryID != value) + { + if (ProductCategory != null + && ProductCategory.ProductCategoryID != value) + { + ProductCategory = null; + } + _productCategoryID = value; + } + } + } + + private int _productCategoryID; + + public virtual string Name { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection Products + { + get + { + if (_products == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProducts; + _products = newCollection; + } + return _products; + } + set + { + if (!ReferenceEquals(_products, value)) + { + var previousValue = _products as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProducts; + } + _products = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProducts; + } + } + } + } + + private ICollection _products; + + public virtual ProductCategory ProductCategory + { + get { return _productCategory; } + set + { + if (!ReferenceEquals(_productCategory, value)) + { + var previousValue = _productCategory; + _productCategory = value; + FixupProductCategory(previousValue); + } + } + } + + private ProductCategory _productCategory; + + private void FixupProductCategory(ProductCategory previousValue) + { + if (previousValue != null + && previousValue.ProductSubcategories.Contains(this)) + { + previousValue.ProductSubcategories.Remove(this); + } + + if (ProductCategory != null) + { + if (!ProductCategory.ProductSubcategories.Contains(this)) + { + ProductCategory.ProductSubcategories.Add(this); + } + if (ProductCategoryID != ProductCategory.ProductCategoryID) + { + ProductCategoryID = ProductCategory.ProductCategoryID; + } + } + } + + private void FixupProducts(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (Product item in e.NewItems) + { + item.ProductSubcategory = this; + } + } + + if (e.OldItems != null) + { + foreach (Product item in e.OldItems) + { + if (ReferenceEquals(item.ProductSubcategory, this)) + { + item.ProductSubcategory = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductVendor.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductVendor.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductVendor.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductVendor.cs index 91646eee..10dcba6c 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ProductVendor.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ProductVendor.cs @@ -1,158 +1,158 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class ProductVendor - { - public virtual int ProductID - { - get { return _productID; } - set - { - if (_productID != value) - { - if (Product != null - && Product.ProductID != value) - { - Product = null; - } - _productID = value; - } - } - } - - private int _productID; - - public virtual int VendorID - { - get { return _vendorID; } - set - { - if (_vendorID != value) - { - if (Vendor != null - && Vendor.VendorID != value) - { - Vendor = null; - } - _vendorID = value; - } - } - } - - private int _vendorID; - - public virtual int AverageLeadTime { get; set; } - - public virtual decimal StandardPrice { get; set; } - - public virtual decimal? LastReceiptCost { get; set; } - - public virtual DateTime? LastReceiptDate { get; set; } - - public virtual int MinOrderQty { get; set; } - - public virtual int MaxOrderQty { get; set; } - - public virtual int? OnOrderQty { get; set; } - - public virtual string UnitMeasureCode - { - get { return _unitMeasureCode; } - set - { - if (_unitMeasureCode != value) - { - if (UnitMeasure != null - && UnitMeasure.UnitMeasureCode != value) - { - UnitMeasure = null; - } - _unitMeasureCode = value; - } - } - } - - private string _unitMeasureCode; - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Product Product - { - get { return _product; } - set - { - if (!ReferenceEquals(_product, value)) - { - var previousValue = _product; - _product = value; - FixupProduct(previousValue); - } - } - } - - private Product _product; - - public virtual UnitMeasure UnitMeasure { get; set; } - - public virtual Vendor Vendor - { - get { return _vendor; } - set - { - if (!ReferenceEquals(_vendor, value)) - { - var previousValue = _vendor; - _vendor = value; - FixupVendor(previousValue); - } - } - } - - private Vendor _vendor; - - private void FixupProduct(Product previousValue) - { - if (previousValue != null - && previousValue.ProductVendors.Contains(this)) - { - previousValue.ProductVendors.Remove(this); - } - - if (Product != null) - { - if (!Product.ProductVendors.Contains(this)) - { - Product.ProductVendors.Add(this); - } - if (ProductID != Product.ProductID) - { - ProductID = Product.ProductID; - } - } - } - - private void FixupVendor(Vendor previousValue) - { - if (previousValue != null - && previousValue.ProductVendors.Contains(this)) - { - previousValue.ProductVendors.Remove(this); - } - - if (Vendor != null) - { - if (!Vendor.ProductVendors.Contains(this)) - { - Vendor.ProductVendors.Add(this); - } - if (VendorID != Vendor.VendorID) - { - VendorID = Vendor.VendorID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class ProductVendor + { + public virtual int ProductID + { + get { return _productID; } + set + { + if (_productID != value) + { + if (Product != null + && Product.ProductID != value) + { + Product = null; + } + _productID = value; + } + } + } + + private int _productID; + + public virtual int VendorID + { + get { return _vendorID; } + set + { + if (_vendorID != value) + { + if (Vendor != null + && Vendor.VendorID != value) + { + Vendor = null; + } + _vendorID = value; + } + } + } + + private int _vendorID; + + public virtual int AverageLeadTime { get; set; } + + public virtual decimal StandardPrice { get; set; } + + public virtual decimal? LastReceiptCost { get; set; } + + public virtual DateTime? LastReceiptDate { get; set; } + + public virtual int MinOrderQty { get; set; } + + public virtual int MaxOrderQty { get; set; } + + public virtual int? OnOrderQty { get; set; } + + public virtual string UnitMeasureCode + { + get { return _unitMeasureCode; } + set + { + if (_unitMeasureCode != value) + { + if (UnitMeasure != null + && UnitMeasure.UnitMeasureCode != value) + { + UnitMeasure = null; + } + _unitMeasureCode = value; + } + } + } + + private string _unitMeasureCode; + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Product Product + { + get { return _product; } + set + { + if (!ReferenceEquals(_product, value)) + { + var previousValue = _product; + _product = value; + FixupProduct(previousValue); + } + } + } + + private Product _product; + + public virtual UnitMeasure UnitMeasure { get; set; } + + public virtual Vendor Vendor + { + get { return _vendor; } + set + { + if (!ReferenceEquals(_vendor, value)) + { + var previousValue = _vendor; + _vendor = value; + FixupVendor(previousValue); + } + } + } + + private Vendor _vendor; + + private void FixupProduct(Product previousValue) + { + if (previousValue != null + && previousValue.ProductVendors.Contains(this)) + { + previousValue.ProductVendors.Remove(this); + } + + if (Product != null) + { + if (!Product.ProductVendors.Contains(this)) + { + Product.ProductVendors.Add(this); + } + if (ProductID != Product.ProductID) + { + ProductID = Product.ProductID; + } + } + } + + private void FixupVendor(Vendor previousValue) + { + if (previousValue != null + && previousValue.ProductVendors.Contains(this)) + { + previousValue.ProductVendors.Remove(this); + } + + if (Vendor != null) + { + if (!Vendor.ProductVendors.Contains(this)) + { + Vendor.ProductVendors.Add(this); + } + if (VendorID != Vendor.VendorID) + { + VendorID = Vendor.VendorID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/PurchaseOrderDetail.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/PurchaseOrderDetail.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/PurchaseOrderDetail.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/PurchaseOrderDetail.cs index 16391e57..14603c92 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/PurchaseOrderDetail.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/PurchaseOrderDetail.cs @@ -1,139 +1,139 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class PurchaseOrderDetail - { - public virtual int PurchaseOrderID - { - get { return _purchaseOrderID; } - set - { - if (_purchaseOrderID != value) - { - if (PurchaseOrderHeader != null - && PurchaseOrderHeader.PurchaseOrderID != value) - { - PurchaseOrderHeader = null; - } - _purchaseOrderID = value; - } - } - } - - private int _purchaseOrderID; - - public virtual int PurchaseOrderDetailID { get; set; } - - public virtual DateTime DueDate { get; set; } - - public virtual short OrderQty { get; set; } - - public virtual int ProductID - { - get { return _productID; } - set - { - if (_productID != value) - { - if (Product != null - && Product.ProductID != value) - { - Product = null; - } - _productID = value; - } - } - } - - private int _productID; - - public virtual decimal UnitPrice { get; set; } - - public virtual decimal LineTotal { get; set; } - - public virtual decimal ReceivedQty { get; set; } - - public virtual decimal RejectedQty { get; set; } - - public virtual decimal StockedQty { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Product Product - { - get { return _product; } - set - { - if (!ReferenceEquals(_product, value)) - { - var previousValue = _product; - _product = value; - FixupProduct(previousValue); - } - } - } - - private Product _product; - - public virtual PurchaseOrderHeader PurchaseOrderHeader - { - get { return _purchaseOrderHeader; } - set - { - if (!ReferenceEquals(_purchaseOrderHeader, value)) - { - var previousValue = _purchaseOrderHeader; - _purchaseOrderHeader = value; - FixupPurchaseOrderHeader(previousValue); - } - } - } - - private PurchaseOrderHeader _purchaseOrderHeader; - - private void FixupProduct(Product previousValue) - { - if (previousValue != null - && previousValue.PurchaseOrderDetails.Contains(this)) - { - previousValue.PurchaseOrderDetails.Remove(this); - } - - if (Product != null) - { - if (!Product.PurchaseOrderDetails.Contains(this)) - { - Product.PurchaseOrderDetails.Add(this); - } - if (ProductID != Product.ProductID) - { - ProductID = Product.ProductID; - } - } - } - - private void FixupPurchaseOrderHeader(PurchaseOrderHeader previousValue) - { - if (previousValue != null - && previousValue.PurchaseOrderDetails.Contains(this)) - { - previousValue.PurchaseOrderDetails.Remove(this); - } - - if (PurchaseOrderHeader != null) - { - if (!PurchaseOrderHeader.PurchaseOrderDetails.Contains(this)) - { - PurchaseOrderHeader.PurchaseOrderDetails.Add(this); - } - if (PurchaseOrderID != PurchaseOrderHeader.PurchaseOrderID) - { - PurchaseOrderID = PurchaseOrderHeader.PurchaseOrderID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class PurchaseOrderDetail + { + public virtual int PurchaseOrderID + { + get { return _purchaseOrderID; } + set + { + if (_purchaseOrderID != value) + { + if (PurchaseOrderHeader != null + && PurchaseOrderHeader.PurchaseOrderID != value) + { + PurchaseOrderHeader = null; + } + _purchaseOrderID = value; + } + } + } + + private int _purchaseOrderID; + + public virtual int PurchaseOrderDetailID { get; set; } + + public virtual DateTime DueDate { get; set; } + + public virtual short OrderQty { get; set; } + + public virtual int ProductID + { + get { return _productID; } + set + { + if (_productID != value) + { + if (Product != null + && Product.ProductID != value) + { + Product = null; + } + _productID = value; + } + } + } + + private int _productID; + + public virtual decimal UnitPrice { get; set; } + + public virtual decimal LineTotal { get; set; } + + public virtual decimal ReceivedQty { get; set; } + + public virtual decimal RejectedQty { get; set; } + + public virtual decimal StockedQty { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Product Product + { + get { return _product; } + set + { + if (!ReferenceEquals(_product, value)) + { + var previousValue = _product; + _product = value; + FixupProduct(previousValue); + } + } + } + + private Product _product; + + public virtual PurchaseOrderHeader PurchaseOrderHeader + { + get { return _purchaseOrderHeader; } + set + { + if (!ReferenceEquals(_purchaseOrderHeader, value)) + { + var previousValue = _purchaseOrderHeader; + _purchaseOrderHeader = value; + FixupPurchaseOrderHeader(previousValue); + } + } + } + + private PurchaseOrderHeader _purchaseOrderHeader; + + private void FixupProduct(Product previousValue) + { + if (previousValue != null + && previousValue.PurchaseOrderDetails.Contains(this)) + { + previousValue.PurchaseOrderDetails.Remove(this); + } + + if (Product != null) + { + if (!Product.PurchaseOrderDetails.Contains(this)) + { + Product.PurchaseOrderDetails.Add(this); + } + if (ProductID != Product.ProductID) + { + ProductID = Product.ProductID; + } + } + } + + private void FixupPurchaseOrderHeader(PurchaseOrderHeader previousValue) + { + if (previousValue != null + && previousValue.PurchaseOrderDetails.Contains(this)) + { + previousValue.PurchaseOrderDetails.Remove(this); + } + + if (PurchaseOrderHeader != null) + { + if (!PurchaseOrderHeader.PurchaseOrderDetails.Contains(this)) + { + PurchaseOrderHeader.PurchaseOrderDetails.Add(this); + } + if (PurchaseOrderID != PurchaseOrderHeader.PurchaseOrderID) + { + PurchaseOrderID = PurchaseOrderHeader.PurchaseOrderID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/PurchaseOrderHeader.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/PurchaseOrderHeader.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/PurchaseOrderHeader.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/PurchaseOrderHeader.cs index c31cd7b0..de8ab9ae 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/PurchaseOrderHeader.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/PurchaseOrderHeader.cs @@ -1,254 +1,254 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class PurchaseOrderHeader - { - public virtual int PurchaseOrderID { get; set; } - - public virtual byte RevisionNumber { get; set; } - - public virtual byte Status { get; set; } - - public virtual int EmployeeID - { - get { return _employeeID; } - set - { - if (_employeeID != value) - { - if (Employee != null - && Employee.EmployeeID != value) - { - Employee = null; - } - _employeeID = value; - } - } - } - - private int _employeeID; - - public virtual int VendorID - { - get { return _vendorID; } - set - { - if (_vendorID != value) - { - if (Vendor != null - && Vendor.VendorID != value) - { - Vendor = null; - } - _vendorID = value; - } - } - } - - private int _vendorID; - - public virtual int ShipMethodID - { - get { return _shipMethodID; } - set - { - if (_shipMethodID != value) - { - if (ShipMethod != null - && ShipMethod.ShipMethodID != value) - { - ShipMethod = null; - } - _shipMethodID = value; - } - } - } - - private int _shipMethodID; - - public virtual DateTime OrderDate { get; set; } - - public virtual DateTime? ShipDate { get; set; } - - public virtual decimal SubTotal { get; set; } - - public virtual decimal TaxAmt { get; set; } - - public virtual decimal Freight { get; set; } - - public virtual decimal TotalDue { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Employee Employee - { - get { return _employee; } - set - { - if (!ReferenceEquals(_employee, value)) - { - var previousValue = _employee; - _employee = value; - FixupEmployee(previousValue); - } - } - } - - private Employee _employee; - - public virtual ICollection PurchaseOrderDetails - { - get - { - if (_purchaseOrderDetails == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupPurchaseOrderDetails; - _purchaseOrderDetails = newCollection; - } - return _purchaseOrderDetails; - } - set - { - if (!ReferenceEquals(_purchaseOrderDetails, value)) - { - var previousValue = _purchaseOrderDetails as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupPurchaseOrderDetails; - } - _purchaseOrderDetails = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupPurchaseOrderDetails; - } - } - } - } - - private ICollection _purchaseOrderDetails; - - public virtual ShipMethod ShipMethod - { - get { return _shipMethod; } - set - { - if (!ReferenceEquals(_shipMethod, value)) - { - var previousValue = _shipMethod; - _shipMethod = value; - FixupShipMethod(previousValue); - } - } - } - - private ShipMethod _shipMethod; - - public virtual Vendor Vendor - { - get { return _vendor; } - set - { - if (!ReferenceEquals(_vendor, value)) - { - var previousValue = _vendor; - _vendor = value; - FixupVendor(previousValue); - } - } - } - - private Vendor _vendor; - - private void FixupEmployee(Employee previousValue) - { - if (previousValue != null - && previousValue.PurchaseOrderHeaders.Contains(this)) - { - previousValue.PurchaseOrderHeaders.Remove(this); - } - - if (Employee != null) - { - if (!Employee.PurchaseOrderHeaders.Contains(this)) - { - Employee.PurchaseOrderHeaders.Add(this); - } - if (EmployeeID != Employee.EmployeeID) - { - EmployeeID = Employee.EmployeeID; - } - } - } - - private void FixupShipMethod(ShipMethod previousValue) - { - if (previousValue != null - && previousValue.PurchaseOrderHeaders.Contains(this)) - { - previousValue.PurchaseOrderHeaders.Remove(this); - } - - if (ShipMethod != null) - { - if (!ShipMethod.PurchaseOrderHeaders.Contains(this)) - { - ShipMethod.PurchaseOrderHeaders.Add(this); - } - if (ShipMethodID != ShipMethod.ShipMethodID) - { - ShipMethodID = ShipMethod.ShipMethodID; - } - } - } - - private void FixupVendor(Vendor previousValue) - { - if (previousValue != null - && previousValue.PurchaseOrderHeaders.Contains(this)) - { - previousValue.PurchaseOrderHeaders.Remove(this); - } - - if (Vendor != null) - { - if (!Vendor.PurchaseOrderHeaders.Contains(this)) - { - Vendor.PurchaseOrderHeaders.Add(this); - } - if (VendorID != Vendor.VendorID) - { - VendorID = Vendor.VendorID; - } - } - } - - private void FixupPurchaseOrderDetails(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (PurchaseOrderDetail item in e.NewItems) - { - item.PurchaseOrderHeader = this; - } - } - - if (e.OldItems != null) - { - foreach (PurchaseOrderDetail item in e.OldItems) - { - if (ReferenceEquals(item.PurchaseOrderHeader, this)) - { - item.PurchaseOrderHeader = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class PurchaseOrderHeader + { + public virtual int PurchaseOrderID { get; set; } + + public virtual byte RevisionNumber { get; set; } + + public virtual byte Status { get; set; } + + public virtual int EmployeeID + { + get { return _employeeID; } + set + { + if (_employeeID != value) + { + if (Employee != null + && Employee.EmployeeID != value) + { + Employee = null; + } + _employeeID = value; + } + } + } + + private int _employeeID; + + public virtual int VendorID + { + get { return _vendorID; } + set + { + if (_vendorID != value) + { + if (Vendor != null + && Vendor.VendorID != value) + { + Vendor = null; + } + _vendorID = value; + } + } + } + + private int _vendorID; + + public virtual int ShipMethodID + { + get { return _shipMethodID; } + set + { + if (_shipMethodID != value) + { + if (ShipMethod != null + && ShipMethod.ShipMethodID != value) + { + ShipMethod = null; + } + _shipMethodID = value; + } + } + } + + private int _shipMethodID; + + public virtual DateTime OrderDate { get; set; } + + public virtual DateTime? ShipDate { get; set; } + + public virtual decimal SubTotal { get; set; } + + public virtual decimal TaxAmt { get; set; } + + public virtual decimal Freight { get; set; } + + public virtual decimal TotalDue { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Employee Employee + { + get { return _employee; } + set + { + if (!ReferenceEquals(_employee, value)) + { + var previousValue = _employee; + _employee = value; + FixupEmployee(previousValue); + } + } + } + + private Employee _employee; + + public virtual ICollection PurchaseOrderDetails + { + get + { + if (_purchaseOrderDetails == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupPurchaseOrderDetails; + _purchaseOrderDetails = newCollection; + } + return _purchaseOrderDetails; + } + set + { + if (!ReferenceEquals(_purchaseOrderDetails, value)) + { + var previousValue = _purchaseOrderDetails as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupPurchaseOrderDetails; + } + _purchaseOrderDetails = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupPurchaseOrderDetails; + } + } + } + } + + private ICollection _purchaseOrderDetails; + + public virtual ShipMethod ShipMethod + { + get { return _shipMethod; } + set + { + if (!ReferenceEquals(_shipMethod, value)) + { + var previousValue = _shipMethod; + _shipMethod = value; + FixupShipMethod(previousValue); + } + } + } + + private ShipMethod _shipMethod; + + public virtual Vendor Vendor + { + get { return _vendor; } + set + { + if (!ReferenceEquals(_vendor, value)) + { + var previousValue = _vendor; + _vendor = value; + FixupVendor(previousValue); + } + } + } + + private Vendor _vendor; + + private void FixupEmployee(Employee previousValue) + { + if (previousValue != null + && previousValue.PurchaseOrderHeaders.Contains(this)) + { + previousValue.PurchaseOrderHeaders.Remove(this); + } + + if (Employee != null) + { + if (!Employee.PurchaseOrderHeaders.Contains(this)) + { + Employee.PurchaseOrderHeaders.Add(this); + } + if (EmployeeID != Employee.EmployeeID) + { + EmployeeID = Employee.EmployeeID; + } + } + } + + private void FixupShipMethod(ShipMethod previousValue) + { + if (previousValue != null + && previousValue.PurchaseOrderHeaders.Contains(this)) + { + previousValue.PurchaseOrderHeaders.Remove(this); + } + + if (ShipMethod != null) + { + if (!ShipMethod.PurchaseOrderHeaders.Contains(this)) + { + ShipMethod.PurchaseOrderHeaders.Add(this); + } + if (ShipMethodID != ShipMethod.ShipMethodID) + { + ShipMethodID = ShipMethod.ShipMethodID; + } + } + } + + private void FixupVendor(Vendor previousValue) + { + if (previousValue != null + && previousValue.PurchaseOrderHeaders.Contains(this)) + { + previousValue.PurchaseOrderHeaders.Remove(this); + } + + if (Vendor != null) + { + if (!Vendor.PurchaseOrderHeaders.Contains(this)) + { + Vendor.PurchaseOrderHeaders.Add(this); + } + if (VendorID != Vendor.VendorID) + { + VendorID = Vendor.VendorID; + } + } + } + + private void FixupPurchaseOrderDetails(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (PurchaseOrderDetail item in e.NewItems) + { + item.PurchaseOrderHeader = this; + } + } + + if (e.OldItems != null) + { + foreach (PurchaseOrderDetail item in e.OldItems) + { + if (ReferenceEquals(item.PurchaseOrderHeader, this)) + { + item.PurchaseOrderHeader = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/RowDetails.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/RowDetails.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/RowDetails.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/RowDetails.cs index 1f492ff6..82be03c3 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/RowDetails.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/RowDetails.cs @@ -1,14 +1,14 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.ComponentModel.DataAnnotations.Schema; - - [ComplexType] - public class RowDetails - { - public Guid rowguid { get; set; } - public DateTime ModifiedDate { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.ComponentModel.DataAnnotations.Schema; + + [ComplexType] + public class RowDetails + { + public Guid rowguid { get; set; } + public DateTime ModifiedDate { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesOrderDetail.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesOrderDetail.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesOrderDetail.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesOrderDetail.cs index 0fe9dc4c..98049d41 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesOrderDetail.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesOrderDetail.cs @@ -1,160 +1,160 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class SalesOrderDetail - { - public virtual int SalesOrderID - { - get { return _salesOrderID; } - set - { - if (_salesOrderID != value) - { - if (SalesOrderHeader != null - && SalesOrderHeader.SalesOrderID != value) - { - SalesOrderHeader = null; - } - _salesOrderID = value; - } - } - } - - private int _salesOrderID; - - public virtual int SalesOrderDetailID { get; set; } - - public virtual string CarrierTrackingNumber { get; set; } - - public virtual short OrderQty { get; set; } - - public virtual int ProductID - { - get { return _productID; } - set - { - if (_productID != value) - { - if (SpecialOfferProduct != null - && SpecialOfferProduct.ProductID != value) - { - SpecialOfferProduct = null; - } - _productID = value; - } - } - } - - private int _productID; - - public virtual int SpecialOfferID - { - get { return _specialOfferID; } - set - { - if (_specialOfferID != value) - { - if (SpecialOfferProduct != null - && SpecialOfferProduct.SpecialOfferID != value) - { - SpecialOfferProduct = null; - } - _specialOfferID = value; - } - } - } - - private int _specialOfferID; - - public virtual decimal UnitPrice { get; set; } - - public virtual decimal UnitPriceDiscount { get; set; } - - public virtual decimal LineTotal { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual SalesOrderHeader SalesOrderHeader - { - get { return _salesOrderHeader; } - set - { - if (!ReferenceEquals(_salesOrderHeader, value)) - { - var previousValue = _salesOrderHeader; - _salesOrderHeader = value; - FixupSalesOrderHeader(previousValue); - } - } - } - - private SalesOrderHeader _salesOrderHeader; - - public virtual SpecialOfferProduct SpecialOfferProduct - { - get { return _specialOfferProduct; } - set - { - if (!ReferenceEquals(_specialOfferProduct, value)) - { - var previousValue = _specialOfferProduct; - _specialOfferProduct = value; - FixupSpecialOfferProduct(previousValue); - } - } - } - - private SpecialOfferProduct _specialOfferProduct; - - private void FixupSalesOrderHeader(SalesOrderHeader previousValue) - { - if (previousValue != null - && previousValue.SalesOrderDetails.Contains(this)) - { - previousValue.SalesOrderDetails.Remove(this); - } - - if (SalesOrderHeader != null) - { - if (!SalesOrderHeader.SalesOrderDetails.Contains(this)) - { - SalesOrderHeader.SalesOrderDetails.Add(this); - } - if (SalesOrderID != SalesOrderHeader.SalesOrderID) - { - SalesOrderID = SalesOrderHeader.SalesOrderID; - } - } - } - - private void FixupSpecialOfferProduct(SpecialOfferProduct previousValue) - { - if (previousValue != null - && previousValue.SalesOrderDetails.Contains(this)) - { - previousValue.SalesOrderDetails.Remove(this); - } - - if (SpecialOfferProduct != null) - { - if (!SpecialOfferProduct.SalesOrderDetails.Contains(this)) - { - SpecialOfferProduct.SalesOrderDetails.Add(this); - } - if (SpecialOfferID != SpecialOfferProduct.SpecialOfferID) - { - SpecialOfferID = SpecialOfferProduct.SpecialOfferID; - } - if (ProductID != SpecialOfferProduct.ProductID) - { - ProductID = SpecialOfferProduct.ProductID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class SalesOrderDetail + { + public virtual int SalesOrderID + { + get { return _salesOrderID; } + set + { + if (_salesOrderID != value) + { + if (SalesOrderHeader != null + && SalesOrderHeader.SalesOrderID != value) + { + SalesOrderHeader = null; + } + _salesOrderID = value; + } + } + } + + private int _salesOrderID; + + public virtual int SalesOrderDetailID { get; set; } + + public virtual string CarrierTrackingNumber { get; set; } + + public virtual short OrderQty { get; set; } + + public virtual int ProductID + { + get { return _productID; } + set + { + if (_productID != value) + { + if (SpecialOfferProduct != null + && SpecialOfferProduct.ProductID != value) + { + SpecialOfferProduct = null; + } + _productID = value; + } + } + } + + private int _productID; + + public virtual int SpecialOfferID + { + get { return _specialOfferID; } + set + { + if (_specialOfferID != value) + { + if (SpecialOfferProduct != null + && SpecialOfferProduct.SpecialOfferID != value) + { + SpecialOfferProduct = null; + } + _specialOfferID = value; + } + } + } + + private int _specialOfferID; + + public virtual decimal UnitPrice { get; set; } + + public virtual decimal UnitPriceDiscount { get; set; } + + public virtual decimal LineTotal { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual SalesOrderHeader SalesOrderHeader + { + get { return _salesOrderHeader; } + set + { + if (!ReferenceEquals(_salesOrderHeader, value)) + { + var previousValue = _salesOrderHeader; + _salesOrderHeader = value; + FixupSalesOrderHeader(previousValue); + } + } + } + + private SalesOrderHeader _salesOrderHeader; + + public virtual SpecialOfferProduct SpecialOfferProduct + { + get { return _specialOfferProduct; } + set + { + if (!ReferenceEquals(_specialOfferProduct, value)) + { + var previousValue = _specialOfferProduct; + _specialOfferProduct = value; + FixupSpecialOfferProduct(previousValue); + } + } + } + + private SpecialOfferProduct _specialOfferProduct; + + private void FixupSalesOrderHeader(SalesOrderHeader previousValue) + { + if (previousValue != null + && previousValue.SalesOrderDetails.Contains(this)) + { + previousValue.SalesOrderDetails.Remove(this); + } + + if (SalesOrderHeader != null) + { + if (!SalesOrderHeader.SalesOrderDetails.Contains(this)) + { + SalesOrderHeader.SalesOrderDetails.Add(this); + } + if (SalesOrderID != SalesOrderHeader.SalesOrderID) + { + SalesOrderID = SalesOrderHeader.SalesOrderID; + } + } + } + + private void FixupSpecialOfferProduct(SpecialOfferProduct previousValue) + { + if (previousValue != null + && previousValue.SalesOrderDetails.Contains(this)) + { + previousValue.SalesOrderDetails.Remove(this); + } + + if (SpecialOfferProduct != null) + { + if (!SpecialOfferProduct.SalesOrderDetails.Contains(this)) + { + SpecialOfferProduct.SalesOrderDetails.Add(this); + } + if (SpecialOfferID != SpecialOfferProduct.SpecialOfferID) + { + SpecialOfferID = SpecialOfferProduct.SpecialOfferID; + } + if (ProductID != SpecialOfferProduct.ProductID) + { + ProductID = SpecialOfferProduct.ProductID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesOrderHeader.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesOrderHeader.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesOrderHeader.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesOrderHeader.cs index f5f920f9..e20027a3 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesOrderHeader.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesOrderHeader.cs @@ -1,700 +1,700 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - using System.ComponentModel.DataAnnotations; - - public class SalesOrderHeader - { - [Key] - public virtual int SalesOrderID { get; set; } - - public virtual byte RevisionNumber { get; set; } - - public virtual DateTime OrderDate { get; set; } - - public virtual DateTime DueDate { get; set; } - - public virtual DateTime? ShipDate { get; set; } - - public virtual byte Status { get; set; } - - public virtual bool OnlineOrderFlag { get; set; } - - public virtual string SalesOrderNumber { get; set; } - - public virtual string PurchaseOrderNumber { get; set; } - - public virtual string AccountNumber { get; set; } - - public virtual int CustomerID - { - get { return _customerID; } - set - { - try - { - _settingFK = true; - if (_customerID != value) - { - if (Customer != null - && Customer.CustomerID != value) - { - Customer = null; - } - _customerID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int _customerID; - - public virtual int ContactID - { - get { return _contactID; } - set - { - try - { - _settingFK = true; - if (_contactID != value) - { - if (Contact != null - && Contact.ContactID != value) - { - Contact = null; - } - _contactID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int _contactID; - - public virtual int? SalesPersonID - { - get { return _salesPersonID; } - set - { - try - { - _settingFK = true; - if (_salesPersonID != value) - { - if (SalesPerson != null - && SalesPerson.SalesPersonID != value) - { - SalesPerson = null; - } - _salesPersonID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int? _salesPersonID; - - public virtual int? TerritoryID - { - get { return _territoryID; } - set - { - try - { - _settingFK = true; - if (_territoryID != value) - { - if (SalesTerritory != null - && SalesTerritory.TerritoryID != value) - { - SalesTerritory = null; - } - _territoryID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int? _territoryID; - - public virtual int BillToAddressID - { - get { return _billToAddressID; } - set - { - try - { - _settingFK = true; - if (_billToAddressID != value) - { - if (Address != null - && Address.AddressID != value) - { - Address = null; - } - _billToAddressID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int _billToAddressID; - - public virtual int ShipToAddressID - { - get { return _shipToAddressID; } - set - { - try - { - _settingFK = true; - if (_shipToAddressID != value) - { - if (Address1 != null - && Address1.AddressID != value) - { - Address1 = null; - } - _shipToAddressID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int _shipToAddressID; - - public virtual int ShipMethodID - { - get { return _shipMethodID; } - set - { - try - { - _settingFK = true; - if (_shipMethodID != value) - { - if (ShipMethod != null - && ShipMethod.ShipMethodID != value) - { - ShipMethod = null; - } - _shipMethodID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int _shipMethodID; - - public virtual int? CreditCardID - { - get { return _creditCardID; } - set - { - try - { - _settingFK = true; - if (_creditCardID != value) - { - if (CreditCard != null - && CreditCard.CreditCardID != value) - { - CreditCard = null; - } - _creditCardID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int? _creditCardID; - - public virtual string CreditCardApprovalCode { get; set; } - - public virtual int? CurrencyRateID - { - get { return _currencyRateID; } - set - { - try - { - _settingFK = true; - if (_currencyRateID != value) - { - if (CurrencyRate != null - && CurrencyRate.CurrencyRateID != value) - { - CurrencyRate = null; - } - _currencyRateID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int? _currencyRateID; - - public virtual decimal SubTotal { get; set; } - - public virtual decimal TaxAmt { get; set; } - - public virtual decimal Freight { get; set; } - - public virtual decimal TotalDue { get; set; } - - public virtual string Comment { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Address Address - { - get { return _address; } - set - { - if (!ReferenceEquals(_address, value)) - { - var previousValue = _address; - _address = value; - FixupAddress(previousValue); - } - } - } - - private Address _address; - - public virtual Address Address1 - { - get { return _address1; } - set - { - if (!ReferenceEquals(_address1, value)) - { - var previousValue = _address1; - _address1 = value; - FixupAddress1(previousValue); - } - } - } - - private Address _address1; - - public virtual Contact Contact - { - get { return _contact; } - set - { - if (!ReferenceEquals(_contact, value)) - { - var previousValue = _contact; - _contact = value; - FixupContact(previousValue); - } - } - } - - private Contact _contact; - - public virtual ShipMethod ShipMethod - { - get { return _shipMethod; } - set - { - if (!ReferenceEquals(_shipMethod, value)) - { - var previousValue = _shipMethod; - _shipMethod = value; - FixupShipMethod(previousValue); - } - } - } - - private ShipMethod _shipMethod; - - public virtual CreditCard CreditCard - { - get { return _creditCard; } - set - { - if (!ReferenceEquals(_creditCard, value)) - { - var previousValue = _creditCard; - _creditCard = value; - FixupCreditCard(previousValue); - } - } - } - - private CreditCard _creditCard; - - public virtual CurrencyRate CurrencyRate - { - get { return _currencyRate; } - set - { - if (!ReferenceEquals(_currencyRate, value)) - { - var previousValue = _currencyRate; - _currencyRate = value; - FixupCurrencyRate(previousValue); - } - } - } - - private CurrencyRate _currencyRate; - - public virtual Customer Customer - { - get { return _customer; } - set - { - if (!ReferenceEquals(_customer, value)) - { - var previousValue = _customer; - _customer = value; - FixupCustomer(previousValue); - } - } - } - - private Customer _customer; - - public virtual ICollection SalesOrderDetails - { - get - { - if (_salesOrderDetails == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesOrderDetails; - _salesOrderDetails = newCollection; - } - return _salesOrderDetails; - } - set - { - if (!ReferenceEquals(_salesOrderDetails, value)) - { - var previousValue = _salesOrderDetails as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesOrderDetails; - } - _salesOrderDetails = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesOrderDetails; - } - } - } - } - - private ICollection _salesOrderDetails; - - public virtual SalesPerson SalesPerson - { - get { return _salesPerson; } - set - { - if (!ReferenceEquals(_salesPerson, value)) - { - var previousValue = _salesPerson; - _salesPerson = value; - FixupSalesPerson(previousValue); - } - } - } - - private SalesPerson _salesPerson; - - public virtual SalesTerritory SalesTerritory - { - get { return _salesTerritory; } - set - { - if (!ReferenceEquals(_salesTerritory, value)) - { - var previousValue = _salesTerritory; - _salesTerritory = value; - FixupSalesTerritory(previousValue); - } - } - } - - private SalesTerritory _salesTerritory; - - public virtual ICollection SalesReasons { get; set; } - - private bool _settingFK; - - private void FixupAddress(Address previousValue) - { - if (previousValue != null - && previousValue.SalesOrderHeaders.Contains(this)) - { - previousValue.SalesOrderHeaders.Remove(this); - } - - if (Address != null) - { - if (!Address.SalesOrderHeaders.Contains(this)) - { - Address.SalesOrderHeaders.Add(this); - } - if (BillToAddressID != Address.AddressID) - { - BillToAddressID = Address.AddressID; - } - } - } - - private void FixupAddress1(Address previousValue) - { - if (previousValue != null - && previousValue.SalesOrderHeaders1.Contains(this)) - { - previousValue.SalesOrderHeaders1.Remove(this); - } - - if (Address1 != null) - { - if (!Address1.SalesOrderHeaders1.Contains(this)) - { - Address1.SalesOrderHeaders1.Add(this); - } - if (ShipToAddressID != Address1.AddressID) - { - ShipToAddressID = Address1.AddressID; - } - } - } - - private void FixupContact(Contact previousValue) - { - if (previousValue != null - && previousValue.SalesOrderHeaders.Contains(this)) - { - previousValue.SalesOrderHeaders.Remove(this); - } - - if (Contact != null) - { - if (!Contact.SalesOrderHeaders.Contains(this)) - { - Contact.SalesOrderHeaders.Add(this); - } - if (ContactID != Contact.ContactID) - { - ContactID = Contact.ContactID; - } - } - } - - private void FixupShipMethod(ShipMethod previousValue) - { - if (previousValue != null - && previousValue.SalesOrderHeaders.Contains(this)) - { - previousValue.SalesOrderHeaders.Remove(this); - } - - if (ShipMethod != null) - { - if (!ShipMethod.SalesOrderHeaders.Contains(this)) - { - ShipMethod.SalesOrderHeaders.Add(this); - } - if (ShipMethodID != ShipMethod.ShipMethodID) - { - ShipMethodID = ShipMethod.ShipMethodID; - } - } - } - - private void FixupCreditCard(CreditCard previousValue) - { - if (previousValue != null - && previousValue.SalesOrderHeaders.Contains(this)) - { - previousValue.SalesOrderHeaders.Remove(this); - } - - if (CreditCard != null) - { - if (!CreditCard.SalesOrderHeaders.Contains(this)) - { - CreditCard.SalesOrderHeaders.Add(this); - } - if (CreditCardID != CreditCard.CreditCardID) - { - CreditCardID = CreditCard.CreditCardID; - } - } - else if (!_settingFK) - { - CreditCardID = null; - } - } - - private void FixupCurrencyRate(CurrencyRate previousValue) - { - if (previousValue != null - && previousValue.SalesOrderHeaders.Contains(this)) - { - previousValue.SalesOrderHeaders.Remove(this); - } - - if (CurrencyRate != null) - { - if (!CurrencyRate.SalesOrderHeaders.Contains(this)) - { - CurrencyRate.SalesOrderHeaders.Add(this); - } - if (CurrencyRateID != CurrencyRate.CurrencyRateID) - { - CurrencyRateID = CurrencyRate.CurrencyRateID; - } - } - else if (!_settingFK) - { - CurrencyRateID = null; - } - } - - private void FixupCustomer(Customer previousValue) - { - if (previousValue != null - && previousValue.SalesOrderHeaders.Contains(this)) - { - previousValue.SalesOrderHeaders.Remove(this); - } - - if (Customer != null) - { - if (!Customer.SalesOrderHeaders.Contains(this)) - { - Customer.SalesOrderHeaders.Add(this); - } - if (CustomerID != Customer.CustomerID) - { - CustomerID = Customer.CustomerID; - } - } - } - - private void FixupSalesPerson(SalesPerson previousValue) - { - if (previousValue != null - && previousValue.SalesOrderHeaders.Contains(this)) - { - previousValue.SalesOrderHeaders.Remove(this); - } - - if (SalesPerson != null) - { - if (!SalesPerson.SalesOrderHeaders.Contains(this)) - { - SalesPerson.SalesOrderHeaders.Add(this); - } - if (SalesPersonID != SalesPerson.SalesPersonID) - { - SalesPersonID = SalesPerson.SalesPersonID; - } - } - else if (!_settingFK) - { - SalesPersonID = null; - } - } - - private void FixupSalesTerritory(SalesTerritory previousValue) - { - if (previousValue != null - && previousValue.SalesOrderHeaders.Contains(this)) - { - previousValue.SalesOrderHeaders.Remove(this); - } - - if (SalesTerritory != null) - { - if (!SalesTerritory.SalesOrderHeaders.Contains(this)) - { - SalesTerritory.SalesOrderHeaders.Add(this); - } - if (TerritoryID != SalesTerritory.TerritoryID) - { - TerritoryID = SalesTerritory.TerritoryID; - } - } - else if (!_settingFK) - { - TerritoryID = null; - } - } - - private void FixupSalesOrderDetails(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesOrderDetail item in e.NewItems) - { - item.SalesOrderHeader = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesOrderDetail item in e.OldItems) - { - if (ReferenceEquals(item.SalesOrderHeader, this)) - { - item.SalesOrderHeader = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + using System.ComponentModel.DataAnnotations; + + public class SalesOrderHeader + { + [Key] + public virtual int SalesOrderID { get; set; } + + public virtual byte RevisionNumber { get; set; } + + public virtual DateTime OrderDate { get; set; } + + public virtual DateTime DueDate { get; set; } + + public virtual DateTime? ShipDate { get; set; } + + public virtual byte Status { get; set; } + + public virtual bool OnlineOrderFlag { get; set; } + + public virtual string SalesOrderNumber { get; set; } + + public virtual string PurchaseOrderNumber { get; set; } + + public virtual string AccountNumber { get; set; } + + public virtual int CustomerID + { + get { return _customerID; } + set + { + try + { + _settingFK = true; + if (_customerID != value) + { + if (Customer != null + && Customer.CustomerID != value) + { + Customer = null; + } + _customerID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int _customerID; + + public virtual int ContactID + { + get { return _contactID; } + set + { + try + { + _settingFK = true; + if (_contactID != value) + { + if (Contact != null + && Contact.ContactID != value) + { + Contact = null; + } + _contactID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int _contactID; + + public virtual int? SalesPersonID + { + get { return _salesPersonID; } + set + { + try + { + _settingFK = true; + if (_salesPersonID != value) + { + if (SalesPerson != null + && SalesPerson.SalesPersonID != value) + { + SalesPerson = null; + } + _salesPersonID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int? _salesPersonID; + + public virtual int? TerritoryID + { + get { return _territoryID; } + set + { + try + { + _settingFK = true; + if (_territoryID != value) + { + if (SalesTerritory != null + && SalesTerritory.TerritoryID != value) + { + SalesTerritory = null; + } + _territoryID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int? _territoryID; + + public virtual int BillToAddressID + { + get { return _billToAddressID; } + set + { + try + { + _settingFK = true; + if (_billToAddressID != value) + { + if (Address != null + && Address.AddressID != value) + { + Address = null; + } + _billToAddressID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int _billToAddressID; + + public virtual int ShipToAddressID + { + get { return _shipToAddressID; } + set + { + try + { + _settingFK = true; + if (_shipToAddressID != value) + { + if (Address1 != null + && Address1.AddressID != value) + { + Address1 = null; + } + _shipToAddressID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int _shipToAddressID; + + public virtual int ShipMethodID + { + get { return _shipMethodID; } + set + { + try + { + _settingFK = true; + if (_shipMethodID != value) + { + if (ShipMethod != null + && ShipMethod.ShipMethodID != value) + { + ShipMethod = null; + } + _shipMethodID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int _shipMethodID; + + public virtual int? CreditCardID + { + get { return _creditCardID; } + set + { + try + { + _settingFK = true; + if (_creditCardID != value) + { + if (CreditCard != null + && CreditCard.CreditCardID != value) + { + CreditCard = null; + } + _creditCardID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int? _creditCardID; + + public virtual string CreditCardApprovalCode { get; set; } + + public virtual int? CurrencyRateID + { + get { return _currencyRateID; } + set + { + try + { + _settingFK = true; + if (_currencyRateID != value) + { + if (CurrencyRate != null + && CurrencyRate.CurrencyRateID != value) + { + CurrencyRate = null; + } + _currencyRateID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int? _currencyRateID; + + public virtual decimal SubTotal { get; set; } + + public virtual decimal TaxAmt { get; set; } + + public virtual decimal Freight { get; set; } + + public virtual decimal TotalDue { get; set; } + + public virtual string Comment { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Address Address + { + get { return _address; } + set + { + if (!ReferenceEquals(_address, value)) + { + var previousValue = _address; + _address = value; + FixupAddress(previousValue); + } + } + } + + private Address _address; + + public virtual Address Address1 + { + get { return _address1; } + set + { + if (!ReferenceEquals(_address1, value)) + { + var previousValue = _address1; + _address1 = value; + FixupAddress1(previousValue); + } + } + } + + private Address _address1; + + public virtual Contact Contact + { + get { return _contact; } + set + { + if (!ReferenceEquals(_contact, value)) + { + var previousValue = _contact; + _contact = value; + FixupContact(previousValue); + } + } + } + + private Contact _contact; + + public virtual ShipMethod ShipMethod + { + get { return _shipMethod; } + set + { + if (!ReferenceEquals(_shipMethod, value)) + { + var previousValue = _shipMethod; + _shipMethod = value; + FixupShipMethod(previousValue); + } + } + } + + private ShipMethod _shipMethod; + + public virtual CreditCard CreditCard + { + get { return _creditCard; } + set + { + if (!ReferenceEquals(_creditCard, value)) + { + var previousValue = _creditCard; + _creditCard = value; + FixupCreditCard(previousValue); + } + } + } + + private CreditCard _creditCard; + + public virtual CurrencyRate CurrencyRate + { + get { return _currencyRate; } + set + { + if (!ReferenceEquals(_currencyRate, value)) + { + var previousValue = _currencyRate; + _currencyRate = value; + FixupCurrencyRate(previousValue); + } + } + } + + private CurrencyRate _currencyRate; + + public virtual Customer Customer + { + get { return _customer; } + set + { + if (!ReferenceEquals(_customer, value)) + { + var previousValue = _customer; + _customer = value; + FixupCustomer(previousValue); + } + } + } + + private Customer _customer; + + public virtual ICollection SalesOrderDetails + { + get + { + if (_salesOrderDetails == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesOrderDetails; + _salesOrderDetails = newCollection; + } + return _salesOrderDetails; + } + set + { + if (!ReferenceEquals(_salesOrderDetails, value)) + { + var previousValue = _salesOrderDetails as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesOrderDetails; + } + _salesOrderDetails = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesOrderDetails; + } + } + } + } + + private ICollection _salesOrderDetails; + + public virtual SalesPerson SalesPerson + { + get { return _salesPerson; } + set + { + if (!ReferenceEquals(_salesPerson, value)) + { + var previousValue = _salesPerson; + _salesPerson = value; + FixupSalesPerson(previousValue); + } + } + } + + private SalesPerson _salesPerson; + + public virtual SalesTerritory SalesTerritory + { + get { return _salesTerritory; } + set + { + if (!ReferenceEquals(_salesTerritory, value)) + { + var previousValue = _salesTerritory; + _salesTerritory = value; + FixupSalesTerritory(previousValue); + } + } + } + + private SalesTerritory _salesTerritory; + + public virtual ICollection SalesReasons { get; set; } + + private bool _settingFK; + + private void FixupAddress(Address previousValue) + { + if (previousValue != null + && previousValue.SalesOrderHeaders.Contains(this)) + { + previousValue.SalesOrderHeaders.Remove(this); + } + + if (Address != null) + { + if (!Address.SalesOrderHeaders.Contains(this)) + { + Address.SalesOrderHeaders.Add(this); + } + if (BillToAddressID != Address.AddressID) + { + BillToAddressID = Address.AddressID; + } + } + } + + private void FixupAddress1(Address previousValue) + { + if (previousValue != null + && previousValue.SalesOrderHeaders1.Contains(this)) + { + previousValue.SalesOrderHeaders1.Remove(this); + } + + if (Address1 != null) + { + if (!Address1.SalesOrderHeaders1.Contains(this)) + { + Address1.SalesOrderHeaders1.Add(this); + } + if (ShipToAddressID != Address1.AddressID) + { + ShipToAddressID = Address1.AddressID; + } + } + } + + private void FixupContact(Contact previousValue) + { + if (previousValue != null + && previousValue.SalesOrderHeaders.Contains(this)) + { + previousValue.SalesOrderHeaders.Remove(this); + } + + if (Contact != null) + { + if (!Contact.SalesOrderHeaders.Contains(this)) + { + Contact.SalesOrderHeaders.Add(this); + } + if (ContactID != Contact.ContactID) + { + ContactID = Contact.ContactID; + } + } + } + + private void FixupShipMethod(ShipMethod previousValue) + { + if (previousValue != null + && previousValue.SalesOrderHeaders.Contains(this)) + { + previousValue.SalesOrderHeaders.Remove(this); + } + + if (ShipMethod != null) + { + if (!ShipMethod.SalesOrderHeaders.Contains(this)) + { + ShipMethod.SalesOrderHeaders.Add(this); + } + if (ShipMethodID != ShipMethod.ShipMethodID) + { + ShipMethodID = ShipMethod.ShipMethodID; + } + } + } + + private void FixupCreditCard(CreditCard previousValue) + { + if (previousValue != null + && previousValue.SalesOrderHeaders.Contains(this)) + { + previousValue.SalesOrderHeaders.Remove(this); + } + + if (CreditCard != null) + { + if (!CreditCard.SalesOrderHeaders.Contains(this)) + { + CreditCard.SalesOrderHeaders.Add(this); + } + if (CreditCardID != CreditCard.CreditCardID) + { + CreditCardID = CreditCard.CreditCardID; + } + } + else if (!_settingFK) + { + CreditCardID = null; + } + } + + private void FixupCurrencyRate(CurrencyRate previousValue) + { + if (previousValue != null + && previousValue.SalesOrderHeaders.Contains(this)) + { + previousValue.SalesOrderHeaders.Remove(this); + } + + if (CurrencyRate != null) + { + if (!CurrencyRate.SalesOrderHeaders.Contains(this)) + { + CurrencyRate.SalesOrderHeaders.Add(this); + } + if (CurrencyRateID != CurrencyRate.CurrencyRateID) + { + CurrencyRateID = CurrencyRate.CurrencyRateID; + } + } + else if (!_settingFK) + { + CurrencyRateID = null; + } + } + + private void FixupCustomer(Customer previousValue) + { + if (previousValue != null + && previousValue.SalesOrderHeaders.Contains(this)) + { + previousValue.SalesOrderHeaders.Remove(this); + } + + if (Customer != null) + { + if (!Customer.SalesOrderHeaders.Contains(this)) + { + Customer.SalesOrderHeaders.Add(this); + } + if (CustomerID != Customer.CustomerID) + { + CustomerID = Customer.CustomerID; + } + } + } + + private void FixupSalesPerson(SalesPerson previousValue) + { + if (previousValue != null + && previousValue.SalesOrderHeaders.Contains(this)) + { + previousValue.SalesOrderHeaders.Remove(this); + } + + if (SalesPerson != null) + { + if (!SalesPerson.SalesOrderHeaders.Contains(this)) + { + SalesPerson.SalesOrderHeaders.Add(this); + } + if (SalesPersonID != SalesPerson.SalesPersonID) + { + SalesPersonID = SalesPerson.SalesPersonID; + } + } + else if (!_settingFK) + { + SalesPersonID = null; + } + } + + private void FixupSalesTerritory(SalesTerritory previousValue) + { + if (previousValue != null + && previousValue.SalesOrderHeaders.Contains(this)) + { + previousValue.SalesOrderHeaders.Remove(this); + } + + if (SalesTerritory != null) + { + if (!SalesTerritory.SalesOrderHeaders.Contains(this)) + { + SalesTerritory.SalesOrderHeaders.Add(this); + } + if (TerritoryID != SalesTerritory.TerritoryID) + { + TerritoryID = SalesTerritory.TerritoryID; + } + } + else if (!_settingFK) + { + TerritoryID = null; + } + } + + private void FixupSalesOrderDetails(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesOrderDetail item in e.NewItems) + { + item.SalesOrderHeader = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesOrderDetail item in e.OldItems) + { + if (ReferenceEquals(item.SalesOrderHeader, this)) + { + item.SalesOrderHeader = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesPerson.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesPerson.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesPerson.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesPerson.cs index eb2c7d47..cc8134f1 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesPerson.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesPerson.cs @@ -1,376 +1,376 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class SalesPerson - { - public virtual int SalesPersonID - { - get { return _salesPersonID; } - set - { - try - { - _settingFK = true; - if (_salesPersonID != value) - { - if (Employee != null - && Employee.EmployeeID != value) - { - Employee = null; - } - _salesPersonID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int _salesPersonID; - - public virtual int? TerritoryID - { - get { return _territoryID; } - set - { - try - { - _settingFK = true; - if (_territoryID != value) - { - if (SalesTerritory != null - && SalesTerritory.TerritoryID != value) - { - SalesTerritory = null; - } - _territoryID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int? _territoryID; - - public virtual decimal? SalesQuota { get; set; } - - public virtual decimal Bonus { get; set; } - - public virtual decimal CommissionPct { get; set; } - - public virtual decimal SalesYTD { get; set; } - - public virtual decimal SalesLastYear { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Employee Employee - { - get { return _employee; } - set - { - if (!ReferenceEquals(_employee, value)) - { - var previousValue = _employee; - _employee = value; - FixupEmployee(previousValue); - } - } - } - - private Employee _employee; - - public virtual ICollection SalesOrderHeaders - { - get - { - if (_salesOrderHeaders == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesOrderHeaders; - _salesOrderHeaders = newCollection; - } - return _salesOrderHeaders; - } - set - { - if (!ReferenceEquals(_salesOrderHeaders, value)) - { - var previousValue = _salesOrderHeaders as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesOrderHeaders; - } - _salesOrderHeaders = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesOrderHeaders; - } - } - } - } - - private ICollection _salesOrderHeaders; - - public virtual SalesTerritory SalesTerritory - { - get { return _salesTerritory; } - set - { - if (!ReferenceEquals(_salesTerritory, value)) - { - var previousValue = _salesTerritory; - _salesTerritory = value; - FixupSalesTerritory(previousValue); - } - } - } - - private SalesTerritory _salesTerritory; - - public virtual ICollection SalesPersonQuotaHistories - { - get - { - if (_salesPersonQuotaHistories == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesPersonQuotaHistories; - _salesPersonQuotaHistories = newCollection; - } - return _salesPersonQuotaHistories; - } - set - { - if (!ReferenceEquals(_salesPersonQuotaHistories, value)) - { - var previousValue = _salesPersonQuotaHistories as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesPersonQuotaHistories; - } - _salesPersonQuotaHistories = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesPersonQuotaHistories; - } - } - } - } - - private ICollection _salesPersonQuotaHistories; - - public virtual ICollection SalesTerritoryHistories - { - get - { - if (_salesTerritoryHistories == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesTerritoryHistories; - _salesTerritoryHistories = newCollection; - } - return _salesTerritoryHistories; - } - set - { - if (!ReferenceEquals(_salesTerritoryHistories, value)) - { - var previousValue = _salesTerritoryHistories as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesTerritoryHistories; - } - _salesTerritoryHistories = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesTerritoryHistories; - } - } - } - } - - private ICollection _salesTerritoryHistories; - - public virtual ICollection Stores - { - get - { - if (_stores == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupStores; - _stores = newCollection; - } - return _stores; - } - set - { - if (!ReferenceEquals(_stores, value)) - { - var previousValue = _stores as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupStores; - } - _stores = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupStores; - } - } - } - } - - private ICollection _stores; - - private bool _settingFK; - - private void FixupEmployee(Employee previousValue) - { - if (previousValue != null - && ReferenceEquals(previousValue.SalesPerson, this)) - { - previousValue.SalesPerson = null; - } - - if (Employee != null) - { - Employee.SalesPerson = this; - if (SalesPersonID != Employee.EmployeeID) - { - SalesPersonID = Employee.EmployeeID; - } - } - } - - private void FixupSalesTerritory(SalesTerritory previousValue) - { - if (previousValue != null - && previousValue.SalesPersons.Contains(this)) - { - previousValue.SalesPersons.Remove(this); - } - - if (SalesTerritory != null) - { - if (!SalesTerritory.SalesPersons.Contains(this)) - { - SalesTerritory.SalesPersons.Add(this); - } - if (TerritoryID != SalesTerritory.TerritoryID) - { - TerritoryID = SalesTerritory.TerritoryID; - } - } - else if (!_settingFK) - { - TerritoryID = null; - } - } - - private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesOrderHeader item in e.NewItems) - { - item.SalesPerson = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesOrderHeader item in e.OldItems) - { - if (ReferenceEquals(item.SalesPerson, this)) - { - item.SalesPerson = null; - } - } - } - } - - private void FixupSalesPersonQuotaHistories(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesPersonQuotaHistory item in e.NewItems) - { - item.SalesPerson = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesPersonQuotaHistory item in e.OldItems) - { - if (ReferenceEquals(item.SalesPerson, this)) - { - item.SalesPerson = null; - } - } - } - } - - private void FixupSalesTerritoryHistories(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesTerritoryHistory item in e.NewItems) - { - item.SalesPerson = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesTerritoryHistory item in e.OldItems) - { - if (ReferenceEquals(item.SalesPerson, this)) - { - item.SalesPerson = null; - } - } - } - } - - private void FixupStores(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (Store item in e.NewItems) - { - item.SalesPerson = this; - } - } - - if (e.OldItems != null) - { - foreach (Store item in e.OldItems) - { - if (ReferenceEquals(item.SalesPerson, this)) - { - item.SalesPerson = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class SalesPerson + { + public virtual int SalesPersonID + { + get { return _salesPersonID; } + set + { + try + { + _settingFK = true; + if (_salesPersonID != value) + { + if (Employee != null + && Employee.EmployeeID != value) + { + Employee = null; + } + _salesPersonID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int _salesPersonID; + + public virtual int? TerritoryID + { + get { return _territoryID; } + set + { + try + { + _settingFK = true; + if (_territoryID != value) + { + if (SalesTerritory != null + && SalesTerritory.TerritoryID != value) + { + SalesTerritory = null; + } + _territoryID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int? _territoryID; + + public virtual decimal? SalesQuota { get; set; } + + public virtual decimal Bonus { get; set; } + + public virtual decimal CommissionPct { get; set; } + + public virtual decimal SalesYTD { get; set; } + + public virtual decimal SalesLastYear { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Employee Employee + { + get { return _employee; } + set + { + if (!ReferenceEquals(_employee, value)) + { + var previousValue = _employee; + _employee = value; + FixupEmployee(previousValue); + } + } + } + + private Employee _employee; + + public virtual ICollection SalesOrderHeaders + { + get + { + if (_salesOrderHeaders == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesOrderHeaders; + _salesOrderHeaders = newCollection; + } + return _salesOrderHeaders; + } + set + { + if (!ReferenceEquals(_salesOrderHeaders, value)) + { + var previousValue = _salesOrderHeaders as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesOrderHeaders; + } + _salesOrderHeaders = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesOrderHeaders; + } + } + } + } + + private ICollection _salesOrderHeaders; + + public virtual SalesTerritory SalesTerritory + { + get { return _salesTerritory; } + set + { + if (!ReferenceEquals(_salesTerritory, value)) + { + var previousValue = _salesTerritory; + _salesTerritory = value; + FixupSalesTerritory(previousValue); + } + } + } + + private SalesTerritory _salesTerritory; + + public virtual ICollection SalesPersonQuotaHistories + { + get + { + if (_salesPersonQuotaHistories == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesPersonQuotaHistories; + _salesPersonQuotaHistories = newCollection; + } + return _salesPersonQuotaHistories; + } + set + { + if (!ReferenceEquals(_salesPersonQuotaHistories, value)) + { + var previousValue = _salesPersonQuotaHistories as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesPersonQuotaHistories; + } + _salesPersonQuotaHistories = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesPersonQuotaHistories; + } + } + } + } + + private ICollection _salesPersonQuotaHistories; + + public virtual ICollection SalesTerritoryHistories + { + get + { + if (_salesTerritoryHistories == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesTerritoryHistories; + _salesTerritoryHistories = newCollection; + } + return _salesTerritoryHistories; + } + set + { + if (!ReferenceEquals(_salesTerritoryHistories, value)) + { + var previousValue = _salesTerritoryHistories as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesTerritoryHistories; + } + _salesTerritoryHistories = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesTerritoryHistories; + } + } + } + } + + private ICollection _salesTerritoryHistories; + + public virtual ICollection Stores + { + get + { + if (_stores == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupStores; + _stores = newCollection; + } + return _stores; + } + set + { + if (!ReferenceEquals(_stores, value)) + { + var previousValue = _stores as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupStores; + } + _stores = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupStores; + } + } + } + } + + private ICollection _stores; + + private bool _settingFK; + + private void FixupEmployee(Employee previousValue) + { + if (previousValue != null + && ReferenceEquals(previousValue.SalesPerson, this)) + { + previousValue.SalesPerson = null; + } + + if (Employee != null) + { + Employee.SalesPerson = this; + if (SalesPersonID != Employee.EmployeeID) + { + SalesPersonID = Employee.EmployeeID; + } + } + } + + private void FixupSalesTerritory(SalesTerritory previousValue) + { + if (previousValue != null + && previousValue.SalesPersons.Contains(this)) + { + previousValue.SalesPersons.Remove(this); + } + + if (SalesTerritory != null) + { + if (!SalesTerritory.SalesPersons.Contains(this)) + { + SalesTerritory.SalesPersons.Add(this); + } + if (TerritoryID != SalesTerritory.TerritoryID) + { + TerritoryID = SalesTerritory.TerritoryID; + } + } + else if (!_settingFK) + { + TerritoryID = null; + } + } + + private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesOrderHeader item in e.NewItems) + { + item.SalesPerson = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesOrderHeader item in e.OldItems) + { + if (ReferenceEquals(item.SalesPerson, this)) + { + item.SalesPerson = null; + } + } + } + } + + private void FixupSalesPersonQuotaHistories(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesPersonQuotaHistory item in e.NewItems) + { + item.SalesPerson = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesPersonQuotaHistory item in e.OldItems) + { + if (ReferenceEquals(item.SalesPerson, this)) + { + item.SalesPerson = null; + } + } + } + } + + private void FixupSalesTerritoryHistories(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesTerritoryHistory item in e.NewItems) + { + item.SalesPerson = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesTerritoryHistory item in e.OldItems) + { + if (ReferenceEquals(item.SalesPerson, this)) + { + item.SalesPerson = null; + } + } + } + } + + private void FixupStores(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (Store item in e.NewItems) + { + item.SalesPerson = this; + } + } + + if (e.OldItems != null) + { + foreach (Store item in e.OldItems) + { + if (ReferenceEquals(item.SalesPerson, this)) + { + item.SalesPerson = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesPersonQuotaHistory.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesPersonQuotaHistory.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesPersonQuotaHistory.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesPersonQuotaHistory.cs index 6027ce64..7336d6aa 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesPersonQuotaHistory.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesPersonQuotaHistory.cs @@ -1,73 +1,73 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class SalesPersonQuotaHistory - { - public virtual int SalesPersonID - { - get { return _salesPersonID; } - set - { - if (_salesPersonID != value) - { - if (SalesPerson != null - && SalesPerson.SalesPersonID != value) - { - SalesPerson = null; - } - _salesPersonID = value; - } - } - } - - private int _salesPersonID; - - public virtual DateTime QuotaDate { get; set; } - - public virtual decimal SalesQuota { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual SalesPerson SalesPerson - { - get { return _salesPerson; } - set - { - if (!ReferenceEquals(_salesPerson, value)) - { - var previousValue = _salesPerson; - _salesPerson = value; - FixupSalesPerson(previousValue); - } - } - } - - private SalesPerson _salesPerson; - - private void FixupSalesPerson(SalesPerson previousValue) - { - if (previousValue != null - && previousValue.SalesPersonQuotaHistories.Contains(this)) - { - previousValue.SalesPersonQuotaHistories.Remove(this); - } - - if (SalesPerson != null) - { - if (!SalesPerson.SalesPersonQuotaHistories.Contains(this)) - { - SalesPerson.SalesPersonQuotaHistories.Add(this); - } - if (SalesPersonID != SalesPerson.SalesPersonID) - { - SalesPersonID = SalesPerson.SalesPersonID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class SalesPersonQuotaHistory + { + public virtual int SalesPersonID + { + get { return _salesPersonID; } + set + { + if (_salesPersonID != value) + { + if (SalesPerson != null + && SalesPerson.SalesPersonID != value) + { + SalesPerson = null; + } + _salesPersonID = value; + } + } + } + + private int _salesPersonID; + + public virtual DateTime QuotaDate { get; set; } + + public virtual decimal SalesQuota { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual SalesPerson SalesPerson + { + get { return _salesPerson; } + set + { + if (!ReferenceEquals(_salesPerson, value)) + { + var previousValue = _salesPerson; + _salesPerson = value; + FixupSalesPerson(previousValue); + } + } + } + + private SalesPerson _salesPerson; + + private void FixupSalesPerson(SalesPerson previousValue) + { + if (previousValue != null + && previousValue.SalesPersonQuotaHistories.Contains(this)) + { + previousValue.SalesPersonQuotaHistories.Remove(this); + } + + if (SalesPerson != null) + { + if (!SalesPerson.SalesPersonQuotaHistories.Contains(this)) + { + SalesPerson.SalesPersonQuotaHistories.Add(this); + } + if (SalesPersonID != SalesPerson.SalesPersonID) + { + SalesPersonID = SalesPerson.SalesPersonID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesReason.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesReason.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesReason.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesReason.cs index 8e5b2ae4..f6146584 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesReason.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesReason.cs @@ -1,20 +1,20 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - - public class SalesReason - { - public virtual int SalesReasonID { get; set; } - - public virtual string Name { get; set; } - - public virtual string ReasonType { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection SalesOrderHeaders { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + + public class SalesReason + { + public virtual int SalesReasonID { get; set; } + + public virtual string Name { get; set; } + + public virtual string ReasonType { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection SalesOrderHeaders { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesTaxRate.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesTaxRate.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesTaxRate.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesTaxRate.cs index 3364b13d..66eadd78 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesTaxRate.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesTaxRate.cs @@ -1,77 +1,77 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class SalesTaxRate - { - public virtual int SalesTaxRateID { get; set; } - - public virtual int StateProvinceID - { - get { return _stateProvinceID; } - set - { - if (_stateProvinceID != value) - { - if (StateProvince != null - && StateProvince.StateProvinceID != value) - { - StateProvince = null; - } - _stateProvinceID = value; - } - } - } - - private int _stateProvinceID; - - public virtual byte TaxType { get; set; } - - public virtual decimal TaxRate { get; set; } - - public virtual string Name { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual StateProvince StateProvince - { - get { return _stateProvince; } - set - { - if (!ReferenceEquals(_stateProvince, value)) - { - var previousValue = _stateProvince; - _stateProvince = value; - FixupStateProvince(previousValue); - } - } - } - - private StateProvince _stateProvince; - - private void FixupStateProvince(StateProvince previousValue) - { - if (previousValue != null - && previousValue.SalesTaxRates.Contains(this)) - { - previousValue.SalesTaxRates.Remove(this); - } - - if (StateProvince != null) - { - if (!StateProvince.SalesTaxRates.Contains(this)) - { - StateProvince.SalesTaxRates.Add(this); - } - if (StateProvinceID != StateProvince.StateProvinceID) - { - StateProvinceID = StateProvince.StateProvinceID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class SalesTaxRate + { + public virtual int SalesTaxRateID { get; set; } + + public virtual int StateProvinceID + { + get { return _stateProvinceID; } + set + { + if (_stateProvinceID != value) + { + if (StateProvince != null + && StateProvince.StateProvinceID != value) + { + StateProvince = null; + } + _stateProvinceID = value; + } + } + } + + private int _stateProvinceID; + + public virtual byte TaxType { get; set; } + + public virtual decimal TaxRate { get; set; } + + public virtual string Name { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual StateProvince StateProvince + { + get { return _stateProvince; } + set + { + if (!ReferenceEquals(_stateProvince, value)) + { + var previousValue = _stateProvince; + _stateProvince = value; + FixupStateProvince(previousValue); + } + } + } + + private StateProvince _stateProvince; + + private void FixupStateProvince(StateProvince previousValue) + { + if (previousValue != null + && previousValue.SalesTaxRates.Contains(this)) + { + previousValue.SalesTaxRates.Remove(this); + } + + if (StateProvince != null) + { + if (!StateProvince.SalesTaxRates.Contains(this)) + { + StateProvince.SalesTaxRates.Add(this); + } + if (StateProvinceID != StateProvince.StateProvinceID) + { + StateProvinceID = StateProvince.StateProvinceID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesTerritory.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesTerritory.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesTerritory.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesTerritory.cs index 7bfcbe95..2d7e5fc4 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesTerritory.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesTerritory.cs @@ -1,308 +1,308 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - using System.ComponentModel.DataAnnotations; - - public class SalesTerritory - { - [Key] - public virtual int TerritoryID { get; set; } - - public virtual string Name { get; set; } - - public virtual string CountryRegionCode { get; set; } - - public virtual string Group { get; set; } - - public virtual decimal SalesYTD { get; set; } - - public virtual decimal SalesLastYear { get; set; } - - public virtual decimal CostYTD { get; set; } - - public virtual decimal CostLastYear { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection StateProvinces - { - get - { - if (_stateProvinces == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupStateProvinces; - _stateProvinces = newCollection; - } - return _stateProvinces; - } - set - { - if (!ReferenceEquals(_stateProvinces, value)) - { - var previousValue = _stateProvinces as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupStateProvinces; - } - _stateProvinces = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupStateProvinces; - } - } - } - } - - private ICollection _stateProvinces; - - public virtual ICollection Customers - { - get - { - if (_customers == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupCustomers; - _customers = newCollection; - } - return _customers; - } - set - { - if (!ReferenceEquals(_customers, value)) - { - var previousValue = _customers as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupCustomers; - } - _customers = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupCustomers; - } - } - } - } - - private ICollection _customers; - - public virtual ICollection SalesOrderHeaders - { - get - { - if (_salesOrderHeaders == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesOrderHeaders; - _salesOrderHeaders = newCollection; - } - return _salesOrderHeaders; - } - set - { - if (!ReferenceEquals(_salesOrderHeaders, value)) - { - var previousValue = _salesOrderHeaders as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesOrderHeaders; - } - _salesOrderHeaders = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesOrderHeaders; - } - } - } - } - - private ICollection _salesOrderHeaders; - - public virtual ICollection SalesPersons - { - get - { - if (_salesPersons == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesPersons; - _salesPersons = newCollection; - } - return _salesPersons; - } - set - { - if (!ReferenceEquals(_salesPersons, value)) - { - var previousValue = _salesPersons as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesPersons; - } - _salesPersons = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesPersons; - } - } - } - } - - private ICollection _salesPersons; - - public virtual ICollection SalesTerritoryHistories - { - get - { - if (_salesTerritoryHistories == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesTerritoryHistories; - _salesTerritoryHistories = newCollection; - } - return _salesTerritoryHistories; - } - set - { - if (!ReferenceEquals(_salesTerritoryHistories, value)) - { - var previousValue = _salesTerritoryHistories as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesTerritoryHistories; - } - _salesTerritoryHistories = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesTerritoryHistories; - } - } - } - } - - private ICollection _salesTerritoryHistories; - - private void FixupStateProvinces(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (StateProvince item in e.NewItems) - { - item.SalesTerritory = this; - } - } - - if (e.OldItems != null) - { - foreach (StateProvince item in e.OldItems) - { - if (ReferenceEquals(item.SalesTerritory, this)) - { - item.SalesTerritory = null; - } - } - } - } - - private void FixupCustomers(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (Customer item in e.NewItems) - { - item.SalesTerritory = this; - } - } - - if (e.OldItems != null) - { - foreach (Customer item in e.OldItems) - { - if (ReferenceEquals(item.SalesTerritory, this)) - { - item.SalesTerritory = null; - } - } - } - } - - private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesOrderHeader item in e.NewItems) - { - item.SalesTerritory = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesOrderHeader item in e.OldItems) - { - if (ReferenceEquals(item.SalesTerritory, this)) - { - item.SalesTerritory = null; - } - } - } - } - - private void FixupSalesPersons(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesPerson item in e.NewItems) - { - item.SalesTerritory = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesPerson item in e.OldItems) - { - if (ReferenceEquals(item.SalesTerritory, this)) - { - item.SalesTerritory = null; - } - } - } - } - - private void FixupSalesTerritoryHistories(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesTerritoryHistory item in e.NewItems) - { - item.SalesTerritory = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesTerritoryHistory item in e.OldItems) - { - if (ReferenceEquals(item.SalesTerritory, this)) - { - item.SalesTerritory = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + using System.ComponentModel.DataAnnotations; + + public class SalesTerritory + { + [Key] + public virtual int TerritoryID { get; set; } + + public virtual string Name { get; set; } + + public virtual string CountryRegionCode { get; set; } + + public virtual string Group { get; set; } + + public virtual decimal SalesYTD { get; set; } + + public virtual decimal SalesLastYear { get; set; } + + public virtual decimal CostYTD { get; set; } + + public virtual decimal CostLastYear { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection StateProvinces + { + get + { + if (_stateProvinces == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupStateProvinces; + _stateProvinces = newCollection; + } + return _stateProvinces; + } + set + { + if (!ReferenceEquals(_stateProvinces, value)) + { + var previousValue = _stateProvinces as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupStateProvinces; + } + _stateProvinces = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupStateProvinces; + } + } + } + } + + private ICollection _stateProvinces; + + public virtual ICollection Customers + { + get + { + if (_customers == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupCustomers; + _customers = newCollection; + } + return _customers; + } + set + { + if (!ReferenceEquals(_customers, value)) + { + var previousValue = _customers as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupCustomers; + } + _customers = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupCustomers; + } + } + } + } + + private ICollection _customers; + + public virtual ICollection SalesOrderHeaders + { + get + { + if (_salesOrderHeaders == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesOrderHeaders; + _salesOrderHeaders = newCollection; + } + return _salesOrderHeaders; + } + set + { + if (!ReferenceEquals(_salesOrderHeaders, value)) + { + var previousValue = _salesOrderHeaders as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesOrderHeaders; + } + _salesOrderHeaders = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesOrderHeaders; + } + } + } + } + + private ICollection _salesOrderHeaders; + + public virtual ICollection SalesPersons + { + get + { + if (_salesPersons == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesPersons; + _salesPersons = newCollection; + } + return _salesPersons; + } + set + { + if (!ReferenceEquals(_salesPersons, value)) + { + var previousValue = _salesPersons as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesPersons; + } + _salesPersons = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesPersons; + } + } + } + } + + private ICollection _salesPersons; + + public virtual ICollection SalesTerritoryHistories + { + get + { + if (_salesTerritoryHistories == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesTerritoryHistories; + _salesTerritoryHistories = newCollection; + } + return _salesTerritoryHistories; + } + set + { + if (!ReferenceEquals(_salesTerritoryHistories, value)) + { + var previousValue = _salesTerritoryHistories as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesTerritoryHistories; + } + _salesTerritoryHistories = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesTerritoryHistories; + } + } + } + } + + private ICollection _salesTerritoryHistories; + + private void FixupStateProvinces(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (StateProvince item in e.NewItems) + { + item.SalesTerritory = this; + } + } + + if (e.OldItems != null) + { + foreach (StateProvince item in e.OldItems) + { + if (ReferenceEquals(item.SalesTerritory, this)) + { + item.SalesTerritory = null; + } + } + } + } + + private void FixupCustomers(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (Customer item in e.NewItems) + { + item.SalesTerritory = this; + } + } + + if (e.OldItems != null) + { + foreach (Customer item in e.OldItems) + { + if (ReferenceEquals(item.SalesTerritory, this)) + { + item.SalesTerritory = null; + } + } + } + } + + private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesOrderHeader item in e.NewItems) + { + item.SalesTerritory = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesOrderHeader item in e.OldItems) + { + if (ReferenceEquals(item.SalesTerritory, this)) + { + item.SalesTerritory = null; + } + } + } + } + + private void FixupSalesPersons(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesPerson item in e.NewItems) + { + item.SalesTerritory = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesPerson item in e.OldItems) + { + if (ReferenceEquals(item.SalesTerritory, this)) + { + item.SalesTerritory = null; + } + } + } + } + + private void FixupSalesTerritoryHistories(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesTerritoryHistory item in e.NewItems) + { + item.SalesTerritory = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesTerritoryHistory item in e.OldItems) + { + if (ReferenceEquals(item.SalesTerritory, this)) + { + item.SalesTerritory = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesTerritoryHistory.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesTerritoryHistory.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesTerritoryHistory.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesTerritoryHistory.cs index b3090cba..541746db 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SalesTerritoryHistory.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SalesTerritoryHistory.cs @@ -1,129 +1,129 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class SalesTerritoryHistory - { - public virtual int SalesPersonID - { - get { return _salesPersonID; } - set - { - if (_salesPersonID != value) - { - if (SalesPerson != null - && SalesPerson.SalesPersonID != value) - { - SalesPerson = null; - } - _salesPersonID = value; - } - } - } - - private int _salesPersonID; - - public virtual int TerritoryID - { - get { return _territoryID; } - set - { - if (_territoryID != value) - { - if (SalesTerritory != null - && SalesTerritory.TerritoryID != value) - { - SalesTerritory = null; - } - _territoryID = value; - } - } - } - - private int _territoryID; - - public virtual DateTime StartDate { get; set; } - - public virtual DateTime? EndDate { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual SalesPerson SalesPerson - { - get { return _salesPerson; } - set - { - if (!ReferenceEquals(_salesPerson, value)) - { - var previousValue = _salesPerson; - _salesPerson = value; - FixupSalesPerson(previousValue); - } - } - } - - private SalesPerson _salesPerson; - - public virtual SalesTerritory SalesTerritory - { - get { return _salesTerritory; } - set - { - if (!ReferenceEquals(_salesTerritory, value)) - { - var previousValue = _salesTerritory; - _salesTerritory = value; - FixupSalesTerritory(previousValue); - } - } - } - - private SalesTerritory _salesTerritory; - - private void FixupSalesPerson(SalesPerson previousValue) - { - if (previousValue != null - && previousValue.SalesTerritoryHistories.Contains(this)) - { - previousValue.SalesTerritoryHistories.Remove(this); - } - - if (SalesPerson != null) - { - if (!SalesPerson.SalesTerritoryHistories.Contains(this)) - { - SalesPerson.SalesTerritoryHistories.Add(this); - } - if (SalesPersonID != SalesPerson.SalesPersonID) - { - SalesPersonID = SalesPerson.SalesPersonID; - } - } - } - - private void FixupSalesTerritory(SalesTerritory previousValue) - { - if (previousValue != null - && previousValue.SalesTerritoryHistories.Contains(this)) - { - previousValue.SalesTerritoryHistories.Remove(this); - } - - if (SalesTerritory != null) - { - if (!SalesTerritory.SalesTerritoryHistories.Contains(this)) - { - SalesTerritory.SalesTerritoryHistories.Add(this); - } - if (TerritoryID != SalesTerritory.TerritoryID) - { - TerritoryID = SalesTerritory.TerritoryID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class SalesTerritoryHistory + { + public virtual int SalesPersonID + { + get { return _salesPersonID; } + set + { + if (_salesPersonID != value) + { + if (SalesPerson != null + && SalesPerson.SalesPersonID != value) + { + SalesPerson = null; + } + _salesPersonID = value; + } + } + } + + private int _salesPersonID; + + public virtual int TerritoryID + { + get { return _territoryID; } + set + { + if (_territoryID != value) + { + if (SalesTerritory != null + && SalesTerritory.TerritoryID != value) + { + SalesTerritory = null; + } + _territoryID = value; + } + } + } + + private int _territoryID; + + public virtual DateTime StartDate { get; set; } + + public virtual DateTime? EndDate { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual SalesPerson SalesPerson + { + get { return _salesPerson; } + set + { + if (!ReferenceEquals(_salesPerson, value)) + { + var previousValue = _salesPerson; + _salesPerson = value; + FixupSalesPerson(previousValue); + } + } + } + + private SalesPerson _salesPerson; + + public virtual SalesTerritory SalesTerritory + { + get { return _salesTerritory; } + set + { + if (!ReferenceEquals(_salesTerritory, value)) + { + var previousValue = _salesTerritory; + _salesTerritory = value; + FixupSalesTerritory(previousValue); + } + } + } + + private SalesTerritory _salesTerritory; + + private void FixupSalesPerson(SalesPerson previousValue) + { + if (previousValue != null + && previousValue.SalesTerritoryHistories.Contains(this)) + { + previousValue.SalesTerritoryHistories.Remove(this); + } + + if (SalesPerson != null) + { + if (!SalesPerson.SalesTerritoryHistories.Contains(this)) + { + SalesPerson.SalesTerritoryHistories.Add(this); + } + if (SalesPersonID != SalesPerson.SalesPersonID) + { + SalesPersonID = SalesPerson.SalesPersonID; + } + } + } + + private void FixupSalesTerritory(SalesTerritory previousValue) + { + if (previousValue != null + && previousValue.SalesTerritoryHistories.Contains(this)) + { + previousValue.SalesTerritoryHistories.Remove(this); + } + + if (SalesTerritory != null) + { + if (!SalesTerritory.SalesTerritoryHistories.Contains(this)) + { + SalesTerritory.SalesTerritoryHistories.Add(this); + } + if (TerritoryID != SalesTerritory.TerritoryID) + { + TerritoryID = SalesTerritory.TerritoryID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ScrapReason.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ScrapReason.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ScrapReason.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ScrapReason.cs index 8a4671f3..3b1aadd5 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ScrapReason.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ScrapReason.cs @@ -1,72 +1,72 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class ScrapReason - { - public virtual short ScrapReasonID { get; set; } - - public virtual string Name { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection WorkOrders - { - get - { - if (_workOrders == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupWorkOrders; - _workOrders = newCollection; - } - return _workOrders; - } - set - { - if (!ReferenceEquals(_workOrders, value)) - { - var previousValue = _workOrders as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupWorkOrders; - } - _workOrders = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupWorkOrders; - } - } - } - } - - private ICollection _workOrders; - - private void FixupWorkOrders(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (WorkOrder item in e.NewItems) - { - item.ScrapReason = this; - } - } - - if (e.OldItems != null) - { - foreach (WorkOrder item in e.OldItems) - { - if (ReferenceEquals(item.ScrapReason, this)) - { - item.ScrapReason = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class ScrapReason + { + public virtual short ScrapReasonID { get; set; } + + public virtual string Name { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection WorkOrders + { + get + { + if (_workOrders == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupWorkOrders; + _workOrders = newCollection; + } + return _workOrders; + } + set + { + if (!ReferenceEquals(_workOrders, value)) + { + var previousValue = _workOrders as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupWorkOrders; + } + _workOrders = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupWorkOrders; + } + } + } + } + + private ICollection _workOrders; + + private void FixupWorkOrders(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (WorkOrder item in e.NewItems) + { + item.ScrapReason = this; + } + } + + if (e.OldItems != null) + { + foreach (WorkOrder item in e.OldItems) + { + if (ReferenceEquals(item.ScrapReason, this)) + { + item.ScrapReason = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Shift.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Shift.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/Shift.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Shift.cs index de8cebda..52211642 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Shift.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Shift.cs @@ -1,76 +1,76 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class Shift - { - public virtual byte ShiftID { get; set; } - - public virtual string Name { get; set; } - - public virtual DateTime StartTime { get; set; } - - public virtual DateTime EndTime { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection EmployeeDepartmentHistories - { - get - { - if (_employeeDepartmentHistories == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupEmployeeDepartmentHistories; - _employeeDepartmentHistories = newCollection; - } - return _employeeDepartmentHistories; - } - set - { - if (!ReferenceEquals(_employeeDepartmentHistories, value)) - { - var previousValue = _employeeDepartmentHistories as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupEmployeeDepartmentHistories; - } - _employeeDepartmentHistories = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupEmployeeDepartmentHistories; - } - } - } - } - - private ICollection _employeeDepartmentHistories; - - private void FixupEmployeeDepartmentHistories(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (EmployeeDepartmentHistory item in e.NewItems) - { - item.Shift = this; - } - } - - if (e.OldItems != null) - { - foreach (EmployeeDepartmentHistory item in e.OldItems) - { - if (ReferenceEquals(item.Shift, this)) - { - item.Shift = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class Shift + { + public virtual byte ShiftID { get; set; } + + public virtual string Name { get; set; } + + public virtual DateTime StartTime { get; set; } + + public virtual DateTime EndTime { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection EmployeeDepartmentHistories + { + get + { + if (_employeeDepartmentHistories == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupEmployeeDepartmentHistories; + _employeeDepartmentHistories = newCollection; + } + return _employeeDepartmentHistories; + } + set + { + if (!ReferenceEquals(_employeeDepartmentHistories, value)) + { + var previousValue = _employeeDepartmentHistories as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupEmployeeDepartmentHistories; + } + _employeeDepartmentHistories = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupEmployeeDepartmentHistories; + } + } + } + } + + private ICollection _employeeDepartmentHistories; + + private void FixupEmployeeDepartmentHistories(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (EmployeeDepartmentHistory item in e.NewItems) + { + item.Shift = this; + } + } + + if (e.OldItems != null) + { + foreach (EmployeeDepartmentHistory item in e.OldItems) + { + if (ReferenceEquals(item.Shift, this)) + { + item.Shift = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ShipMethod.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ShipMethod.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ShipMethod.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ShipMethod.cs index 1b282c7a..a49e6888 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ShipMethod.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ShipMethod.cs @@ -1,133 +1,133 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class ShipMethod - { - public virtual int ShipMethodID { get; set; } - - public virtual string Name { get; set; } - - public virtual decimal ShipBase { get; set; } - - public virtual decimal ShipRate { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection PurchaseOrderHeaders - { - get - { - if (_purchaseOrderHeaders == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupPurchaseOrderHeaders; - _purchaseOrderHeaders = newCollection; - } - return _purchaseOrderHeaders; - } - set - { - if (!ReferenceEquals(_purchaseOrderHeaders, value)) - { - var previousValue = _purchaseOrderHeaders as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupPurchaseOrderHeaders; - } - _purchaseOrderHeaders = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupPurchaseOrderHeaders; - } - } - } - } - - private ICollection _purchaseOrderHeaders; - - public virtual ICollection SalesOrderHeaders - { - get - { - if (_salesOrderHeaders == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesOrderHeaders; - _salesOrderHeaders = newCollection; - } - return _salesOrderHeaders; - } - set - { - if (!ReferenceEquals(_salesOrderHeaders, value)) - { - var previousValue = _salesOrderHeaders as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesOrderHeaders; - } - _salesOrderHeaders = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesOrderHeaders; - } - } - } - } - - private ICollection _salesOrderHeaders; - - private void FixupPurchaseOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (PurchaseOrderHeader item in e.NewItems) - { - item.ShipMethod = this; - } - } - - if (e.OldItems != null) - { - foreach (PurchaseOrderHeader item in e.OldItems) - { - if (ReferenceEquals(item.ShipMethod, this)) - { - item.ShipMethod = null; - } - } - } - } - - private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesOrderHeader item in e.NewItems) - { - item.ShipMethod = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesOrderHeader item in e.OldItems) - { - if (ReferenceEquals(item.ShipMethod, this)) - { - item.ShipMethod = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class ShipMethod + { + public virtual int ShipMethodID { get; set; } + + public virtual string Name { get; set; } + + public virtual decimal ShipBase { get; set; } + + public virtual decimal ShipRate { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection PurchaseOrderHeaders + { + get + { + if (_purchaseOrderHeaders == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupPurchaseOrderHeaders; + _purchaseOrderHeaders = newCollection; + } + return _purchaseOrderHeaders; + } + set + { + if (!ReferenceEquals(_purchaseOrderHeaders, value)) + { + var previousValue = _purchaseOrderHeaders as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupPurchaseOrderHeaders; + } + _purchaseOrderHeaders = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupPurchaseOrderHeaders; + } + } + } + } + + private ICollection _purchaseOrderHeaders; + + public virtual ICollection SalesOrderHeaders + { + get + { + if (_salesOrderHeaders == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesOrderHeaders; + _salesOrderHeaders = newCollection; + } + return _salesOrderHeaders; + } + set + { + if (!ReferenceEquals(_salesOrderHeaders, value)) + { + var previousValue = _salesOrderHeaders as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesOrderHeaders; + } + _salesOrderHeaders = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesOrderHeaders; + } + } + } + } + + private ICollection _salesOrderHeaders; + + private void FixupPurchaseOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (PurchaseOrderHeader item in e.NewItems) + { + item.ShipMethod = this; + } + } + + if (e.OldItems != null) + { + foreach (PurchaseOrderHeader item in e.OldItems) + { + if (ReferenceEquals(item.ShipMethod, this)) + { + item.ShipMethod = null; + } + } + } + } + + private void FixupSalesOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesOrderHeader item in e.NewItems) + { + item.ShipMethod = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesOrderHeader item in e.OldItems) + { + if (ReferenceEquals(item.ShipMethod, this)) + { + item.ShipMethod = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ShoppingCartItem.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ShoppingCartItem.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/ShoppingCartItem.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ShoppingCartItem.cs index 811c2db3..896a9f65 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/ShoppingCartItem.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/ShoppingCartItem.cs @@ -1,77 +1,77 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.ComponentModel.DataAnnotations.Schema; - - public class ShoppingCartItem - { - public virtual int ShoppingCartItemID { get; set; } - - public virtual string ShoppingCartID { get; set; } - - public virtual int Quantity { get; set; } - - public virtual int ProductID - { - get { return _productID; } - set - { - if (_productID != value) - { - if (Product != null - && Product.ProductID != value) - { - Product = null; - } - _productID = value; - } - } - } - - private int _productID; - - public virtual DateTime DateCreated { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - [InverseProperty("ShoppingCartItems")] - public virtual Product Product - { - get { return _product; } - set - { - if (!ReferenceEquals(_product, value)) - { - var previousValue = _product; - _product = value; - FixupProduct(previousValue); - } - } - } - - private Product _product; - - private void FixupProduct(Product previousValue) - { - if (previousValue != null - && previousValue.ShoppingCartItems.Contains(this)) - { - previousValue.ShoppingCartItems.Remove(this); - } - - if (Product != null) - { - if (!Product.ShoppingCartItems.Contains(this)) - { - Product.ShoppingCartItems.Add(this); - } - if (ProductID != Product.ProductID) - { - ProductID = Product.ProductID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.ComponentModel.DataAnnotations.Schema; + + public class ShoppingCartItem + { + public virtual int ShoppingCartItemID { get; set; } + + public virtual string ShoppingCartID { get; set; } + + public virtual int Quantity { get; set; } + + public virtual int ProductID + { + get { return _productID; } + set + { + if (_productID != value) + { + if (Product != null + && Product.ProductID != value) + { + Product = null; + } + _productID = value; + } + } + } + + private int _productID; + + public virtual DateTime DateCreated { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + [InverseProperty("ShoppingCartItems")] + public virtual Product Product + { + get { return _product; } + set + { + if (!ReferenceEquals(_product, value)) + { + var previousValue = _product; + _product = value; + FixupProduct(previousValue); + } + } + } + + private Product _product; + + private void FixupProduct(Product previousValue) + { + if (previousValue != null + && previousValue.ShoppingCartItems.Contains(this)) + { + previousValue.ShoppingCartItems.Remove(this); + } + + if (Product != null) + { + if (!Product.ShoppingCartItems.Contains(this)) + { + Product.ShoppingCartItems.Add(this); + } + if (ProductID != Product.ProductID) + { + ProductID = Product.ProductID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SpecialOffer.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SpecialOffer.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/SpecialOffer.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SpecialOffer.cs index 88e8f2b2..8ff9636b 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SpecialOffer.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SpecialOffer.cs @@ -1,88 +1,88 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class SpecialOffer - { - public virtual int SpecialOfferID { get; set; } - - public virtual string Description { get; set; } - - public virtual decimal DiscountPct { get; set; } - - public virtual string Type { get; set; } - - public virtual string Category { get; set; } - - public virtual DateTime StartDate { get; set; } - - public virtual DateTime EndDate { get; set; } - - public virtual int MinQty { get; set; } - - public virtual int? MaxQty { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection SpecialOfferProducts - { - get - { - if (_specialOfferProducts == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSpecialOfferProducts; - _specialOfferProducts = newCollection; - } - return _specialOfferProducts; - } - set - { - if (!ReferenceEquals(_specialOfferProducts, value)) - { - var previousValue = _specialOfferProducts as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSpecialOfferProducts; - } - _specialOfferProducts = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSpecialOfferProducts; - } - } - } - } - - private ICollection _specialOfferProducts; - - private void FixupSpecialOfferProducts(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SpecialOfferProduct item in e.NewItems) - { - item.SpecialOffer = this; - } - } - - if (e.OldItems != null) - { - foreach (SpecialOfferProduct item in e.OldItems) - { - if (ReferenceEquals(item.SpecialOffer, this)) - { - item.SpecialOffer = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class SpecialOffer + { + public virtual int SpecialOfferID { get; set; } + + public virtual string Description { get; set; } + + public virtual decimal DiscountPct { get; set; } + + public virtual string Type { get; set; } + + public virtual string Category { get; set; } + + public virtual DateTime StartDate { get; set; } + + public virtual DateTime EndDate { get; set; } + + public virtual int MinQty { get; set; } + + public virtual int? MaxQty { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection SpecialOfferProducts + { + get + { + if (_specialOfferProducts == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSpecialOfferProducts; + _specialOfferProducts = newCollection; + } + return _specialOfferProducts; + } + set + { + if (!ReferenceEquals(_specialOfferProducts, value)) + { + var previousValue = _specialOfferProducts as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSpecialOfferProducts; + } + _specialOfferProducts = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSpecialOfferProducts; + } + } + } + } + + private ICollection _specialOfferProducts; + + private void FixupSpecialOfferProducts(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SpecialOfferProduct item in e.NewItems) + { + item.SpecialOffer = this; + } + } + + if (e.OldItems != null) + { + foreach (SpecialOfferProduct item in e.OldItems) + { + if (ReferenceEquals(item.SpecialOffer, this)) + { + item.SpecialOffer = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SpecialOfferProduct.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SpecialOfferProduct.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/SpecialOfferProduct.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SpecialOfferProduct.cs index 8a7ab7d0..d0db25b2 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/SpecialOfferProduct.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/SpecialOfferProduct.cs @@ -1,182 +1,182 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class SpecialOfferProduct - { - public virtual int SpecialOfferID - { - get { return _specialOfferID; } - set - { - if (_specialOfferID != value) - { - if (SpecialOffer != null - && SpecialOffer.SpecialOfferID != value) - { - SpecialOffer = null; - } - _specialOfferID = value; - } - } - } - - private int _specialOfferID; - - public virtual int ProductID - { - get { return _productID; } - set - { - if (_productID != value) - { - if (Product != null - && Product.ProductID != value) - { - Product = null; - } - _productID = value; - } - } - } - - private int _productID; - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Product Product - { - get { return _product; } - set - { - if (!ReferenceEquals(_product, value)) - { - var previousValue = _product; - _product = value; - FixupProduct(previousValue); - } - } - } - - private Product _product; - - public virtual ICollection SalesOrderDetails - { - get - { - if (_salesOrderDetails == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesOrderDetails; - _salesOrderDetails = newCollection; - } - return _salesOrderDetails; - } - set - { - if (!ReferenceEquals(_salesOrderDetails, value)) - { - var previousValue = _salesOrderDetails as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesOrderDetails; - } - _salesOrderDetails = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesOrderDetails; - } - } - } - } - - private ICollection _salesOrderDetails; - - public virtual SpecialOffer SpecialOffer - { - get { return _specialOffer; } - set - { - if (!ReferenceEquals(_specialOffer, value)) - { - var previousValue = _specialOffer; - _specialOffer = value; - FixupSpecialOffer(previousValue); - } - } - } - - private SpecialOffer _specialOffer; - - private void FixupProduct(Product previousValue) - { - if (previousValue != null - && previousValue.SpecialOfferProducts.Contains(this)) - { - previousValue.SpecialOfferProducts.Remove(this); - } - - if (Product != null) - { - if (!Product.SpecialOfferProducts.Contains(this)) - { - Product.SpecialOfferProducts.Add(this); - } - if (ProductID != Product.ProductID) - { - ProductID = Product.ProductID; - } - } - } - - private void FixupSpecialOffer(SpecialOffer previousValue) - { - if (previousValue != null - && previousValue.SpecialOfferProducts.Contains(this)) - { - previousValue.SpecialOfferProducts.Remove(this); - } - - if (SpecialOffer != null) - { - if (!SpecialOffer.SpecialOfferProducts.Contains(this)) - { - SpecialOffer.SpecialOfferProducts.Add(this); - } - if (SpecialOfferID != SpecialOffer.SpecialOfferID) - { - SpecialOfferID = SpecialOffer.SpecialOfferID; - } - } - } - - private void FixupSalesOrderDetails(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesOrderDetail item in e.NewItems) - { - item.SpecialOfferProduct = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesOrderDetail item in e.OldItems) - { - if (ReferenceEquals(item.SpecialOfferProduct, this)) - { - item.SpecialOfferProduct = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class SpecialOfferProduct + { + public virtual int SpecialOfferID + { + get { return _specialOfferID; } + set + { + if (_specialOfferID != value) + { + if (SpecialOffer != null + && SpecialOffer.SpecialOfferID != value) + { + SpecialOffer = null; + } + _specialOfferID = value; + } + } + } + + private int _specialOfferID; + + public virtual int ProductID + { + get { return _productID; } + set + { + if (_productID != value) + { + if (Product != null + && Product.ProductID != value) + { + Product = null; + } + _productID = value; + } + } + } + + private int _productID; + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Product Product + { + get { return _product; } + set + { + if (!ReferenceEquals(_product, value)) + { + var previousValue = _product; + _product = value; + FixupProduct(previousValue); + } + } + } + + private Product _product; + + public virtual ICollection SalesOrderDetails + { + get + { + if (_salesOrderDetails == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesOrderDetails; + _salesOrderDetails = newCollection; + } + return _salesOrderDetails; + } + set + { + if (!ReferenceEquals(_salesOrderDetails, value)) + { + var previousValue = _salesOrderDetails as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesOrderDetails; + } + _salesOrderDetails = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesOrderDetails; + } + } + } + } + + private ICollection _salesOrderDetails; + + public virtual SpecialOffer SpecialOffer + { + get { return _specialOffer; } + set + { + if (!ReferenceEquals(_specialOffer, value)) + { + var previousValue = _specialOffer; + _specialOffer = value; + FixupSpecialOffer(previousValue); + } + } + } + + private SpecialOffer _specialOffer; + + private void FixupProduct(Product previousValue) + { + if (previousValue != null + && previousValue.SpecialOfferProducts.Contains(this)) + { + previousValue.SpecialOfferProducts.Remove(this); + } + + if (Product != null) + { + if (!Product.SpecialOfferProducts.Contains(this)) + { + Product.SpecialOfferProducts.Add(this); + } + if (ProductID != Product.ProductID) + { + ProductID = Product.ProductID; + } + } + } + + private void FixupSpecialOffer(SpecialOffer previousValue) + { + if (previousValue != null + && previousValue.SpecialOfferProducts.Contains(this)) + { + previousValue.SpecialOfferProducts.Remove(this); + } + + if (SpecialOffer != null) + { + if (!SpecialOffer.SpecialOfferProducts.Contains(this)) + { + SpecialOffer.SpecialOfferProducts.Add(this); + } + if (SpecialOfferID != SpecialOffer.SpecialOfferID) + { + SpecialOfferID = SpecialOffer.SpecialOfferID; + } + } + } + + private void FixupSalesOrderDetails(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesOrderDetail item in e.NewItems) + { + item.SpecialOfferProduct = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesOrderDetail item in e.OldItems) + { + if (ReferenceEquals(item.SpecialOfferProduct, this)) + { + item.SpecialOfferProduct = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/StateProvince.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/StateProvince.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/StateProvince.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/StateProvince.cs index 5759cba3..c71bce4c 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/StateProvince.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/StateProvince.cs @@ -1,245 +1,245 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class StateProvince - { - public virtual int StateProvinceID { get; set; } - - public virtual string StateProvinceCode { get; set; } - - public virtual string CountryRegionCode - { - get { return _countryRegionCode; } - set - { - if (_countryRegionCode != value) - { - if (CountryRegion != null - && CountryRegion.CountryRegionCode != value) - { - CountryRegion = null; - } - _countryRegionCode = value; - } - } - } - - private string _countryRegionCode; - - public virtual bool IsOnlyStateProvinceFlag { get; set; } - - public virtual string Name { get; set; } - - public virtual int TerritoryID - { - get { return _territoryID; } - set - { - if (_territoryID != value) - { - if (SalesTerritory != null - && SalesTerritory.TerritoryID != value) - { - SalesTerritory = null; - } - _territoryID = value; - } - } - } - - private int _territoryID; - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection
Addresses - { - get - { - if (_addresses == null) - { - var newCollection = new FixupCollection
(); - newCollection.CollectionChanged += FixupAddresses; - _addresses = newCollection; - } - return _addresses; - } - set - { - if (!ReferenceEquals(_addresses, value)) - { - var previousValue = _addresses as FixupCollection
; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupAddresses; - } - _addresses = value; - var newValue = value as FixupCollection
; - if (newValue != null) - { - newValue.CollectionChanged += FixupAddresses; - } - } - } - } - - private ICollection
_addresses; - - public virtual CountryRegion CountryRegion - { - get { return _countryRegion; } - set - { - if (!ReferenceEquals(_countryRegion, value)) - { - var previousValue = _countryRegion; - _countryRegion = value; - FixupCountryRegion(previousValue); - } - } - } - - private CountryRegion _countryRegion; - - public virtual ICollection SalesTaxRates - { - get - { - if (_salesTaxRates == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupSalesTaxRates; - _salesTaxRates = newCollection; - } - return _salesTaxRates; - } - set - { - if (!ReferenceEquals(_salesTaxRates, value)) - { - var previousValue = _salesTaxRates as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupSalesTaxRates; - } - _salesTaxRates = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupSalesTaxRates; - } - } - } - } - - private ICollection _salesTaxRates; - - public virtual SalesTerritory SalesTerritory - { - get { return _salesTerritory; } - set - { - if (!ReferenceEquals(_salesTerritory, value)) - { - var previousValue = _salesTerritory; - _salesTerritory = value; - FixupSalesTerritory(previousValue); - } - } - } - - private SalesTerritory _salesTerritory; - - private void FixupCountryRegion(CountryRegion previousValue) - { - if (previousValue != null - && previousValue.StateProvinces.Contains(this)) - { - previousValue.StateProvinces.Remove(this); - } - - if (CountryRegion != null) - { - if (!CountryRegion.StateProvinces.Contains(this)) - { - CountryRegion.StateProvinces.Add(this); - } - if (CountryRegionCode != CountryRegion.CountryRegionCode) - { - CountryRegionCode = CountryRegion.CountryRegionCode; - } - } - } - - private void FixupSalesTerritory(SalesTerritory previousValue) - { - if (previousValue != null - && previousValue.StateProvinces.Contains(this)) - { - previousValue.StateProvinces.Remove(this); - } - - if (SalesTerritory != null) - { - if (!SalesTerritory.StateProvinces.Contains(this)) - { - SalesTerritory.StateProvinces.Add(this); - } - if (TerritoryID != SalesTerritory.TerritoryID) - { - TerritoryID = SalesTerritory.TerritoryID; - } - } - } - - private void FixupAddresses(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (Address item in e.NewItems) - { - item.StateProvince = this; - } - } - - if (e.OldItems != null) - { - foreach (Address item in e.OldItems) - { - if (ReferenceEquals(item.StateProvince, this)) - { - item.StateProvince = null; - } - } - } - } - - private void FixupSalesTaxRates(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (SalesTaxRate item in e.NewItems) - { - item.StateProvince = this; - } - } - - if (e.OldItems != null) - { - foreach (SalesTaxRate item in e.OldItems) - { - if (ReferenceEquals(item.StateProvince, this)) - { - item.StateProvince = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class StateProvince + { + public virtual int StateProvinceID { get; set; } + + public virtual string StateProvinceCode { get; set; } + + public virtual string CountryRegionCode + { + get { return _countryRegionCode; } + set + { + if (_countryRegionCode != value) + { + if (CountryRegion != null + && CountryRegion.CountryRegionCode != value) + { + CountryRegion = null; + } + _countryRegionCode = value; + } + } + } + + private string _countryRegionCode; + + public virtual bool IsOnlyStateProvinceFlag { get; set; } + + public virtual string Name { get; set; } + + public virtual int TerritoryID + { + get { return _territoryID; } + set + { + if (_territoryID != value) + { + if (SalesTerritory != null + && SalesTerritory.TerritoryID != value) + { + SalesTerritory = null; + } + _territoryID = value; + } + } + } + + private int _territoryID; + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection
Addresses + { + get + { + if (_addresses == null) + { + var newCollection = new FixupCollection
(); + newCollection.CollectionChanged += FixupAddresses; + _addresses = newCollection; + } + return _addresses; + } + set + { + if (!ReferenceEquals(_addresses, value)) + { + var previousValue = _addresses as FixupCollection
; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupAddresses; + } + _addresses = value; + var newValue = value as FixupCollection
; + if (newValue != null) + { + newValue.CollectionChanged += FixupAddresses; + } + } + } + } + + private ICollection
_addresses; + + public virtual CountryRegion CountryRegion + { + get { return _countryRegion; } + set + { + if (!ReferenceEquals(_countryRegion, value)) + { + var previousValue = _countryRegion; + _countryRegion = value; + FixupCountryRegion(previousValue); + } + } + } + + private CountryRegion _countryRegion; + + public virtual ICollection SalesTaxRates + { + get + { + if (_salesTaxRates == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupSalesTaxRates; + _salesTaxRates = newCollection; + } + return _salesTaxRates; + } + set + { + if (!ReferenceEquals(_salesTaxRates, value)) + { + var previousValue = _salesTaxRates as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupSalesTaxRates; + } + _salesTaxRates = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupSalesTaxRates; + } + } + } + } + + private ICollection _salesTaxRates; + + public virtual SalesTerritory SalesTerritory + { + get { return _salesTerritory; } + set + { + if (!ReferenceEquals(_salesTerritory, value)) + { + var previousValue = _salesTerritory; + _salesTerritory = value; + FixupSalesTerritory(previousValue); + } + } + } + + private SalesTerritory _salesTerritory; + + private void FixupCountryRegion(CountryRegion previousValue) + { + if (previousValue != null + && previousValue.StateProvinces.Contains(this)) + { + previousValue.StateProvinces.Remove(this); + } + + if (CountryRegion != null) + { + if (!CountryRegion.StateProvinces.Contains(this)) + { + CountryRegion.StateProvinces.Add(this); + } + if (CountryRegionCode != CountryRegion.CountryRegionCode) + { + CountryRegionCode = CountryRegion.CountryRegionCode; + } + } + } + + private void FixupSalesTerritory(SalesTerritory previousValue) + { + if (previousValue != null + && previousValue.StateProvinces.Contains(this)) + { + previousValue.StateProvinces.Remove(this); + } + + if (SalesTerritory != null) + { + if (!SalesTerritory.StateProvinces.Contains(this)) + { + SalesTerritory.StateProvinces.Add(this); + } + if (TerritoryID != SalesTerritory.TerritoryID) + { + TerritoryID = SalesTerritory.TerritoryID; + } + } + } + + private void FixupAddresses(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (Address item in e.NewItems) + { + item.StateProvince = this; + } + } + + if (e.OldItems != null) + { + foreach (Address item in e.OldItems) + { + if (ReferenceEquals(item.StateProvince, this)) + { + item.StateProvince = null; + } + } + } + } + + private void FixupSalesTaxRates(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (SalesTaxRate item in e.NewItems) + { + item.StateProvince = this; + } + } + + if (e.OldItems != null) + { + foreach (SalesTaxRate item in e.OldItems) + { + if (ReferenceEquals(item.StateProvince, this)) + { + item.StateProvince = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Store.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Store.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/Store.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Store.cs index 9872b51f..c98bb4e1 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Store.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Store.cs @@ -1,205 +1,205 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class Store - { - public virtual int CustomerID - { - get { return _customerID; } - set - { - try - { - _settingFK = true; - if (_customerID != value) - { - if (Customer != null - && Customer.CustomerID != value) - { - Customer = null; - } - _customerID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int _customerID; - - public virtual string Name { get; set; } - - public virtual int? SalesPersonID - { - get { return _salesPersonID; } - set - { - try - { - _settingFK = true; - if (_salesPersonID != value) - { - if (SalesPerson != null - && SalesPerson.SalesPersonID != value) - { - SalesPerson = null; - } - _salesPersonID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int? _salesPersonID; - - public virtual string Demographics { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Customer Customer - { - get { return _customer; } - set - { - if (!ReferenceEquals(_customer, value)) - { - var previousValue = _customer; - _customer = value; - FixupCustomer(previousValue); - } - } - } - - private Customer _customer; - - public virtual SalesPerson SalesPerson - { - get { return _salesPerson; } - set - { - if (!ReferenceEquals(_salesPerson, value)) - { - var previousValue = _salesPerson; - _salesPerson = value; - FixupSalesPerson(previousValue); - } - } - } - - private SalesPerson _salesPerson; - - public virtual ICollection StoreContacts - { - get - { - if (_storeContacts == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupStoreContacts; - _storeContacts = newCollection; - } - return _storeContacts; - } - set - { - if (!ReferenceEquals(_storeContacts, value)) - { - var previousValue = _storeContacts as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupStoreContacts; - } - _storeContacts = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupStoreContacts; - } - } - } - } - - private ICollection _storeContacts; - - private bool _settingFK; - - private void FixupCustomer(Customer previousValue) - { - if (previousValue != null - && ReferenceEquals(previousValue.Store, this)) - { - previousValue.Store = null; - } - - if (Customer != null) - { - Customer.Store = this; - if (CustomerID != Customer.CustomerID) - { - CustomerID = Customer.CustomerID; - } - } - } - - private void FixupSalesPerson(SalesPerson previousValue) - { - if (previousValue != null - && previousValue.Stores.Contains(this)) - { - previousValue.Stores.Remove(this); - } - - if (SalesPerson != null) - { - if (!SalesPerson.Stores.Contains(this)) - { - SalesPerson.Stores.Add(this); - } - if (SalesPersonID != SalesPerson.SalesPersonID) - { - SalesPersonID = SalesPerson.SalesPersonID; - } - } - else if (!_settingFK) - { - SalesPersonID = null; - } - } - - private void FixupStoreContacts(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (StoreContact item in e.NewItems) - { - item.Store = this; - } - } - - if (e.OldItems != null) - { - foreach (StoreContact item in e.OldItems) - { - if (ReferenceEquals(item.Store, this)) - { - item.Store = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class Store + { + public virtual int CustomerID + { + get { return _customerID; } + set + { + try + { + _settingFK = true; + if (_customerID != value) + { + if (Customer != null + && Customer.CustomerID != value) + { + Customer = null; + } + _customerID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int _customerID; + + public virtual string Name { get; set; } + + public virtual int? SalesPersonID + { + get { return _salesPersonID; } + set + { + try + { + _settingFK = true; + if (_salesPersonID != value) + { + if (SalesPerson != null + && SalesPerson.SalesPersonID != value) + { + SalesPerson = null; + } + _salesPersonID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int? _salesPersonID; + + public virtual string Demographics { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Customer Customer + { + get { return _customer; } + set + { + if (!ReferenceEquals(_customer, value)) + { + var previousValue = _customer; + _customer = value; + FixupCustomer(previousValue); + } + } + } + + private Customer _customer; + + public virtual SalesPerson SalesPerson + { + get { return _salesPerson; } + set + { + if (!ReferenceEquals(_salesPerson, value)) + { + var previousValue = _salesPerson; + _salesPerson = value; + FixupSalesPerson(previousValue); + } + } + } + + private SalesPerson _salesPerson; + + public virtual ICollection StoreContacts + { + get + { + if (_storeContacts == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupStoreContacts; + _storeContacts = newCollection; + } + return _storeContacts; + } + set + { + if (!ReferenceEquals(_storeContacts, value)) + { + var previousValue = _storeContacts as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupStoreContacts; + } + _storeContacts = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupStoreContacts; + } + } + } + } + + private ICollection _storeContacts; + + private bool _settingFK; + + private void FixupCustomer(Customer previousValue) + { + if (previousValue != null + && ReferenceEquals(previousValue.Store, this)) + { + previousValue.Store = null; + } + + if (Customer != null) + { + Customer.Store = this; + if (CustomerID != Customer.CustomerID) + { + CustomerID = Customer.CustomerID; + } + } + } + + private void FixupSalesPerson(SalesPerson previousValue) + { + if (previousValue != null + && previousValue.Stores.Contains(this)) + { + previousValue.Stores.Remove(this); + } + + if (SalesPerson != null) + { + if (!SalesPerson.Stores.Contains(this)) + { + SalesPerson.Stores.Add(this); + } + if (SalesPersonID != SalesPerson.SalesPersonID) + { + SalesPersonID = SalesPerson.SalesPersonID; + } + } + else if (!_settingFK) + { + SalesPersonID = null; + } + } + + private void FixupStoreContacts(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (StoreContact item in e.NewItems) + { + item.Store = this; + } + } + + if (e.OldItems != null) + { + foreach (StoreContact item in e.OldItems) + { + if (ReferenceEquals(item.Store, this)) + { + item.Store = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/StoreContact.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/StoreContact.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/StoreContact.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/StoreContact.cs index 5391004c..48040513 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/StoreContact.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/StoreContact.cs @@ -1,181 +1,181 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class StoreContact - { - public virtual int CustomerID - { - get { return _customerID; } - set - { - if (_customerID != value) - { - if (Store != null - && Store.CustomerID != value) - { - Store = null; - } - _customerID = value; - } - } - } - - private int _customerID; - - public virtual int ContactID - { - get { return _contactID; } - set - { - if (_contactID != value) - { - if (Contact != null - && Contact.ContactID != value) - { - Contact = null; - } - _contactID = value; - } - } - } - - private int _contactID; - - public virtual int ContactTypeID - { - get { return _contactTypeID; } - set - { - if (_contactTypeID != value) - { - if (ContactType != null - && ContactType.ContactTypeID != value) - { - ContactType = null; - } - _contactTypeID = value; - } - } - } - - private int _contactTypeID; - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Contact Contact - { - get { return _contact; } - set - { - if (!ReferenceEquals(_contact, value)) - { - var previousValue = _contact; - _contact = value; - FixupContact(previousValue); - } - } - } - - private Contact _contact; - - public virtual ContactType ContactType - { - get { return _contactType; } - set - { - if (!ReferenceEquals(_contactType, value)) - { - var previousValue = _contactType; - _contactType = value; - FixupContactType(previousValue); - } - } - } - - private ContactType _contactType; - - public virtual Store Store - { - get { return _store; } - set - { - if (!ReferenceEquals(_store, value)) - { - var previousValue = _store; - _store = value; - FixupStore(previousValue); - } - } - } - - private Store _store; - - private void FixupContact(Contact previousValue) - { - if (previousValue != null - && previousValue.StoreContacts.Contains(this)) - { - previousValue.StoreContacts.Remove(this); - } - - if (Contact != null) - { - if (!Contact.StoreContacts.Contains(this)) - { - Contact.StoreContacts.Add(this); - } - if (ContactID != Contact.ContactID) - { - ContactID = Contact.ContactID; - } - } - } - - private void FixupContactType(ContactType previousValue) - { - if (previousValue != null - && previousValue.StoreContacts.Contains(this)) - { - previousValue.StoreContacts.Remove(this); - } - - if (ContactType != null) - { - if (!ContactType.StoreContacts.Contains(this)) - { - ContactType.StoreContacts.Add(this); - } - if (ContactTypeID != ContactType.ContactTypeID) - { - ContactTypeID = ContactType.ContactTypeID; - } - } - } - - private void FixupStore(Store previousValue) - { - if (previousValue != null - && previousValue.StoreContacts.Contains(this)) - { - previousValue.StoreContacts.Remove(this); - } - - if (Store != null) - { - if (!Store.StoreContacts.Contains(this)) - { - Store.StoreContacts.Add(this); - } - if (CustomerID != Store.CustomerID) - { - CustomerID = Store.CustomerID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class StoreContact + { + public virtual int CustomerID + { + get { return _customerID; } + set + { + if (_customerID != value) + { + if (Store != null + && Store.CustomerID != value) + { + Store = null; + } + _customerID = value; + } + } + } + + private int _customerID; + + public virtual int ContactID + { + get { return _contactID; } + set + { + if (_contactID != value) + { + if (Contact != null + && Contact.ContactID != value) + { + Contact = null; + } + _contactID = value; + } + } + } + + private int _contactID; + + public virtual int ContactTypeID + { + get { return _contactTypeID; } + set + { + if (_contactTypeID != value) + { + if (ContactType != null + && ContactType.ContactTypeID != value) + { + ContactType = null; + } + _contactTypeID = value; + } + } + } + + private int _contactTypeID; + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Contact Contact + { + get { return _contact; } + set + { + if (!ReferenceEquals(_contact, value)) + { + var previousValue = _contact; + _contact = value; + FixupContact(previousValue); + } + } + } + + private Contact _contact; + + public virtual ContactType ContactType + { + get { return _contactType; } + set + { + if (!ReferenceEquals(_contactType, value)) + { + var previousValue = _contactType; + _contactType = value; + FixupContactType(previousValue); + } + } + } + + private ContactType _contactType; + + public virtual Store Store + { + get { return _store; } + set + { + if (!ReferenceEquals(_store, value)) + { + var previousValue = _store; + _store = value; + FixupStore(previousValue); + } + } + } + + private Store _store; + + private void FixupContact(Contact previousValue) + { + if (previousValue != null + && previousValue.StoreContacts.Contains(this)) + { + previousValue.StoreContacts.Remove(this); + } + + if (Contact != null) + { + if (!Contact.StoreContacts.Contains(this)) + { + Contact.StoreContacts.Add(this); + } + if (ContactID != Contact.ContactID) + { + ContactID = Contact.ContactID; + } + } + } + + private void FixupContactType(ContactType previousValue) + { + if (previousValue != null + && previousValue.StoreContacts.Contains(this)) + { + previousValue.StoreContacts.Remove(this); + } + + if (ContactType != null) + { + if (!ContactType.StoreContacts.Contains(this)) + { + ContactType.StoreContacts.Add(this); + } + if (ContactTypeID != ContactType.ContactTypeID) + { + ContactTypeID = ContactType.ContactTypeID; + } + } + } + + private void FixupStore(Store previousValue) + { + if (previousValue != null + && previousValue.StoreContacts.Contains(this)) + { + previousValue.StoreContacts.Remove(this); + } + + if (Store != null) + { + if (!Store.StoreContacts.Contains(this)) + { + Store.StoreContacts.Add(this); + } + if (CustomerID != Store.CustomerID) + { + CustomerID = Store.CustomerID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/StyledProduct.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/StyledProduct.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/StyledProduct.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/StyledProduct.cs index b4a2cf34..a1fd1d4a 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/StyledProduct.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/StyledProduct.cs @@ -1,12 +1,12 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System.ComponentModel.DataAnnotations; - - public class StyledProduct : Product - { - [StringLength(150)] - public virtual string Style { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System.ComponentModel.DataAnnotations; + + public class StyledProduct : Product + { + [StringLength(150)] + public virtual string Style { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/TransactionHistory.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/TransactionHistory.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/TransactionHistory.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/TransactionHistory.cs index 74b57ae5..151be06d 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/TransactionHistory.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/TransactionHistory.cs @@ -1,22 +1,22 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class TransactionHistory - { - internal virtual int TransactionID { get; set; } - - public virtual int ProductID { get; set; } - public virtual int ReferenceOrderID { get; set; } - public virtual int ReferenceOrderLineID { get; set; } - public virtual DateTime TransactionDate { get; set; } - public virtual int Quantity { get; set; } - public virtual decimal ActualCost { get; set; } - - internal virtual string TransactionType { get; set; } - internal RowDetails RowDetails { get; set; } - internal virtual Product Product { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class TransactionHistory + { + internal virtual int TransactionID { get; set; } + + public virtual int ProductID { get; set; } + public virtual int ReferenceOrderID { get; set; } + public virtual int ReferenceOrderLineID { get; set; } + public virtual DateTime TransactionDate { get; set; } + public virtual int Quantity { get; set; } + public virtual decimal ActualCost { get; set; } + + internal virtual string TransactionType { get; set; } + internal RowDetails RowDetails { get; set; } + internal virtual Product Product { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/TransactionHistoryArchive.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/TransactionHistoryArchive.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/TransactionHistoryArchive.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/TransactionHistoryArchive.cs index 6ffffa48..3e01a867 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/TransactionHistoryArchive.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/TransactionHistoryArchive.cs @@ -1,22 +1,22 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.ComponentModel.DataAnnotations; - - public class TransactionHistoryArchive - { - [Key] - public virtual int TransactionID { get; set; } - - public virtual int ProductID { get; set; } - public virtual int ReferenceOrderID { get; set; } - public virtual int ReferenceOrderLineID { get; set; } - public virtual DateTime TransactionDate { get; set; } - public virtual string TransactionType { get; set; } - public virtual int Quantity { get; set; } - public virtual decimal ActualCost { get; set; } - public virtual DateTime ModifiedDate { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.ComponentModel.DataAnnotations; + + public class TransactionHistoryArchive + { + [Key] + public virtual int TransactionID { get; set; } + + public virtual int ProductID { get; set; } + public virtual int ReferenceOrderID { get; set; } + public virtual int ReferenceOrderLineID { get; set; } + public virtual DateTime TransactionDate { get; set; } + public virtual string TransactionType { get; set; } + public virtual int Quantity { get; set; } + public virtual decimal ActualCost { get; set; } + public virtual DateTime ModifiedDate { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/UnitMeasure.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/UnitMeasure.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/UnitMeasure.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/UnitMeasure.cs index 27e68543..d60ce72b 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/UnitMeasure.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/UnitMeasure.cs @@ -1,14 +1,14 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System.ComponentModel.DataAnnotations; - - public class UnitMeasure - { - public virtual string UnitMeasureCode { get; set; } - - [MaxLength(42)] - public virtual string Name { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System.ComponentModel.DataAnnotations; + + public class UnitMeasure + { + public virtual string UnitMeasureCode { get; set; } + + [MaxLength(42)] + public virtual string Name { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/User.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/User.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/User.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/User.cs index c58fb8fe..02a88d33 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/User.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/User.cs @@ -1,22 +1,22 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.ComponentModel.DataAnnotations.Schema; - - public class User - { - public virtual int UserID { get; set; } - - [InverseProperty("Following")] - public virtual ICollection Followers { get; set; } - - public virtual ICollection Following { get; set; } - - public virtual Guid rowguid { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations.Schema; + + public class User + { + public virtual int UserID { get; set; } + + [InverseProperty("Following")] + public virtual ICollection Followers { get; set; } + + public virtual ICollection Following { get; set; } + + public virtual Guid rowguid { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Vendor.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Vendor.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/Vendor.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Vendor.cs index f5135c52..09b35f64 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/Vendor.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/Vendor.cs @@ -1,247 +1,247 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class Vendor - { - public virtual int VendorID { get; set; } - - public virtual string AccountNumber { get; set; } - - public virtual string Name { get; set; } - - public virtual byte CreditRating { get; set; } - - public virtual bool PreferredVendorStatus { get; set; } - - public virtual bool ActiveFlag { get; set; } - - public virtual string PurchasingWebServiceURL { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual ICollection ProductVendors - { - get - { - if (_productVendors == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupProductVendors; - _productVendors = newCollection; - } - return _productVendors; - } - set - { - if (!ReferenceEquals(_productVendors, value)) - { - var previousValue = _productVendors as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupProductVendors; - } - _productVendors = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupProductVendors; - } - } - } - } - - private ICollection _productVendors; - - public virtual ICollection PurchaseOrderHeaders - { - get - { - if (_purchaseOrderHeaders == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupPurchaseOrderHeaders; - _purchaseOrderHeaders = newCollection; - } - return _purchaseOrderHeaders; - } - set - { - if (!ReferenceEquals(_purchaseOrderHeaders, value)) - { - var previousValue = _purchaseOrderHeaders as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupPurchaseOrderHeaders; - } - _purchaseOrderHeaders = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupPurchaseOrderHeaders; - } - } - } - } - - private ICollection _purchaseOrderHeaders; - - public virtual ICollection VendorAddresses - { - get - { - if (_vendorAddresses == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupVendorAddresses; - _vendorAddresses = newCollection; - } - return _vendorAddresses; - } - set - { - if (!ReferenceEquals(_vendorAddresses, value)) - { - var previousValue = _vendorAddresses as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupVendorAddresses; - } - _vendorAddresses = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupVendorAddresses; - } - } - } - } - - private ICollection _vendorAddresses; - - public virtual ICollection VendorContacts - { - get - { - if (_vendorContacts == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupVendorContacts; - _vendorContacts = newCollection; - } - return _vendorContacts; - } - set - { - if (!ReferenceEquals(_vendorContacts, value)) - { - var previousValue = _vendorContacts as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupVendorContacts; - } - _vendorContacts = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupVendorContacts; - } - } - } - } - - private ICollection _vendorContacts; - - private void FixupProductVendors(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (ProductVendor item in e.NewItems) - { - item.Vendor = this; - } - } - - if (e.OldItems != null) - { - foreach (ProductVendor item in e.OldItems) - { - if (ReferenceEquals(item.Vendor, this)) - { - item.Vendor = null; - } - } - } - } - - private void FixupPurchaseOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (PurchaseOrderHeader item in e.NewItems) - { - item.Vendor = this; - } - } - - if (e.OldItems != null) - { - foreach (PurchaseOrderHeader item in e.OldItems) - { - if (ReferenceEquals(item.Vendor, this)) - { - item.Vendor = null; - } - } - } - } - - private void FixupVendorAddresses(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (VendorAddress item in e.NewItems) - { - item.Vendor = this; - } - } - - if (e.OldItems != null) - { - foreach (VendorAddress item in e.OldItems) - { - if (ReferenceEquals(item.Vendor, this)) - { - item.Vendor = null; - } - } - } - } - - private void FixupVendorContacts(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (VendorContact item in e.NewItems) - { - item.Vendor = this; - } - } - - if (e.OldItems != null) - { - foreach (VendorContact item in e.OldItems) - { - if (ReferenceEquals(item.Vendor, this)) - { - item.Vendor = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class Vendor + { + public virtual int VendorID { get; set; } + + public virtual string AccountNumber { get; set; } + + public virtual string Name { get; set; } + + public virtual byte CreditRating { get; set; } + + public virtual bool PreferredVendorStatus { get; set; } + + public virtual bool ActiveFlag { get; set; } + + public virtual string PurchasingWebServiceURL { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual ICollection ProductVendors + { + get + { + if (_productVendors == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupProductVendors; + _productVendors = newCollection; + } + return _productVendors; + } + set + { + if (!ReferenceEquals(_productVendors, value)) + { + var previousValue = _productVendors as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupProductVendors; + } + _productVendors = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupProductVendors; + } + } + } + } + + private ICollection _productVendors; + + public virtual ICollection PurchaseOrderHeaders + { + get + { + if (_purchaseOrderHeaders == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupPurchaseOrderHeaders; + _purchaseOrderHeaders = newCollection; + } + return _purchaseOrderHeaders; + } + set + { + if (!ReferenceEquals(_purchaseOrderHeaders, value)) + { + var previousValue = _purchaseOrderHeaders as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupPurchaseOrderHeaders; + } + _purchaseOrderHeaders = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupPurchaseOrderHeaders; + } + } + } + } + + private ICollection _purchaseOrderHeaders; + + public virtual ICollection VendorAddresses + { + get + { + if (_vendorAddresses == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupVendorAddresses; + _vendorAddresses = newCollection; + } + return _vendorAddresses; + } + set + { + if (!ReferenceEquals(_vendorAddresses, value)) + { + var previousValue = _vendorAddresses as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupVendorAddresses; + } + _vendorAddresses = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupVendorAddresses; + } + } + } + } + + private ICollection _vendorAddresses; + + public virtual ICollection VendorContacts + { + get + { + if (_vendorContacts == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupVendorContacts; + _vendorContacts = newCollection; + } + return _vendorContacts; + } + set + { + if (!ReferenceEquals(_vendorContacts, value)) + { + var previousValue = _vendorContacts as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupVendorContacts; + } + _vendorContacts = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupVendorContacts; + } + } + } + } + + private ICollection _vendorContacts; + + private void FixupProductVendors(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (ProductVendor item in e.NewItems) + { + item.Vendor = this; + } + } + + if (e.OldItems != null) + { + foreach (ProductVendor item in e.OldItems) + { + if (ReferenceEquals(item.Vendor, this)) + { + item.Vendor = null; + } + } + } + } + + private void FixupPurchaseOrderHeaders(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (PurchaseOrderHeader item in e.NewItems) + { + item.Vendor = this; + } + } + + if (e.OldItems != null) + { + foreach (PurchaseOrderHeader item in e.OldItems) + { + if (ReferenceEquals(item.Vendor, this)) + { + item.Vendor = null; + } + } + } + } + + private void FixupVendorAddresses(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (VendorAddress item in e.NewItems) + { + item.Vendor = this; + } + } + + if (e.OldItems != null) + { + foreach (VendorAddress item in e.OldItems) + { + if (ReferenceEquals(item.Vendor, this)) + { + item.Vendor = null; + } + } + } + } + + private void FixupVendorContacts(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (VendorContact item in e.NewItems) + { + item.Vendor = this; + } + } + + if (e.OldItems != null) + { + foreach (VendorContact item in e.OldItems) + { + if (ReferenceEquals(item.Vendor, this)) + { + item.Vendor = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/VendorAddress.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/VendorAddress.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/VendorAddress.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/VendorAddress.cs index a31bcaa8..58ec9b6f 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/VendorAddress.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/VendorAddress.cs @@ -1,179 +1,179 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class VendorAddress - { - public virtual int VendorID - { - get { return _vendorID; } - set - { - if (_vendorID != value) - { - if (Vendor != null - && Vendor.VendorID != value) - { - Vendor = null; - } - _vendorID = value; - } - } - } - - private int _vendorID; - - public virtual int AddressID - { - get { return _addressID; } - set - { - if (_addressID != value) - { - if (Address != null - && Address.AddressID != value) - { - Address = null; - } - _addressID = value; - } - } - } - - private int _addressID; - - public virtual int AddressTypeID - { - get { return _addressTypeID; } - set - { - if (_addressTypeID != value) - { - if (AddressType != null - && AddressType.AddressTypeID != value) - { - AddressType = null; - } - _addressTypeID = value; - } - } - } - - private int _addressTypeID; - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Address Address - { - get { return _address; } - set - { - if (!ReferenceEquals(_address, value)) - { - var previousValue = _address; - _address = value; - FixupAddress(previousValue); - } - } - } - - private Address _address; - - public virtual AddressType AddressType - { - get { return _addressType; } - set - { - if (!ReferenceEquals(_addressType, value)) - { - var previousValue = _addressType; - _addressType = value; - FixupAddressType(previousValue); - } - } - } - - private AddressType _addressType; - - public virtual Vendor Vendor - { - get { return _vendor; } - set - { - if (!ReferenceEquals(_vendor, value)) - { - var previousValue = _vendor; - _vendor = value; - FixupVendor(previousValue); - } - } - } - - private Vendor _vendor; - - private void FixupAddress(Address previousValue) - { - if (previousValue != null - && previousValue.VendorAddresses.Contains(this)) - { - previousValue.VendorAddresses.Remove(this); - } - - if (Address != null) - { - if (!Address.VendorAddresses.Contains(this)) - { - Address.VendorAddresses.Add(this); - } - if (AddressID != Address.AddressID) - { - AddressID = Address.AddressID; - } - } - } - - private void FixupAddressType(AddressType previousValue) - { - if (previousValue != null - && previousValue.VendorAddresses.Contains(this)) - { - previousValue.VendorAddresses.Remove(this); - } - - if (AddressType != null) - { - if (!AddressType.VendorAddresses.Contains(this)) - { - AddressType.VendorAddresses.Add(this); - } - if (AddressTypeID != AddressType.AddressTypeID) - { - AddressTypeID = AddressType.AddressTypeID; - } - } - } - - private void FixupVendor(Vendor previousValue) - { - if (previousValue != null - && previousValue.VendorAddresses.Contains(this)) - { - previousValue.VendorAddresses.Remove(this); - } - - if (Vendor != null) - { - if (!Vendor.VendorAddresses.Contains(this)) - { - Vendor.VendorAddresses.Add(this); - } - if (VendorID != Vendor.VendorID) - { - VendorID = Vendor.VendorID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class VendorAddress + { + public virtual int VendorID + { + get { return _vendorID; } + set + { + if (_vendorID != value) + { + if (Vendor != null + && Vendor.VendorID != value) + { + Vendor = null; + } + _vendorID = value; + } + } + } + + private int _vendorID; + + public virtual int AddressID + { + get { return _addressID; } + set + { + if (_addressID != value) + { + if (Address != null + && Address.AddressID != value) + { + Address = null; + } + _addressID = value; + } + } + } + + private int _addressID; + + public virtual int AddressTypeID + { + get { return _addressTypeID; } + set + { + if (_addressTypeID != value) + { + if (AddressType != null + && AddressType.AddressTypeID != value) + { + AddressType = null; + } + _addressTypeID = value; + } + } + } + + private int _addressTypeID; + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Address Address + { + get { return _address; } + set + { + if (!ReferenceEquals(_address, value)) + { + var previousValue = _address; + _address = value; + FixupAddress(previousValue); + } + } + } + + private Address _address; + + public virtual AddressType AddressType + { + get { return _addressType; } + set + { + if (!ReferenceEquals(_addressType, value)) + { + var previousValue = _addressType; + _addressType = value; + FixupAddressType(previousValue); + } + } + } + + private AddressType _addressType; + + public virtual Vendor Vendor + { + get { return _vendor; } + set + { + if (!ReferenceEquals(_vendor, value)) + { + var previousValue = _vendor; + _vendor = value; + FixupVendor(previousValue); + } + } + } + + private Vendor _vendor; + + private void FixupAddress(Address previousValue) + { + if (previousValue != null + && previousValue.VendorAddresses.Contains(this)) + { + previousValue.VendorAddresses.Remove(this); + } + + if (Address != null) + { + if (!Address.VendorAddresses.Contains(this)) + { + Address.VendorAddresses.Add(this); + } + if (AddressID != Address.AddressID) + { + AddressID = Address.AddressID; + } + } + } + + private void FixupAddressType(AddressType previousValue) + { + if (previousValue != null + && previousValue.VendorAddresses.Contains(this)) + { + previousValue.VendorAddresses.Remove(this); + } + + if (AddressType != null) + { + if (!AddressType.VendorAddresses.Contains(this)) + { + AddressType.VendorAddresses.Add(this); + } + if (AddressTypeID != AddressType.AddressTypeID) + { + AddressTypeID = AddressType.AddressTypeID; + } + } + } + + private void FixupVendor(Vendor previousValue) + { + if (previousValue != null + && previousValue.VendorAddresses.Contains(this)) + { + previousValue.VendorAddresses.Remove(this); + } + + if (Vendor != null) + { + if (!Vendor.VendorAddresses.Contains(this)) + { + Vendor.VendorAddresses.Add(this); + } + if (VendorID != Vendor.VendorID) + { + VendorID = Vendor.VendorID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/VendorContact.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/VendorContact.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/VendorContact.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/VendorContact.cs index 535b25a1..4ad60995 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/VendorContact.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/VendorContact.cs @@ -1,179 +1,179 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class VendorContact - { - public virtual int VendorID - { - get { return _vendorID; } - set - { - if (_vendorID != value) - { - if (Vendor != null - && Vendor.VendorID != value) - { - Vendor = null; - } - _vendorID = value; - } - } - } - - private int _vendorID; - - public virtual int ContactID - { - get { return _contactID; } - set - { - if (_contactID != value) - { - if (Contact != null - && Contact.ContactID != value) - { - Contact = null; - } - _contactID = value; - } - } - } - - private int _contactID; - - public virtual int ContactTypeID - { - get { return _contactTypeID; } - set - { - if (_contactTypeID != value) - { - if (ContactType != null - && ContactType.ContactTypeID != value) - { - ContactType = null; - } - _contactTypeID = value; - } - } - } - - private int _contactTypeID; - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Contact Contact - { - get { return _contact; } - set - { - if (!ReferenceEquals(_contact, value)) - { - var previousValue = _contact; - _contact = value; - FixupContact(previousValue); - } - } - } - - private Contact _contact; - - public virtual ContactType ContactType - { - get { return _contactType; } - set - { - if (!ReferenceEquals(_contactType, value)) - { - var previousValue = _contactType; - _contactType = value; - FixupContactType(previousValue); - } - } - } - - private ContactType _contactType; - - public virtual Vendor Vendor - { - get { return _vendor; } - set - { - if (!ReferenceEquals(_vendor, value)) - { - var previousValue = _vendor; - _vendor = value; - FixupVendor(previousValue); - } - } - } - - private Vendor _vendor; - - private void FixupContact(Contact previousValue) - { - if (previousValue != null - && previousValue.VendorContacts.Contains(this)) - { - previousValue.VendorContacts.Remove(this); - } - - if (Contact != null) - { - if (!Contact.VendorContacts.Contains(this)) - { - Contact.VendorContacts.Add(this); - } - if (ContactID != Contact.ContactID) - { - ContactID = Contact.ContactID; - } - } - } - - private void FixupContactType(ContactType previousValue) - { - if (previousValue != null - && previousValue.VendorContacts.Contains(this)) - { - previousValue.VendorContacts.Remove(this); - } - - if (ContactType != null) - { - if (!ContactType.VendorContacts.Contains(this)) - { - ContactType.VendorContacts.Add(this); - } - if (ContactTypeID != ContactType.ContactTypeID) - { - ContactTypeID = ContactType.ContactTypeID; - } - } - } - - private void FixupVendor(Vendor previousValue) - { - if (previousValue != null - && previousValue.VendorContacts.Contains(this)) - { - previousValue.VendorContacts.Remove(this); - } - - if (Vendor != null) - { - if (!Vendor.VendorContacts.Contains(this)) - { - Vendor.VendorContacts.Add(this); - } - if (VendorID != Vendor.VendorID) - { - VendorID = Vendor.VendorID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class VendorContact + { + public virtual int VendorID + { + get { return _vendorID; } + set + { + if (_vendorID != value) + { + if (Vendor != null + && Vendor.VendorID != value) + { + Vendor = null; + } + _vendorID = value; + } + } + } + + private int _vendorID; + + public virtual int ContactID + { + get { return _contactID; } + set + { + if (_contactID != value) + { + if (Contact != null + && Contact.ContactID != value) + { + Contact = null; + } + _contactID = value; + } + } + } + + private int _contactID; + + public virtual int ContactTypeID + { + get { return _contactTypeID; } + set + { + if (_contactTypeID != value) + { + if (ContactType != null + && ContactType.ContactTypeID != value) + { + ContactType = null; + } + _contactTypeID = value; + } + } + } + + private int _contactTypeID; + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Contact Contact + { + get { return _contact; } + set + { + if (!ReferenceEquals(_contact, value)) + { + var previousValue = _contact; + _contact = value; + FixupContact(previousValue); + } + } + } + + private Contact _contact; + + public virtual ContactType ContactType + { + get { return _contactType; } + set + { + if (!ReferenceEquals(_contactType, value)) + { + var previousValue = _contactType; + _contactType = value; + FixupContactType(previousValue); + } + } + } + + private ContactType _contactType; + + public virtual Vendor Vendor + { + get { return _vendor; } + set + { + if (!ReferenceEquals(_vendor, value)) + { + var previousValue = _vendor; + _vendor = value; + FixupVendor(previousValue); + } + } + } + + private Vendor _vendor; + + private void FixupContact(Contact previousValue) + { + if (previousValue != null + && previousValue.VendorContacts.Contains(this)) + { + previousValue.VendorContacts.Remove(this); + } + + if (Contact != null) + { + if (!Contact.VendorContacts.Contains(this)) + { + Contact.VendorContacts.Add(this); + } + if (ContactID != Contact.ContactID) + { + ContactID = Contact.ContactID; + } + } + } + + private void FixupContactType(ContactType previousValue) + { + if (previousValue != null + && previousValue.VendorContacts.Contains(this)) + { + previousValue.VendorContacts.Remove(this); + } + + if (ContactType != null) + { + if (!ContactType.VendorContacts.Contains(this)) + { + ContactType.VendorContacts.Add(this); + } + if (ContactTypeID != ContactType.ContactTypeID) + { + ContactTypeID = ContactType.ContactTypeID; + } + } + } + + private void FixupVendor(Vendor previousValue) + { + if (previousValue != null + && previousValue.VendorContacts.Contains(this)) + { + previousValue.VendorContacts.Remove(this); + } + + if (Vendor != null) + { + if (!Vendor.VendorContacts.Contains(this)) + { + Vendor.VendorContacts.Add(this); + } + if (VendorID != Vendor.VendorID) + { + VendorID = Vendor.VendorID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/WorkOrder.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/WorkOrder.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/WorkOrder.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/WorkOrder.cs index e8ab95e4..1395e609 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/WorkOrder.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/WorkOrder.cs @@ -1,216 +1,216 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - using System.Collections.Generic; - using System.Collections.Specialized; - - public class WorkOrder - { - public virtual int WorkOrderID { get; set; } - - public virtual int ProductID - { - get { return _productID; } - set - { - try - { - _settingFK = true; - if (_productID != value) - { - if (Product != null - && Product.ProductID != value) - { - Product = null; - } - _productID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private int _productID; - - public virtual int OrderQty { get; set; } - - public virtual int StockedQty { get; set; } - - public virtual short ScrappedQty { get; set; } - - public virtual DateTime StartDate { get; set; } - - public virtual DateTime? EndDate { get; set; } - - public virtual DateTime DueDate { get; set; } - - public virtual short? ScrapReasonID - { - get { return _scrapReasonID; } - set - { - try - { - _settingFK = true; - if (_scrapReasonID != value) - { - if (ScrapReason != null - && ScrapReason.ScrapReasonID != value) - { - ScrapReason = null; - } - _scrapReasonID = value; - } - } - finally - { - _settingFK = false; - } - } - } - - private short? _scrapReasonID; - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Product Product - { - get { return _product; } - set - { - if (!ReferenceEquals(_product, value)) - { - var previousValue = _product; - _product = value; - FixupProduct(previousValue); - } - } - } - - private Product _product; - - public virtual ScrapReason ScrapReason - { - get { return _scrapReason; } - set - { - if (!ReferenceEquals(_scrapReason, value)) - { - var previousValue = _scrapReason; - _scrapReason = value; - FixupScrapReason(previousValue); - } - } - } - - private ScrapReason _scrapReason; - - public virtual ICollection WorkOrderRoutings - { - get - { - if (_workOrderRoutings == null) - { - var newCollection = new FixupCollection(); - newCollection.CollectionChanged += FixupWorkOrderRoutings; - _workOrderRoutings = newCollection; - } - return _workOrderRoutings; - } - set - { - if (!ReferenceEquals(_workOrderRoutings, value)) - { - var previousValue = _workOrderRoutings as FixupCollection; - if (previousValue != null) - { - previousValue.CollectionChanged -= FixupWorkOrderRoutings; - } - _workOrderRoutings = value; - var newValue = value as FixupCollection; - if (newValue != null) - { - newValue.CollectionChanged += FixupWorkOrderRoutings; - } - } - } - } - - private ICollection _workOrderRoutings; - - private bool _settingFK; - - private void FixupProduct(Product previousValue) - { - if (previousValue != null - && previousValue.WorkOrders.Contains(this)) - { - previousValue.WorkOrders.Remove(this); - } - - if (Product != null) - { - if (!Product.WorkOrders.Contains(this)) - { - Product.WorkOrders.Add(this); - } - if (ProductID != Product.ProductID) - { - ProductID = Product.ProductID; - } - } - } - - private void FixupScrapReason(ScrapReason previousValue) - { - if (previousValue != null - && previousValue.WorkOrders.Contains(this)) - { - previousValue.WorkOrders.Remove(this); - } - - if (ScrapReason != null) - { - if (!ScrapReason.WorkOrders.Contains(this)) - { - ScrapReason.WorkOrders.Add(this); - } - if (ScrapReasonID != ScrapReason.ScrapReasonID) - { - ScrapReasonID = ScrapReason.ScrapReasonID; - } - } - else if (!_settingFK) - { - ScrapReasonID = null; - } - } - - private void FixupWorkOrderRoutings(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.NewItems != null) - { - foreach (WorkOrderRouting item in e.NewItems) - { - item.WorkOrder = this; - } - } - - if (e.OldItems != null) - { - foreach (WorkOrderRouting item in e.OldItems) - { - if (ReferenceEquals(item.WorkOrder, this)) - { - item.WorkOrder = null; - } - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + + public class WorkOrder + { + public virtual int WorkOrderID { get; set; } + + public virtual int ProductID + { + get { return _productID; } + set + { + try + { + _settingFK = true; + if (_productID != value) + { + if (Product != null + && Product.ProductID != value) + { + Product = null; + } + _productID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private int _productID; + + public virtual int OrderQty { get; set; } + + public virtual int StockedQty { get; set; } + + public virtual short ScrappedQty { get; set; } + + public virtual DateTime StartDate { get; set; } + + public virtual DateTime? EndDate { get; set; } + + public virtual DateTime DueDate { get; set; } + + public virtual short? ScrapReasonID + { + get { return _scrapReasonID; } + set + { + try + { + _settingFK = true; + if (_scrapReasonID != value) + { + if (ScrapReason != null + && ScrapReason.ScrapReasonID != value) + { + ScrapReason = null; + } + _scrapReasonID = value; + } + } + finally + { + _settingFK = false; + } + } + } + + private short? _scrapReasonID; + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Product Product + { + get { return _product; } + set + { + if (!ReferenceEquals(_product, value)) + { + var previousValue = _product; + _product = value; + FixupProduct(previousValue); + } + } + } + + private Product _product; + + public virtual ScrapReason ScrapReason + { + get { return _scrapReason; } + set + { + if (!ReferenceEquals(_scrapReason, value)) + { + var previousValue = _scrapReason; + _scrapReason = value; + FixupScrapReason(previousValue); + } + } + } + + private ScrapReason _scrapReason; + + public virtual ICollection WorkOrderRoutings + { + get + { + if (_workOrderRoutings == null) + { + var newCollection = new FixupCollection(); + newCollection.CollectionChanged += FixupWorkOrderRoutings; + _workOrderRoutings = newCollection; + } + return _workOrderRoutings; + } + set + { + if (!ReferenceEquals(_workOrderRoutings, value)) + { + var previousValue = _workOrderRoutings as FixupCollection; + if (previousValue != null) + { + previousValue.CollectionChanged -= FixupWorkOrderRoutings; + } + _workOrderRoutings = value; + var newValue = value as FixupCollection; + if (newValue != null) + { + newValue.CollectionChanged += FixupWorkOrderRoutings; + } + } + } + } + + private ICollection _workOrderRoutings; + + private bool _settingFK; + + private void FixupProduct(Product previousValue) + { + if (previousValue != null + && previousValue.WorkOrders.Contains(this)) + { + previousValue.WorkOrders.Remove(this); + } + + if (Product != null) + { + if (!Product.WorkOrders.Contains(this)) + { + Product.WorkOrders.Add(this); + } + if (ProductID != Product.ProductID) + { + ProductID = Product.ProductID; + } + } + } + + private void FixupScrapReason(ScrapReason previousValue) + { + if (previousValue != null + && previousValue.WorkOrders.Contains(this)) + { + previousValue.WorkOrders.Remove(this); + } + + if (ScrapReason != null) + { + if (!ScrapReason.WorkOrders.Contains(this)) + { + ScrapReason.WorkOrders.Add(this); + } + if (ScrapReasonID != ScrapReason.ScrapReasonID) + { + ScrapReasonID = ScrapReason.ScrapReasonID; + } + } + else if (!_settingFK) + { + ScrapReasonID = null; + } + } + + private void FixupWorkOrderRoutings(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.NewItems != null) + { + foreach (WorkOrderRouting item in e.NewItems) + { + item.WorkOrder = this; + } + } + + if (e.OldItems != null) + { + foreach (WorkOrderRouting item in e.OldItems) + { + if (ReferenceEquals(item.WorkOrder, this)) + { + item.WorkOrder = null; + } + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/WorkOrderRouting.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/WorkOrderRouting.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/StoreModel/WorkOrderRouting.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/WorkOrderRouting.cs index e6222c76..ef62229d 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/StoreModel/WorkOrderRouting.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/StoreModel/WorkOrderRouting.cs @@ -1,141 +1,141 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.Model -{ - using System; - - public class WorkOrderRouting - { - public virtual int WorkOrderID - { - get { return _workOrderID; } - set - { - if (_workOrderID != value) - { - if (WorkOrder != null - && WorkOrder.WorkOrderID != value) - { - WorkOrder = null; - } - _workOrderID = value; - } - } - } - - private int _workOrderID; - - public virtual int ProductID { get; set; } - - public virtual short OperationSequence { get; set; } - - public virtual short LocationID - { - get { return _locationID; } - set - { - if (_locationID != value) - { - if (Location != null - && Location.LocationID != value) - { - Location = null; - } - _locationID = value; - } - } - } - - private short _locationID; - - public virtual DateTime ScheduledStartDate { get; set; } - - public virtual DateTime ScheduledEndDate { get; set; } - - public virtual DateTime? ActualStartDate { get; set; } - - public virtual DateTime? ActualEndDate { get; set; } - - public virtual decimal? ActualResourceHrs { get; set; } - - public virtual decimal PlannedCost { get; set; } - - public virtual decimal? ActualCost { get; set; } - - public virtual DateTime ModifiedDate { get; set; } - - public virtual Location Location - { - get { return _location; } - set - { - if (!ReferenceEquals(_location, value)) - { - var previousValue = _location; - _location = value; - FixupLocation(previousValue); - } - } - } - - private Location _location; - - public virtual WorkOrder WorkOrder - { - get { return _workOrder; } - set - { - if (!ReferenceEquals(_workOrder, value)) - { - var previousValue = _workOrder; - _workOrder = value; - FixupWorkOrder(previousValue); - } - } - } - - private WorkOrder _workOrder; - - private void FixupLocation(Location previousValue) - { - if (previousValue != null - && previousValue.WorkOrderRoutings.Contains(this)) - { - previousValue.WorkOrderRoutings.Remove(this); - } - - if (Location != null) - { - if (!Location.WorkOrderRoutings.Contains(this)) - { - Location.WorkOrderRoutings.Add(this); - } - if (LocationID != Location.LocationID) - { - LocationID = Location.LocationID.Value; - } - } - } - - private void FixupWorkOrder(WorkOrder previousValue) - { - if (previousValue != null - && previousValue.WorkOrderRoutings.Contains(this)) - { - previousValue.WorkOrderRoutings.Remove(this); - } - - if (WorkOrder != null) - { - if (!WorkOrder.WorkOrderRoutings.Contains(this)) - { - WorkOrder.WorkOrderRoutings.Add(this); - } - if (WorkOrderID != WorkOrder.WorkOrderID) - { - WorkOrderID = WorkOrder.WorkOrderID; - } - } - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.Model +{ + using System; + + public class WorkOrderRouting + { + public virtual int WorkOrderID + { + get { return _workOrderID; } + set + { + if (_workOrderID != value) + { + if (WorkOrder != null + && WorkOrder.WorkOrderID != value) + { + WorkOrder = null; + } + _workOrderID = value; + } + } + } + + private int _workOrderID; + + public virtual int ProductID { get; set; } + + public virtual short OperationSequence { get; set; } + + public virtual short LocationID + { + get { return _locationID; } + set + { + if (_locationID != value) + { + if (Location != null + && Location.LocationID != value) + { + Location = null; + } + _locationID = value; + } + } + } + + private short _locationID; + + public virtual DateTime ScheduledStartDate { get; set; } + + public virtual DateTime ScheduledEndDate { get; set; } + + public virtual DateTime? ActualStartDate { get; set; } + + public virtual DateTime? ActualEndDate { get; set; } + + public virtual decimal? ActualResourceHrs { get; set; } + + public virtual decimal PlannedCost { get; set; } + + public virtual decimal? ActualCost { get; set; } + + public virtual DateTime ModifiedDate { get; set; } + + public virtual Location Location + { + get { return _location; } + set + { + if (!ReferenceEquals(_location, value)) + { + var previousValue = _location; + _location = value; + FixupLocation(previousValue); + } + } + } + + private Location _location; + + public virtual WorkOrder WorkOrder + { + get { return _workOrder; } + set + { + if (!ReferenceEquals(_workOrder, value)) + { + var previousValue = _workOrder; + _workOrder = value; + FixupWorkOrder(previousValue); + } + } + } + + private WorkOrder _workOrder; + + private void FixupLocation(Location previousValue) + { + if (previousValue != null + && previousValue.WorkOrderRoutings.Contains(this)) + { + previousValue.WorkOrderRoutings.Remove(this); + } + + if (Location != null) + { + if (!Location.WorkOrderRoutings.Contains(this)) + { + Location.WorkOrderRoutings.Add(this); + } + if (LocationID != Location.LocationID) + { + LocationID = Location.LocationID.Value; + } + } + } + + private void FixupWorkOrder(WorkOrder previousValue) + { + if (previousValue != null + && previousValue.WorkOrderRoutings.Contains(this)) + { + previousValue.WorkOrderRoutings.Remove(this); + } + + if (WorkOrder != null) + { + if (!WorkOrder.WorkOrderRoutings.Contains(this)) + { + WorkOrder.WorkOrderRoutings.Add(this); + } + if (WorkOrderID != WorkOrder.WorkOrderID) + { + WorkOrderID = WorkOrder.WorkOrderID; + } + } + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/AddressMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/AddressMf.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/AddressMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/AddressMf.cs index 2301bf96..e4367952 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/AddressMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/AddressMf.cs @@ -1,28 +1,28 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - using System; - - public partial class AddressMf - { - public AddressMf() - { - this.SiteInfo = new SiteInfoMf(); - } - - public string Street { get; set; } - public string City { private get; set; } - internal string State { get; set; } - internal string ZipCode { get; private set; } - - internal SiteInfoMf SiteInfo { get; private set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + using System; + + public partial class AddressMf + { + public AddressMf() + { + this.SiteInfo = new SiteInfoMf(); + } + + public string Street { get; set; } + public string City { private get; set; } + internal string State { get; set; } + internal string ZipCode { get; private set; } + + internal SiteInfoMf SiteInfo { get; private set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/BuildingDetailMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/BuildingDetailMf.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/BuildingDetailMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/BuildingDetailMf.cs index 27af0878..1e77dcca 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/BuildingDetailMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/BuildingDetailMf.cs @@ -1,22 +1,22 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - using System; - using System.Collections.Generic; - - public partial class BuildingDetailMf - { - public System.Guid BuildingId { get; set; } - public string Details { get; set; } - - public virtual BuildingMf Building { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + using System; + using System.Collections.Generic; + + public partial class BuildingDetailMf + { + public System.Guid BuildingId { get; set; } + public string Details { get; set; } + + public virtual BuildingMf Building { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/BuildingMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/BuildingMf.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/BuildingMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/BuildingMf.cs index 79710abe..e9a015ae 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/BuildingMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/BuildingMf.cs @@ -1,33 +1,33 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - using System; - using System.Collections.Generic; - - public partial class BuildingMf - { - public BuildingMf() - { - this.Offices = new HashSet(); - this.MailRooms = new HashSet(); - this.Address = new AddressMf(); - } - - public System.Guid BuildingId { get; set; } - public string Name { get; set; } - internal decimal Value { get; set; } - - internal AddressMf Address { get; private set; } - - public virtual ICollection Offices { get; set; } - internal virtual ICollection MailRooms { get; private set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + using System; + using System.Collections.Generic; + + public partial class BuildingMf + { + public BuildingMf() + { + this.Offices = new HashSet(); + this.MailRooms = new HashSet(); + this.Address = new AddressMf(); + } + + public System.Guid BuildingId { get; set; } + public string Name { get; set; } + internal decimal Value { get; set; } + + internal AddressMf Address { get; private set; } + + public virtual ICollection Offices { get; set; } + internal virtual ICollection MailRooms { get; private set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.Context.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.Context.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.Context.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.Context.cs index 43e2b9fe..bbbe7a28 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.Context.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.Context.cs @@ -1,99 +1,99 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - using System; - using System.Data.Entity; - using System.Data.Entity.Infrastructure; - using System.Data.Entity.Core.Objects; - using System.Data.Entity.Core.Objects.DataClasses; - using System.Linq; - - internal partial class AdvancedPatternsModelFirstContext : DbContext - { - public AdvancedPatternsModelFirstContext() - : base("name=AdvancedPatternsModelFirstContext") - { - this.Configuration.LazyLoadingEnabled = false; - } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - throw new UnintentionalCodeFirstException(); - } - - public DbSet Employees { get; set; } - public DbSet Offices { get; set; } - public DbSet Buildings { get; set; } - internal DbSet MailRooms { get; set; } - public DbSet Whiteboards { get; set; } - public DbSet BuildingDetails { get; set; } - public DbSet WorkOrders { get; set; } - - public virtual ObjectResult AllOfficesStoredProc() - { - return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("AllOfficesStoredProc"); - } - - public virtual ObjectResult AllOfficesStoredProc(MergeOption mergeOption) - { - return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("AllOfficesStoredProc", mergeOption); - } - - public virtual ObjectResult> EmployeeIdsInOfficeStoredProc(string officeNumber, Nullable buildingId) - { - var officeNumberParameter = officeNumber != null ? - new ObjectParameter("OfficeNumber", officeNumber) : - new ObjectParameter("OfficeNumber", typeof(string)); - - var buildingIdParameter = buildingId.HasValue ? - new ObjectParameter("BuildingId", buildingId) : - new ObjectParameter("BuildingId", typeof(System.Guid)); - - return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction>("EmployeeIdsInOfficeStoredProc", officeNumberParameter, buildingIdParameter); - } - - public virtual ObjectResult OfficesInBuildingStoredProc(Nullable buildingId) - { - var buildingIdParameter = buildingId.HasValue ? - new ObjectParameter("BuildingId", buildingId) : - new ObjectParameter("BuildingId", typeof(System.Guid)); - - return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("OfficesInBuildingStoredProc", buildingIdParameter); - } - - public virtual ObjectResult OfficesInBuildingStoredProc(Nullable buildingId, MergeOption mergeOption) - { - var buildingIdParameter = buildingId.HasValue ? - new ObjectParameter("BuildingId", buildingId) : - new ObjectParameter("BuildingId", typeof(System.Guid)); - - return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("OfficesInBuildingStoredProc", mergeOption, buildingIdParameter); - } - - public virtual int SkimOffLeaveBalanceStoredProc(string first, string last) - { - var firstParameter = first != null ? - new ObjectParameter("First", first) : - new ObjectParameter("First", typeof(string)); - - var lastParameter = last != null ? - new ObjectParameter("Last", last) : - new ObjectParameter("Last", typeof(string)); - - return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("SkimOffLeaveBalanceStoredProc", firstParameter, lastParameter); - } - - public virtual ObjectResult AllSiteInfoStoredProc() - { - return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("AllSiteInfoStoredProc"); - } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + using System; + using System.Data.Entity; + using System.Data.Entity.Infrastructure; + using System.Data.Entity.Core.Objects; + using System.Data.Entity.Core.Objects.DataClasses; + using System.Linq; + + internal partial class AdvancedPatternsModelFirstContext : DbContext + { + public AdvancedPatternsModelFirstContext() + : base("name=AdvancedPatternsModelFirstContext") + { + this.Configuration.LazyLoadingEnabled = false; + } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + throw new UnintentionalCodeFirstException(); + } + + public DbSet Employees { get; set; } + public DbSet Offices { get; set; } + public DbSet Buildings { get; set; } + internal DbSet MailRooms { get; set; } + public DbSet Whiteboards { get; set; } + public DbSet BuildingDetails { get; set; } + public DbSet WorkOrders { get; set; } + + public virtual ObjectResult AllOfficesStoredProc() + { + return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("AllOfficesStoredProc"); + } + + public virtual ObjectResult AllOfficesStoredProc(MergeOption mergeOption) + { + return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("AllOfficesStoredProc", mergeOption); + } + + public virtual ObjectResult> EmployeeIdsInOfficeStoredProc(string officeNumber, Nullable buildingId) + { + var officeNumberParameter = officeNumber != null ? + new ObjectParameter("OfficeNumber", officeNumber) : + new ObjectParameter("OfficeNumber", typeof(string)); + + var buildingIdParameter = buildingId.HasValue ? + new ObjectParameter("BuildingId", buildingId) : + new ObjectParameter("BuildingId", typeof(System.Guid)); + + return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction>("EmployeeIdsInOfficeStoredProc", officeNumberParameter, buildingIdParameter); + } + + public virtual ObjectResult OfficesInBuildingStoredProc(Nullable buildingId) + { + var buildingIdParameter = buildingId.HasValue ? + new ObjectParameter("BuildingId", buildingId) : + new ObjectParameter("BuildingId", typeof(System.Guid)); + + return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("OfficesInBuildingStoredProc", buildingIdParameter); + } + + public virtual ObjectResult OfficesInBuildingStoredProc(Nullable buildingId, MergeOption mergeOption) + { + var buildingIdParameter = buildingId.HasValue ? + new ObjectParameter("BuildingId", buildingId) : + new ObjectParameter("BuildingId", typeof(System.Guid)); + + return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("OfficesInBuildingStoredProc", mergeOption, buildingIdParameter); + } + + public virtual int SkimOffLeaveBalanceStoredProc(string first, string last) + { + var firstParameter = first != null ? + new ObjectParameter("First", first) : + new ObjectParameter("First", typeof(string)); + + var lastParameter = last != null ? + new ObjectParameter("Last", last) : + new ObjectParameter("Last", typeof(string)); + + return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("SkimOffLeaveBalanceStoredProc", firstParameter, lastParameter); + } + + public virtual ObjectResult AllSiteInfoStoredProc() + { + return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("AllSiteInfoStoredProc"); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.Context.tt b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.Context.tt similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.Context.tt rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.Context.tt index 4ab69314..1b1bfcc7 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.Context.tt +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.Context.tt @@ -1,735 +1,735 @@ -<#@ template language="C#" debug="false" hostspecific="true"#> -<#@ include file="EF.Utility.CS.ttinclude"#><#@ - output extension=".cs"#><# - -const string inputFile = @"..\Schemas\AdvancedPatterns.edmx"; -var textTransform = DynamicTextTransformation.Create(this); -var code = new CodeGenerationTools(this); -var ef = new MetadataTools(this); -var typeMapper = new TypeMapper(code, ef, textTransform.Errors); -var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors); -var itemCollection = loader.CreateEdmItemCollection(inputFile); -var modelNamespace = loader.GetModelNamespace(inputFile); -var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); - -var container = itemCollection.OfType().FirstOrDefault(); -if (container == null) -{ - return string.Empty; -} -#> -//------------------------------------------------------------------------------ -// -// <#=GetResourceString("Template_GeneratedCodeCommentLine1")#> -// -// <#=GetResourceString("Template_GeneratedCodeCommentLine2")#> -// <#=GetResourceString("Template_GeneratedCodeCommentLine3")#> -// -//------------------------------------------------------------------------------ - -<# - -var codeNamespace = code.VsNamespaceSuggestion(); -if (!String.IsNullOrEmpty(codeNamespace)) -{ -#> -namespace <#=code.EscapeNamespace(codeNamespace)#> -{ -<# - PushIndent(" "); -} - -#> -using System; -using System.Data.Entity; -using System.Data.Entity.Infrastructure; -<# -if (container.FunctionImports.Any()) -{ -#> -using System.Data.Entity.Core.Objects; -using System.Data.Entity.Core.Objects.DataClasses; -using System.Linq; -<# -} -#> - -<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext -{ - public <#=code.Escape(container)#>() - : base("name=<#=container.Name#>") - { -<# -if (!loader.IsLazyLoadingEnabled(container)) -{ -#> - this.Configuration.LazyLoadingEnabled = false; -<# -} -#> - } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - throw new UnintentionalCodeFirstException(); - } - -<# - foreach (var entitySet in container.BaseEntitySets.OfType()) - { -#> - <#=codeStringGenerator.DbSet(entitySet)#> -<# - } - - foreach (var edmFunction in container.FunctionImports) - { - WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false); - } -#> -} -<# - -if (!String.IsNullOrEmpty(codeNamespace)) -{ - PopIndent(); -#> -} -<# -} -#> -<#+ - -private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) -{ - if (typeMapper.IsComposable(edmFunction)) - { -#> - - [EdmFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")] - <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#> - { -<#+ - codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter); -#> - <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#> - } -<#+ - } - else - { -#> - - <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#> - { -<#+ - codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter); -#> - <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#> - } -<#+ - if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption)) - { - WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true); - } - } -} - -public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit) -{ -#> - var <#=name#> = <#=isNotNull#> ? - <#=notNullInit#> : - <#=nullInit#>; - -<#+ -} - -public const string TemplateId = "CSharp_DbContext_Context_EF5"; - -public class CodeStringGenerator -{ - private readonly CodeGenerationTools _code; - private readonly TypeMapper _typeMapper; - private readonly MetadataTools _ef; - - public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef) - { - ArgumentNotNull(code, "code"); - ArgumentNotNull(typeMapper, "typeMapper"); - ArgumentNotNull(ef, "ef"); - - _code = code; - _typeMapper = typeMapper; - _ef = ef; - } - - public string Property(EdmProperty edmProperty) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1} {2} {{ {3}get; {4}set; }}", - Accessibility.ForProperty(edmProperty), - _typeMapper.GetTypeName(edmProperty.TypeUsage), - _code.Escape(edmProperty), - _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), - _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); - } - - public string NavigationProperty(NavigationProperty navigationProperty) - { - var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType()); - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1} {2} {{ {3}get; {4}set; }}", - AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)), - navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, - _code.Escape(navigationProperty), - _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)), - _code.SpaceAfter(Accessibility.ForSetter(navigationProperty))); - } - - public string AccessibilityAndVirtual(string accessibility) - { - return accessibility + (accessibility != "private" ? " virtual" : ""); - } - - public string EntityClassOpening(EntityType entity) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1}partial class {2}{3}", - Accessibility.ForType(entity), - _code.SpaceAfter(_code.AbstractOption(entity)), - _code.Escape(entity), - _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType))); - } - - public string EnumOpening(SimpleType enumType) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} enum {1} : {2}", - Accessibility.ForType(enumType), - _code.Escape(enumType), - _code.Escape(_typeMapper.UnderlyingClrType(enumType))); - } - - public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter) - { - var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); - foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) - { - var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; - var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")"; - var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + parameter.RawClrTypeName + "))"; - writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit); - } - } - - public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace) - { - var parameters = _typeMapper.GetParameters(edmFunction); - - return string.Format( - CultureInfo.InvariantCulture, - "{0} IQueryable<{1}> {2}{3}", - AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), - _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), - _code.Escape(edmFunction), - string.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray())); - } - - public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace) - { - var parameters = _typeMapper.GetParameters(edmFunction); - - return string.Format( - CultureInfo.InvariantCulture, - "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});", - _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), - edmFunction.NamespaceName, - edmFunction.Name, - string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()), - _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))); - } - - public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) - { - var parameters = _typeMapper.GetParameters(edmFunction); - var returnType = _typeMapper.GetReturnType(edmFunction); - - var paramList = String.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray()); - if (includeMergeOption) - { - paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption"; - } - - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1} {2}({3})", - AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), - returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", - _code.Escape(edmFunction), - paramList); - } - - public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) - { - var parameters = _typeMapper.GetParameters(edmFunction); - var returnType = _typeMapper.GetReturnType(edmFunction); - - var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())); - if (includeMergeOption) - { - callParams = ", mergeOption" + callParams; - } - - return string.Format( - CultureInfo.InvariantCulture, - "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});", - returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", - edmFunction.Name, - callParams); - } - - public string DbSet(EntitySet entitySet) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} DbSet<{1}> {2} {{ get; set; }}", - Accessibility.ForReadOnlyProperty(entitySet), - _typeMapper.GetTypeName(entitySet.ElementType), - _code.Escape(entitySet)); - } - - public string UsingDirectives(bool inHeader, bool includeCollections = true) - { - return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion()) - ? string.Format( - CultureInfo.InvariantCulture, - "{0}using System;{1}" + - "{2}", - inHeader ? Environment.NewLine : "", - includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "", - inHeader ? "" : Environment.NewLine) - : ""; - } -} - -public class TypeMapper -{ - private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; - - private readonly System.Collections.IList _errors; - private readonly CodeGenerationTools _code; - private readonly MetadataTools _ef; - - public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors) - { - ArgumentNotNull(code, "code"); - ArgumentNotNull(ef, "ef"); - ArgumentNotNull(errors, "errors"); - - _code = code; - _ef = ef; - _errors = errors; - } - - public string GetTypeName(TypeUsage typeUsage) - { - return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); - } - - public string GetTypeName(EdmType edmType) - { - return GetTypeName(edmType, isNullable: null, modelNamespace: null); - } - - public string GetTypeName(TypeUsage typeUsage, string modelNamespace) - { - return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); - } - - public string GetTypeName(EdmType edmType, string modelNamespace) - { - return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); - } - - public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) - { - if (edmType == null) - { - return null; - } - - var collectionType = edmType as CollectionType; - if (collectionType != null) - { - return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); - } - - var typeName = _code.Escape(edmType.MetadataProperties - .Where(p => p.Name == ExternalTypeNameAttributeName) - .Select(p => (string)p.Value) - .FirstOrDefault()) - ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ? - _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) : - _code.Escape(edmType)); - - if (edmType is StructuralType) - { - return typeName; - } - - if (edmType is SimpleType) - { - var clrType = UnderlyingClrType(edmType); - if (!IsEnumType(edmType)) - { - typeName = _code.Escape(clrType); - } - - return clrType.IsValueType && isNullable == true ? - String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : - typeName; - } - - throw new ArgumentException("edmType"); - } - - public Type UnderlyingClrType(EdmType edmType) - { - ArgumentNotNull(edmType, "edmType"); - - var primitiveType = edmType as PrimitiveType; - if (primitiveType != null) - { - return primitiveType.ClrEquivalentType; - } - - if (IsEnumType(edmType)) - { - return GetEnumUnderlyingType(edmType).ClrEquivalentType; - } - - return typeof(object); - } - - public object GetEnumMemberValue(MetadataItem enumMember) - { - ArgumentNotNull(enumMember, "enumMember"); - - var valueProperty = enumMember.GetType().GetProperty("Value"); - return valueProperty == null ? null : valueProperty.GetValue(enumMember, null); - } - - public string GetEnumMemberName(MetadataItem enumMember) - { - ArgumentNotNull(enumMember, "enumMember"); - - var nameProperty = enumMember.GetType().GetProperty("Name"); - return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null); - } - - public System.Collections.IEnumerable GetEnumMembers(EdmType enumType) - { - ArgumentNotNull(enumType, "enumType"); - - var membersProperty = enumType.GetType().GetProperty("Members"); - return membersProperty != null - ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null) - : Enumerable.Empty(); - } - - public bool EnumIsFlags(EdmType enumType) - { - ArgumentNotNull(enumType, "enumType"); - - var isFlagsProperty = enumType.GetType().GetProperty("IsFlags"); - return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null); - } - - public bool IsEnumType(GlobalItem edmType) - { - ArgumentNotNull(edmType, "edmType"); - - return edmType.GetType().Name == "EnumType"; - } - - public PrimitiveType GetEnumUnderlyingType(EdmType enumType) - { - ArgumentNotNull(enumType, "enumType"); - - return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null); - } - - public string CreateLiteral(object value) - { - if (value == null || value.GetType() != typeof(TimeSpan)) - { - return _code.CreateLiteral(value); - } - - return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks); - } - - public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) - { - ArgumentNotNull(types, "types"); - ArgumentNotNull(sourceFile, "sourceFile"); - - var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); - if (types.Any(item => !hash.Add(item))) - { - _errors.Add( - new CompilerError(sourceFile, -1, -1, "6023", - String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CaseInsensitiveTypeConflict")))); - return false; - } - return true; - } - - public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection) - { - return GetItemsToGenerate(itemCollection) - .Where(e => IsEnumType(e)); - } - - public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType - { - return itemCollection - .OfType() - .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) - .OrderBy(i => i.Name); - } - - public IEnumerable GetAllGlobalItems(IEnumerable itemCollection) - { - return itemCollection - .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i)) - .Select(g => GetGlobalItemName(g)); - } - - public string GetGlobalItemName(GlobalItem item) - { - if (item is EdmType) - { - return ((EdmType)item).Name; - } - else - { - return ((EntityContainer)item).Name; - } - } - - public IEnumerable GetSimpleProperties(EntityType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); - } - - public IEnumerable GetSimpleProperties(ComplexType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); - } - - public IEnumerable GetComplexProperties(EntityType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); - } - - public IEnumerable GetComplexProperties(ComplexType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); - } - - public IEnumerable GetPropertiesWithDefaultValues(EntityType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); - } - - public IEnumerable GetPropertiesWithDefaultValues(ComplexType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); - } - - public IEnumerable GetNavigationProperties(EntityType type) - { - return type.NavigationProperties.Where(np => np.DeclaringType == type); - } - - public IEnumerable GetCollectionNavigationProperties(EntityType type) - { - return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many); - } - - public FunctionParameter GetReturnParameter(EdmFunction edmFunction) - { - ArgumentNotNull(edmFunction, "edmFunction"); - - var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters"); - return returnParamsProperty == null - ? edmFunction.ReturnParameter - : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault(); - } - - public bool IsComposable(EdmFunction edmFunction) - { - ArgumentNotNull(edmFunction, "edmFunction"); - - var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute"); - return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null); - } - - public IEnumerable GetParameters(EdmFunction edmFunction) - { - return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); - } - - public TypeUsage GetReturnType(EdmFunction edmFunction) - { - var returnParam = GetReturnParameter(edmFunction); - return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage); - } - - public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption) - { - var returnType = GetReturnType(edmFunction); - return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType; - } -} - -public class EdmMetadataLoader -{ - private readonly IDynamicHost _host; - private readonly System.Collections.IList _errors; - - public EdmMetadataLoader(IDynamicHost host, System.Collections.IList errors) - { - ArgumentNotNull(host, "host"); - ArgumentNotNull(errors, "errors"); - - _host = host; - _errors = errors; - } - - public IEnumerable CreateEdmItemCollection(string sourcePath) - { - ArgumentNotNull(sourcePath, "sourcePath"); - - if (!ValidateInputPath(sourcePath)) - { - return new EdmItemCollection(); - } - - var schemaElement = LoadRootElement(_host.ResolvePath(sourcePath)); - if (schemaElement != null) - { - using (var reader = schemaElement.CreateReader()) - { - IList errors; - var itemCollection = MetadataItemCollectionFactory.CreateEdmItemCollection(new[] { reader }, out errors); - - ProcessErrors(errors, sourcePath); - - return itemCollection; - } - } - return new EdmItemCollection(); - } - - public string GetModelNamespace(string sourcePath) - { - ArgumentNotNull(sourcePath, "sourcePath"); - - if (!ValidateInputPath(sourcePath)) - { - return string.Empty; - } - - var model = LoadRootElement(_host.ResolvePath(sourcePath)); - if (model == null) - { - return string.Empty; - } - - var attribute = model.Attribute("Namespace"); - return attribute != null ? attribute.Value : ""; - } - - private bool ValidateInputPath(string sourcePath) - { - if (sourcePath == "$" + "edmxInputFile" + "$") - { - _errors.Add( - new CompilerError(_host.TemplateFile ?? sourcePath, 0, 0, string.Empty, - GetResourceString("Template_ReplaceVsItemTemplateToken"))); - return false; - } - - return true; - } - - public XElement LoadRootElement(string sourcePath) - { - ArgumentNotNull(sourcePath, "sourcePath"); - - var root = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); - return root.Elements() - .Where(e => e.Name.LocalName == "Runtime") - .Elements() - .Where(e => e.Name.LocalName == "ConceptualModels") - .Elements() - .Where(e => e.Name.LocalName == "Schema") - .FirstOrDefault() - ?? root; - } - - private void ProcessErrors(IEnumerable errors, string sourceFilePath) - { - foreach (var error in errors) - { - _errors.Add( - new CompilerError( - error.SchemaLocation ?? sourceFilePath, - error.Line, - error.Column, - error.ErrorCode.ToString(CultureInfo.InvariantCulture), - error.Message) - { - IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning - }); - } - } - - public bool IsLazyLoadingEnabled(EntityContainer container) - { - string lazyLoadingAttributeValue; - var lazyLoadingAttributeName = MetadataConstants.EDM_ANNOTATION_09_02 + ":LazyLoadingEnabled"; - bool isLazyLoading; - return !MetadataTools.TryGetStringMetadataPropertySetting(container, lazyLoadingAttributeName, out lazyLoadingAttributeValue) - || !bool.TryParse(lazyLoadingAttributeValue, out isLazyLoading) - || isLazyLoading; - } -} - -public static void ArgumentNotNull(T arg, string name) where T : class -{ - if (arg == null) - { - throw new ArgumentNullException(name); - } -} - -private static readonly Lazy ResourceManager = - new Lazy( - () => new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(MetadataItemCollectionFactory).Assembly), isThreadSafe: true); - -public static string GetResourceString(string resourceName) -{ - ArgumentNotNull(resourceName, "resourceName"); - - return ResourceManager.Value.GetString(resourceName, null); -} - +<#@ template language="C#" debug="false" hostspecific="true"#> +<#@ include file="EF.Utility.CS.ttinclude"#><#@ + output extension=".cs"#><# + +const string inputFile = @"..\Schemas\AdvancedPatterns.edmx"; +var textTransform = DynamicTextTransformation.Create(this); +var code = new CodeGenerationTools(this); +var ef = new MetadataTools(this); +var typeMapper = new TypeMapper(code, ef, textTransform.Errors); +var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors); +var itemCollection = loader.CreateEdmItemCollection(inputFile); +var modelNamespace = loader.GetModelNamespace(inputFile); +var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); + +var container = itemCollection.OfType().FirstOrDefault(); +if (container == null) +{ + return string.Empty; +} +#> +//------------------------------------------------------------------------------ +// +// <#=GetResourceString("Template_GeneratedCodeCommentLine1")#> +// +// <#=GetResourceString("Template_GeneratedCodeCommentLine2")#> +// <#=GetResourceString("Template_GeneratedCodeCommentLine3")#> +// +//------------------------------------------------------------------------------ + +<# + +var codeNamespace = code.VsNamespaceSuggestion(); +if (!String.IsNullOrEmpty(codeNamespace)) +{ +#> +namespace <#=code.EscapeNamespace(codeNamespace)#> +{ +<# + PushIndent(" "); +} + +#> +using System; +using System.Data.Entity; +using System.Data.Entity.Infrastructure; +<# +if (container.FunctionImports.Any()) +{ +#> +using System.Data.Entity.Core.Objects; +using System.Data.Entity.Core.Objects.DataClasses; +using System.Linq; +<# +} +#> + +<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext +{ + public <#=code.Escape(container)#>() + : base("name=<#=container.Name#>") + { +<# +if (!loader.IsLazyLoadingEnabled(container)) +{ +#> + this.Configuration.LazyLoadingEnabled = false; +<# +} +#> + } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + throw new UnintentionalCodeFirstException(); + } + +<# + foreach (var entitySet in container.BaseEntitySets.OfType()) + { +#> + <#=codeStringGenerator.DbSet(entitySet)#> +<# + } + + foreach (var edmFunction in container.FunctionImports) + { + WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false); + } +#> +} +<# + +if (!String.IsNullOrEmpty(codeNamespace)) +{ + PopIndent(); +#> +} +<# +} +#> +<#+ + +private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) +{ + if (typeMapper.IsComposable(edmFunction)) + { +#> + + [EdmFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")] + <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#> + { +<#+ + codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter); +#> + <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#> + } +<#+ + } + else + { +#> + + <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#> + { +<#+ + codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter); +#> + <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#> + } +<#+ + if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption)) + { + WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true); + } + } +} + +public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit) +{ +#> + var <#=name#> = <#=isNotNull#> ? + <#=notNullInit#> : + <#=nullInit#>; + +<#+ +} + +public const string TemplateId = "CSharp_DbContext_Context_EF5"; + +public class CodeStringGenerator +{ + private readonly CodeGenerationTools _code; + private readonly TypeMapper _typeMapper; + private readonly MetadataTools _ef; + + public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef) + { + ArgumentNotNull(code, "code"); + ArgumentNotNull(typeMapper, "typeMapper"); + ArgumentNotNull(ef, "ef"); + + _code = code; + _typeMapper = typeMapper; + _ef = ef; + } + + public string Property(EdmProperty edmProperty) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2} {{ {3}get; {4}set; }}", + Accessibility.ForProperty(edmProperty), + _typeMapper.GetTypeName(edmProperty.TypeUsage), + _code.Escape(edmProperty), + _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), + _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); + } + + public string NavigationProperty(NavigationProperty navigationProperty) + { + var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType()); + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2} {{ {3}get; {4}set; }}", + AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)), + navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, + _code.Escape(navigationProperty), + _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)), + _code.SpaceAfter(Accessibility.ForSetter(navigationProperty))); + } + + public string AccessibilityAndVirtual(string accessibility) + { + return accessibility + (accessibility != "private" ? " virtual" : ""); + } + + public string EntityClassOpening(EntityType entity) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1}partial class {2}{3}", + Accessibility.ForType(entity), + _code.SpaceAfter(_code.AbstractOption(entity)), + _code.Escape(entity), + _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType))); + } + + public string EnumOpening(SimpleType enumType) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} enum {1} : {2}", + Accessibility.ForType(enumType), + _code.Escape(enumType), + _code.Escape(_typeMapper.UnderlyingClrType(enumType))); + } + + public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter) + { + var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); + foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) + { + var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; + var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")"; + var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + parameter.RawClrTypeName + "))"; + writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit); + } + } + + public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace) + { + var parameters = _typeMapper.GetParameters(edmFunction); + + return string.Format( + CultureInfo.InvariantCulture, + "{0} IQueryable<{1}> {2}{3}", + AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), + _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), + _code.Escape(edmFunction), + string.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray())); + } + + public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace) + { + var parameters = _typeMapper.GetParameters(edmFunction); + + return string.Format( + CultureInfo.InvariantCulture, + "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});", + _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), + edmFunction.NamespaceName, + edmFunction.Name, + string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()), + _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))); + } + + public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) + { + var parameters = _typeMapper.GetParameters(edmFunction); + var returnType = _typeMapper.GetReturnType(edmFunction); + + var paramList = String.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray()); + if (includeMergeOption) + { + paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption"; + } + + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2}({3})", + AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), + returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", + _code.Escape(edmFunction), + paramList); + } + + public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) + { + var parameters = _typeMapper.GetParameters(edmFunction); + var returnType = _typeMapper.GetReturnType(edmFunction); + + var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())); + if (includeMergeOption) + { + callParams = ", mergeOption" + callParams; + } + + return string.Format( + CultureInfo.InvariantCulture, + "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});", + returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", + edmFunction.Name, + callParams); + } + + public string DbSet(EntitySet entitySet) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} DbSet<{1}> {2} {{ get; set; }}", + Accessibility.ForReadOnlyProperty(entitySet), + _typeMapper.GetTypeName(entitySet.ElementType), + _code.Escape(entitySet)); + } + + public string UsingDirectives(bool inHeader, bool includeCollections = true) + { + return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion()) + ? string.Format( + CultureInfo.InvariantCulture, + "{0}using System;{1}" + + "{2}", + inHeader ? Environment.NewLine : "", + includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "", + inHeader ? "" : Environment.NewLine) + : ""; + } +} + +public class TypeMapper +{ + private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; + + private readonly System.Collections.IList _errors; + private readonly CodeGenerationTools _code; + private readonly MetadataTools _ef; + + public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors) + { + ArgumentNotNull(code, "code"); + ArgumentNotNull(ef, "ef"); + ArgumentNotNull(errors, "errors"); + + _code = code; + _ef = ef; + _errors = errors; + } + + public string GetTypeName(TypeUsage typeUsage) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); + } + + public string GetTypeName(EdmType edmType) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: null); + } + + public string GetTypeName(TypeUsage typeUsage, string modelNamespace) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); + } + + public string GetTypeName(EdmType edmType, string modelNamespace) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); + } + + public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) + { + if (edmType == null) + { + return null; + } + + var collectionType = edmType as CollectionType; + if (collectionType != null) + { + return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); + } + + var typeName = _code.Escape(edmType.MetadataProperties + .Where(p => p.Name == ExternalTypeNameAttributeName) + .Select(p => (string)p.Value) + .FirstOrDefault()) + ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ? + _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) : + _code.Escape(edmType)); + + if (edmType is StructuralType) + { + return typeName; + } + + if (edmType is SimpleType) + { + var clrType = UnderlyingClrType(edmType); + if (!IsEnumType(edmType)) + { + typeName = _code.Escape(clrType); + } + + return clrType.IsValueType && isNullable == true ? + String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : + typeName; + } + + throw new ArgumentException("edmType"); + } + + public Type UnderlyingClrType(EdmType edmType) + { + ArgumentNotNull(edmType, "edmType"); + + var primitiveType = edmType as PrimitiveType; + if (primitiveType != null) + { + return primitiveType.ClrEquivalentType; + } + + if (IsEnumType(edmType)) + { + return GetEnumUnderlyingType(edmType).ClrEquivalentType; + } + + return typeof(object); + } + + public object GetEnumMemberValue(MetadataItem enumMember) + { + ArgumentNotNull(enumMember, "enumMember"); + + var valueProperty = enumMember.GetType().GetProperty("Value"); + return valueProperty == null ? null : valueProperty.GetValue(enumMember, null); + } + + public string GetEnumMemberName(MetadataItem enumMember) + { + ArgumentNotNull(enumMember, "enumMember"); + + var nameProperty = enumMember.GetType().GetProperty("Name"); + return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null); + } + + public System.Collections.IEnumerable GetEnumMembers(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + var membersProperty = enumType.GetType().GetProperty("Members"); + return membersProperty != null + ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null) + : Enumerable.Empty(); + } + + public bool EnumIsFlags(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + var isFlagsProperty = enumType.GetType().GetProperty("IsFlags"); + return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null); + } + + public bool IsEnumType(GlobalItem edmType) + { + ArgumentNotNull(edmType, "edmType"); + + return edmType.GetType().Name == "EnumType"; + } + + public PrimitiveType GetEnumUnderlyingType(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null); + } + + public string CreateLiteral(object value) + { + if (value == null || value.GetType() != typeof(TimeSpan)) + { + return _code.CreateLiteral(value); + } + + return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks); + } + + public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) + { + ArgumentNotNull(types, "types"); + ArgumentNotNull(sourceFile, "sourceFile"); + + var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); + if (types.Any(item => !hash.Add(item))) + { + _errors.Add( + new CompilerError(sourceFile, -1, -1, "6023", + String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CaseInsensitiveTypeConflict")))); + return false; + } + return true; + } + + public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection) + { + return GetItemsToGenerate(itemCollection) + .Where(e => IsEnumType(e)); + } + + public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType + { + return itemCollection + .OfType() + .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) + .OrderBy(i => i.Name); + } + + public IEnumerable GetAllGlobalItems(IEnumerable itemCollection) + { + return itemCollection + .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i)) + .Select(g => GetGlobalItemName(g)); + } + + public string GetGlobalItemName(GlobalItem item) + { + if (item is EdmType) + { + return ((EdmType)item).Name; + } + else + { + return ((EntityContainer)item).Name; + } + } + + public IEnumerable GetSimpleProperties(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); + } + + public IEnumerable GetSimpleProperties(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); + } + + public IEnumerable GetComplexProperties(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); + } + + public IEnumerable GetComplexProperties(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); + } + + public IEnumerable GetPropertiesWithDefaultValues(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); + } + + public IEnumerable GetPropertiesWithDefaultValues(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); + } + + public IEnumerable GetNavigationProperties(EntityType type) + { + return type.NavigationProperties.Where(np => np.DeclaringType == type); + } + + public IEnumerable GetCollectionNavigationProperties(EntityType type) + { + return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many); + } + + public FunctionParameter GetReturnParameter(EdmFunction edmFunction) + { + ArgumentNotNull(edmFunction, "edmFunction"); + + var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters"); + return returnParamsProperty == null + ? edmFunction.ReturnParameter + : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault(); + } + + public bool IsComposable(EdmFunction edmFunction) + { + ArgumentNotNull(edmFunction, "edmFunction"); + + var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute"); + return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null); + } + + public IEnumerable GetParameters(EdmFunction edmFunction) + { + return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); + } + + public TypeUsage GetReturnType(EdmFunction edmFunction) + { + var returnParam = GetReturnParameter(edmFunction); + return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage); + } + + public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption) + { + var returnType = GetReturnType(edmFunction); + return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType; + } +} + +public class EdmMetadataLoader +{ + private readonly IDynamicHost _host; + private readonly System.Collections.IList _errors; + + public EdmMetadataLoader(IDynamicHost host, System.Collections.IList errors) + { + ArgumentNotNull(host, "host"); + ArgumentNotNull(errors, "errors"); + + _host = host; + _errors = errors; + } + + public IEnumerable CreateEdmItemCollection(string sourcePath) + { + ArgumentNotNull(sourcePath, "sourcePath"); + + if (!ValidateInputPath(sourcePath)) + { + return new EdmItemCollection(); + } + + var schemaElement = LoadRootElement(_host.ResolvePath(sourcePath)); + if (schemaElement != null) + { + using (var reader = schemaElement.CreateReader()) + { + IList errors; + var itemCollection = MetadataItemCollectionFactory.CreateEdmItemCollection(new[] { reader }, out errors); + + ProcessErrors(errors, sourcePath); + + return itemCollection; + } + } + return new EdmItemCollection(); + } + + public string GetModelNamespace(string sourcePath) + { + ArgumentNotNull(sourcePath, "sourcePath"); + + if (!ValidateInputPath(sourcePath)) + { + return string.Empty; + } + + var model = LoadRootElement(_host.ResolvePath(sourcePath)); + if (model == null) + { + return string.Empty; + } + + var attribute = model.Attribute("Namespace"); + return attribute != null ? attribute.Value : ""; + } + + private bool ValidateInputPath(string sourcePath) + { + if (sourcePath == "$" + "edmxInputFile" + "$") + { + _errors.Add( + new CompilerError(_host.TemplateFile ?? sourcePath, 0, 0, string.Empty, + GetResourceString("Template_ReplaceVsItemTemplateToken"))); + return false; + } + + return true; + } + + public XElement LoadRootElement(string sourcePath) + { + ArgumentNotNull(sourcePath, "sourcePath"); + + var root = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); + return root.Elements() + .Where(e => e.Name.LocalName == "Runtime") + .Elements() + .Where(e => e.Name.LocalName == "ConceptualModels") + .Elements() + .Where(e => e.Name.LocalName == "Schema") + .FirstOrDefault() + ?? root; + } + + private void ProcessErrors(IEnumerable errors, string sourceFilePath) + { + foreach (var error in errors) + { + _errors.Add( + new CompilerError( + error.SchemaLocation ?? sourceFilePath, + error.Line, + error.Column, + error.ErrorCode.ToString(CultureInfo.InvariantCulture), + error.Message) + { + IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning + }); + } + } + + public bool IsLazyLoadingEnabled(EntityContainer container) + { + string lazyLoadingAttributeValue; + var lazyLoadingAttributeName = MetadataConstants.EDM_ANNOTATION_09_02 + ":LazyLoadingEnabled"; + bool isLazyLoading; + return !MetadataTools.TryGetStringMetadataPropertySetting(container, lazyLoadingAttributeName, out lazyLoadingAttributeValue) + || !bool.TryParse(lazyLoadingAttributeValue, out isLazyLoading) + || isLazyLoading; + } +} + +public static void ArgumentNotNull(T arg, string name) where T : class +{ + if (arg == null) + { + throw new ArgumentNullException(name); + } +} + +private static readonly Lazy ResourceManager = + new Lazy( + () => new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(MetadataItemCollectionFactory).Assembly), isThreadSafe: true); + +public static string GetResourceString(string resourceName) +{ + ArgumentNotNull(resourceName, "resourceName"); + + return ResourceManager.Value.GetString(resourceName, null); +} + #> \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.cs index 90e37bda..fb52571e 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.cs @@ -1,9 +1,9 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.tt b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.tt similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.tt rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.tt index e8dee422..449d1fe3 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.tt +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/CsAdvancedPatterns.tt @@ -1,845 +1,845 @@ -<#@ template language="C#" debug="false" hostspecific="true"#> -<#@ include file="EF.Utility.CS.ttinclude"#><#@ - output extension=".cs"#><# - -const string inputFile = @"..\Schemas\AdvancedPatterns.edmx"; -var textTransform = DynamicTextTransformation.Create(this); -var code = new CodeGenerationTools(this); -var ef = new MetadataTools(this); -var typeMapper = new TypeMapper(code, ef, textTransform.Errors); -var fileManager = EntityFrameworkTemplateFileManager.Create(this); -var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile); -var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); - -if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile)) -{ - return string.Empty; -} - -WriteHeader(codeStringGenerator, fileManager); - -foreach (var entity in typeMapper.GetItemsToGenerate(itemCollection)) -{ - fileManager.StartNewFile(entity.Name + ".cs"); - BeginNamespace(code); -#> -<#=codeStringGenerator.UsingDirectives(inHeader: false)#> -<#=codeStringGenerator.EntityClassOpening(entity)#> -{ -<# - var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity); - var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity); - var complexProperties = typeMapper.GetComplexProperties(entity); - - if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any()) - { -#> - public <#=code.Escape(entity)#>() - { -<# - foreach (var edmProperty in propertiesWithDefaultValues) - { -#> - this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>; -<# - } - - foreach (var navigationProperty in collectionNavigationProperties) - { -#> - this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>(); -<# - } - - foreach (var complexProperty in complexProperties) - { -#> - this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>(); -<# - } -#> - } - -<# - } - - var simpleProperties = typeMapper.GetSimpleProperties(entity); - if (simpleProperties.Any()) - { - foreach (var edmProperty in simpleProperties) - { -#> - <#=codeStringGenerator.Property(edmProperty)#> -<# - } - } - - if (complexProperties.Any()) - { -#> - -<# - foreach(var complexProperty in complexProperties) - { -#> - <#=codeStringGenerator.Property(complexProperty)#> -<# - } - } - - var navigationProperties = typeMapper.GetNavigationProperties(entity); - if (navigationProperties.Any()) - { -#> - -<# - foreach (var navigationProperty in navigationProperties) - { -#> - <#=codeStringGenerator.NavigationProperty(navigationProperty)#> -<# - } - } -#> -} -<# - EndNamespace(code); -} - -foreach (var complex in typeMapper.GetItemsToGenerate(itemCollection)) -{ - fileManager.StartNewFile(complex.Name + ".cs"); - BeginNamespace(code); -#> -<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#> -<#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#> -{ -<# - var complexProperties = typeMapper.GetComplexProperties(complex); - var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex); - - if (propertiesWithDefaultValues.Any() || complexProperties.Any()) - { -#> - public <#=code.Escape(complex)#>() - { -<# - foreach (var edmProperty in propertiesWithDefaultValues) - { -#> - this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>; -<# - } - - foreach (var complexProperty in complexProperties) - { -#> - this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>(); -<# - } -#> - } - -<# - } - - var simpleProperties = typeMapper.GetSimpleProperties(complex); - if (simpleProperties.Any()) - { - foreach(var edmProperty in simpleProperties) - { -#> - <#=codeStringGenerator.Property(edmProperty)#> -<# - } - } - - if (complexProperties.Any()) - { -#> - -<# - foreach(var edmProperty in complexProperties) - { -#> - <#=codeStringGenerator.Property(edmProperty)#> -<# - } - } -#> -} -<# - EndNamespace(code); -} - -foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection)) -{ - fileManager.StartNewFile(enumType.Name + ".cs"); - BeginNamespace(code); -#> -<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#> -<# - if (typeMapper.EnumIsFlags(enumType)) - { -#> -[Flags] -<# - } -#> -<#=codeStringGenerator.EnumOpening(enumType)#> -{ -<# - var foundOne = false; - - foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType)) - { - foundOne = true; -#> - <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>, -<# - } - - if (foundOne) - { - this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1); - } -#> -} -<# - EndNamespace(code); -} - -fileManager.Process(); - -#> -<#+ - -public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager) -{ - fileManager.StartHeader(); -#> -//------------------------------------------------------------------------------ -// -// <#=GetResourceString("Template_GeneratedCodeCommentLine1")#> -// -// <#=GetResourceString("Template_GeneratedCodeCommentLine2")#> -// <#=GetResourceString("Template_GeneratedCodeCommentLine3")#> -// -//------------------------------------------------------------------------------ -<#=codeStringGenerator.UsingDirectives(inHeader: true)#> -<#+ - fileManager.EndBlock(); -} - -public void BeginNamespace(CodeGenerationTools code) -{ - var codeNamespace = code.VsNamespaceSuggestion(); - if (!String.IsNullOrEmpty(codeNamespace)) - { -#> -namespace <#=code.EscapeNamespace(codeNamespace)#> -{ -<#+ - PushIndent(" "); - } -} - -public void EndNamespace(CodeGenerationTools code) -{ - if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion())) - { - PopIndent(); -#> -} -<#+ - } -} - -public const string TemplateId = "CSharp_DbContext_Types_EF5"; - -public class CodeStringGenerator -{ - private readonly CodeGenerationTools _code; - private readonly TypeMapper _typeMapper; - private readonly MetadataTools _ef; - - public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef) - { - ArgumentNotNull(code, "code"); - ArgumentNotNull(typeMapper, "typeMapper"); - ArgumentNotNull(ef, "ef"); - - _code = code; - _typeMapper = typeMapper; - _ef = ef; - } - - public string Property(EdmProperty edmProperty) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1} {2} {{ {3}get; {4}set; }}", - Accessibility.ForProperty(edmProperty), - _typeMapper.GetTypeName(edmProperty.TypeUsage), - _code.Escape(edmProperty), - _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), - _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); - } - - public string NavigationProperty(NavigationProperty navigationProperty) - { - var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType()); - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1} {2} {{ {3}get; {4}set; }}", - AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)), - navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, - _code.Escape(navigationProperty), - _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)), - _code.SpaceAfter(Accessibility.ForSetter(navigationProperty))); - } - - public string AccessibilityAndVirtual(string accessibility) - { - return accessibility + (accessibility != "private" ? " virtual" : ""); - } - - public string EntityClassOpening(EntityType entity) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1}partial class {2}{3}", - Accessibility.ForType(entity), - _code.SpaceAfter(_code.AbstractOption(entity)), - _code.Escape(entity), - _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType))); - } - - public string EnumOpening(SimpleType enumType) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} enum {1} : {2}", - Accessibility.ForType(enumType), - _code.Escape(enumType), - _code.Escape(_typeMapper.UnderlyingClrType(enumType))); - } - - public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter) - { - var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); - foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) - { - var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; - var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")"; - var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + parameter.RawClrTypeName + "))"; - writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit); - } - } - - public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace) - { - var parameters = _typeMapper.GetParameters(edmFunction); - - return string.Format( - CultureInfo.InvariantCulture, - "{0} IQueryable<{1}> {2}{3}", - AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), - _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), - _code.Escape(edmFunction), - string.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray())); - } - - public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace) - { - var parameters = _typeMapper.GetParameters(edmFunction); - - return string.Format( - CultureInfo.InvariantCulture, - "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});", - _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), - edmFunction.NamespaceName, - edmFunction.Name, - string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()), - _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))); - } - - public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) - { - var parameters = _typeMapper.GetParameters(edmFunction); - var returnType = _typeMapper.GetReturnType(edmFunction); - - var paramList = String.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray()); - if (includeMergeOption) - { - paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption"; - } - - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1} {2}({3})", - AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), - returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", - _code.Escape(edmFunction), - paramList); - } - - public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) - { - var parameters = _typeMapper.GetParameters(edmFunction); - var returnType = _typeMapper.GetReturnType(edmFunction); - - var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())); - if (includeMergeOption) - { - callParams = ", mergeOption" + callParams; - } - - return string.Format( - CultureInfo.InvariantCulture, - "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});", - returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", - edmFunction.Name, - callParams); - } - - public string DbSet(EntitySet entitySet) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} DbSet<{1}> {2} {{ get; set; }}", - Accessibility.ForReadOnlyProperty(entitySet), - _typeMapper.GetTypeName(entitySet.ElementType), - _code.Escape(entitySet)); - } - - public string UsingDirectives(bool inHeader, bool includeCollections = true) - { - return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion()) - ? string.Format( - CultureInfo.InvariantCulture, - "{0}using System;{1}" + - "{2}", - inHeader ? Environment.NewLine : "", - includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "", - inHeader ? "" : Environment.NewLine) - : ""; - } -} - -public class TypeMapper -{ - private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; - - private readonly System.Collections.IList _errors; - private readonly CodeGenerationTools _code; - private readonly MetadataTools _ef; - - public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors) - { - ArgumentNotNull(code, "code"); - ArgumentNotNull(ef, "ef"); - ArgumentNotNull(errors, "errors"); - - _code = code; - _ef = ef; - _errors = errors; - } - - public string GetTypeName(TypeUsage typeUsage) - { - return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); - } - - public string GetTypeName(EdmType edmType) - { - return GetTypeName(edmType, isNullable: null, modelNamespace: null); - } - - public string GetTypeName(TypeUsage typeUsage, string modelNamespace) - { - return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); - } - - public string GetTypeName(EdmType edmType, string modelNamespace) - { - return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); - } - - public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) - { - if (edmType == null) - { - return null; - } - - var collectionType = edmType as CollectionType; - if (collectionType != null) - { - return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); - } - - var typeName = _code.Escape(edmType.MetadataProperties - .Where(p => p.Name == ExternalTypeNameAttributeName) - .Select(p => (string)p.Value) - .FirstOrDefault()) - ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ? - _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) : - _code.Escape(edmType)); - - if (edmType is StructuralType) - { - return typeName; - } - - if (edmType is SimpleType) - { - var clrType = UnderlyingClrType(edmType); - if (!IsEnumType(edmType)) - { - typeName = _code.Escape(clrType); - } - - return clrType.IsValueType && isNullable == true ? - String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : - typeName; - } - - throw new ArgumentException("edmType"); - } - - public Type UnderlyingClrType(EdmType edmType) - { - ArgumentNotNull(edmType, "edmType"); - - var primitiveType = edmType as PrimitiveType; - if (primitiveType != null) - { - return primitiveType.ClrEquivalentType; - } - - if (IsEnumType(edmType)) - { - return GetEnumUnderlyingType(edmType).ClrEquivalentType; - } - - return typeof(object); - } - - public object GetEnumMemberValue(MetadataItem enumMember) - { - ArgumentNotNull(enumMember, "enumMember"); - - var valueProperty = enumMember.GetType().GetProperty("Value"); - return valueProperty == null ? null : valueProperty.GetValue(enumMember, null); - } - - public string GetEnumMemberName(MetadataItem enumMember) - { - ArgumentNotNull(enumMember, "enumMember"); - - var nameProperty = enumMember.GetType().GetProperty("Name"); - return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null); - } - - public System.Collections.IEnumerable GetEnumMembers(EdmType enumType) - { - ArgumentNotNull(enumType, "enumType"); - - var membersProperty = enumType.GetType().GetProperty("Members"); - return membersProperty != null - ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null) - : Enumerable.Empty(); - } - - public bool EnumIsFlags(EdmType enumType) - { - ArgumentNotNull(enumType, "enumType"); - - var isFlagsProperty = enumType.GetType().GetProperty("IsFlags"); - return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null); - } - - public bool IsEnumType(GlobalItem edmType) - { - ArgumentNotNull(edmType, "edmType"); - - return edmType.GetType().Name == "EnumType"; - } - - public PrimitiveType GetEnumUnderlyingType(EdmType enumType) - { - ArgumentNotNull(enumType, "enumType"); - - return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null); - } - - public string CreateLiteral(object value) - { - if (value == null || value.GetType() != typeof(TimeSpan)) - { - return _code.CreateLiteral(value); - } - - return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks); - } - - public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) - { - ArgumentNotNull(types, "types"); - ArgumentNotNull(sourceFile, "sourceFile"); - - var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); - if (types.Any(item => !hash.Add(item))) - { - _errors.Add( - new CompilerError(sourceFile, -1, -1, "6023", - String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CaseInsensitiveTypeConflict")))); - return false; - } - return true; - } - - public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection) - { - return GetItemsToGenerate(itemCollection) - .Where(e => IsEnumType(e)); - } - - public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType - { - return itemCollection - .OfType() - .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) - .OrderBy(i => i.Name); - } - - public IEnumerable GetAllGlobalItems(IEnumerable itemCollection) - { - return itemCollection - .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i)) - .Select(g => GetGlobalItemName(g)); - } - - public string GetGlobalItemName(GlobalItem item) - { - if (item is EdmType) - { - return ((EdmType)item).Name; - } - else - { - return ((EntityContainer)item).Name; - } - } - - public IEnumerable GetSimpleProperties(EntityType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); - } - - public IEnumerable GetSimpleProperties(ComplexType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); - } - - public IEnumerable GetComplexProperties(EntityType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); - } - - public IEnumerable GetComplexProperties(ComplexType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); - } - - public IEnumerable GetPropertiesWithDefaultValues(EntityType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); - } - - public IEnumerable GetPropertiesWithDefaultValues(ComplexType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); - } - - public IEnumerable GetNavigationProperties(EntityType type) - { - return type.NavigationProperties.Where(np => np.DeclaringType == type); - } - - public IEnumerable GetCollectionNavigationProperties(EntityType type) - { - return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many); - } - - public FunctionParameter GetReturnParameter(EdmFunction edmFunction) - { - ArgumentNotNull(edmFunction, "edmFunction"); - - var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters"); - return returnParamsProperty == null - ? edmFunction.ReturnParameter - : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault(); - } - - public bool IsComposable(EdmFunction edmFunction) - { - ArgumentNotNull(edmFunction, "edmFunction"); - - var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute"); - return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null); - } - - public IEnumerable GetParameters(EdmFunction edmFunction) - { - return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); - } - - public TypeUsage GetReturnType(EdmFunction edmFunction) - { - var returnParam = GetReturnParameter(edmFunction); - return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage); - } - - public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption) - { - var returnType = GetReturnType(edmFunction); - return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType; - } -} - -public class EdmMetadataLoader -{ - private readonly IDynamicHost _host; - private readonly System.Collections.IList _errors; - - public EdmMetadataLoader(IDynamicHost host, System.Collections.IList errors) - { - ArgumentNotNull(host, "host"); - ArgumentNotNull(errors, "errors"); - - _host = host; - _errors = errors; - } - - public IEnumerable CreateEdmItemCollection(string sourcePath) - { - ArgumentNotNull(sourcePath, "sourcePath"); - - if (!ValidateInputPath(sourcePath)) - { - return new EdmItemCollection(); - } - - var schemaElement = LoadRootElement(_host.ResolvePath(sourcePath)); - if (schemaElement != null) - { - using (var reader = schemaElement.CreateReader()) - { - IList errors; - var itemCollection = MetadataItemCollectionFactory.CreateEdmItemCollection(new[] { reader }, out errors); - - ProcessErrors(errors, sourcePath); - - return itemCollection; - } - } - return new EdmItemCollection(); - } - - public string GetModelNamespace(string sourcePath) - { - ArgumentNotNull(sourcePath, "sourcePath"); - - if (!ValidateInputPath(sourcePath)) - { - return string.Empty; - } - - var model = LoadRootElement(_host.ResolvePath(sourcePath)); - if (model == null) - { - return string.Empty; - } - - var attribute = model.Attribute("Namespace"); - return attribute != null ? attribute.Value : ""; - } - - private bool ValidateInputPath(string sourcePath) - { - if (sourcePath == "$" + "edmxInputFile" + "$") - { - _errors.Add( - new CompilerError(_host.TemplateFile ?? sourcePath, 0, 0, string.Empty, - GetResourceString("Template_ReplaceVsItemTemplateToken"))); - return false; - } - - return true; - } - - public XElement LoadRootElement(string sourcePath) - { - ArgumentNotNull(sourcePath, "sourcePath"); - - var root = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); - return root.Elements() - .Where(e => e.Name.LocalName == "Runtime") - .Elements() - .Where(e => e.Name.LocalName == "ConceptualModels") - .Elements() - .Where(e => e.Name.LocalName == "Schema") - .FirstOrDefault() - ?? root; - } - - private void ProcessErrors(IEnumerable errors, string sourceFilePath) - { - foreach (var error in errors) - { - _errors.Add( - new CompilerError( - error.SchemaLocation ?? sourceFilePath, - error.Line, - error.Column, - error.ErrorCode.ToString(CultureInfo.InvariantCulture), - error.Message) - { - IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning - }); - } - } - - public bool IsLazyLoadingEnabled(EntityContainer container) - { - string lazyLoadingAttributeValue; - var lazyLoadingAttributeName = MetadataConstants.EDM_ANNOTATION_09_02 + ":LazyLoadingEnabled"; - bool isLazyLoading; - return !MetadataTools.TryGetStringMetadataPropertySetting(container, lazyLoadingAttributeName, out lazyLoadingAttributeValue) - || !bool.TryParse(lazyLoadingAttributeValue, out isLazyLoading) - || isLazyLoading; - } -} - -public static void ArgumentNotNull(T arg, string name) where T : class -{ - if (arg == null) - { - throw new ArgumentNullException(name); - } -} - -private static readonly Lazy ResourceManager = - new Lazy( - () => new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(MetadataItemCollectionFactory).Assembly), isThreadSafe: true); - -public static string GetResourceString(string resourceName) -{ - ArgumentNotNull(resourceName, "resourceName"); - - return ResourceManager.Value.GetString(resourceName, null); -} - +<#@ template language="C#" debug="false" hostspecific="true"#> +<#@ include file="EF.Utility.CS.ttinclude"#><#@ + output extension=".cs"#><# + +const string inputFile = @"..\Schemas\AdvancedPatterns.edmx"; +var textTransform = DynamicTextTransformation.Create(this); +var code = new CodeGenerationTools(this); +var ef = new MetadataTools(this); +var typeMapper = new TypeMapper(code, ef, textTransform.Errors); +var fileManager = EntityFrameworkTemplateFileManager.Create(this); +var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile); +var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); + +if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile)) +{ + return string.Empty; +} + +WriteHeader(codeStringGenerator, fileManager); + +foreach (var entity in typeMapper.GetItemsToGenerate(itemCollection)) +{ + fileManager.StartNewFile(entity.Name + ".cs"); + BeginNamespace(code); +#> +<#=codeStringGenerator.UsingDirectives(inHeader: false)#> +<#=codeStringGenerator.EntityClassOpening(entity)#> +{ +<# + var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity); + var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity); + var complexProperties = typeMapper.GetComplexProperties(entity); + + if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any()) + { +#> + public <#=code.Escape(entity)#>() + { +<# + foreach (var edmProperty in propertiesWithDefaultValues) + { +#> + this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>; +<# + } + + foreach (var navigationProperty in collectionNavigationProperties) + { +#> + this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>(); +<# + } + + foreach (var complexProperty in complexProperties) + { +#> + this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>(); +<# + } +#> + } + +<# + } + + var simpleProperties = typeMapper.GetSimpleProperties(entity); + if (simpleProperties.Any()) + { + foreach (var edmProperty in simpleProperties) + { +#> + <#=codeStringGenerator.Property(edmProperty)#> +<# + } + } + + if (complexProperties.Any()) + { +#> + +<# + foreach(var complexProperty in complexProperties) + { +#> + <#=codeStringGenerator.Property(complexProperty)#> +<# + } + } + + var navigationProperties = typeMapper.GetNavigationProperties(entity); + if (navigationProperties.Any()) + { +#> + +<# + foreach (var navigationProperty in navigationProperties) + { +#> + <#=codeStringGenerator.NavigationProperty(navigationProperty)#> +<# + } + } +#> +} +<# + EndNamespace(code); +} + +foreach (var complex in typeMapper.GetItemsToGenerate(itemCollection)) +{ + fileManager.StartNewFile(complex.Name + ".cs"); + BeginNamespace(code); +#> +<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#> +<#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#> +{ +<# + var complexProperties = typeMapper.GetComplexProperties(complex); + var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex); + + if (propertiesWithDefaultValues.Any() || complexProperties.Any()) + { +#> + public <#=code.Escape(complex)#>() + { +<# + foreach (var edmProperty in propertiesWithDefaultValues) + { +#> + this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>; +<# + } + + foreach (var complexProperty in complexProperties) + { +#> + this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>(); +<# + } +#> + } + +<# + } + + var simpleProperties = typeMapper.GetSimpleProperties(complex); + if (simpleProperties.Any()) + { + foreach(var edmProperty in simpleProperties) + { +#> + <#=codeStringGenerator.Property(edmProperty)#> +<# + } + } + + if (complexProperties.Any()) + { +#> + +<# + foreach(var edmProperty in complexProperties) + { +#> + <#=codeStringGenerator.Property(edmProperty)#> +<# + } + } +#> +} +<# + EndNamespace(code); +} + +foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection)) +{ + fileManager.StartNewFile(enumType.Name + ".cs"); + BeginNamespace(code); +#> +<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#> +<# + if (typeMapper.EnumIsFlags(enumType)) + { +#> +[Flags] +<# + } +#> +<#=codeStringGenerator.EnumOpening(enumType)#> +{ +<# + var foundOne = false; + + foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType)) + { + foundOne = true; +#> + <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>, +<# + } + + if (foundOne) + { + this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1); + } +#> +} +<# + EndNamespace(code); +} + +fileManager.Process(); + +#> +<#+ + +public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager) +{ + fileManager.StartHeader(); +#> +//------------------------------------------------------------------------------ +// +// <#=GetResourceString("Template_GeneratedCodeCommentLine1")#> +// +// <#=GetResourceString("Template_GeneratedCodeCommentLine2")#> +// <#=GetResourceString("Template_GeneratedCodeCommentLine3")#> +// +//------------------------------------------------------------------------------ +<#=codeStringGenerator.UsingDirectives(inHeader: true)#> +<#+ + fileManager.EndBlock(); +} + +public void BeginNamespace(CodeGenerationTools code) +{ + var codeNamespace = code.VsNamespaceSuggestion(); + if (!String.IsNullOrEmpty(codeNamespace)) + { +#> +namespace <#=code.EscapeNamespace(codeNamespace)#> +{ +<#+ + PushIndent(" "); + } +} + +public void EndNamespace(CodeGenerationTools code) +{ + if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion())) + { + PopIndent(); +#> +} +<#+ + } +} + +public const string TemplateId = "CSharp_DbContext_Types_EF5"; + +public class CodeStringGenerator +{ + private readonly CodeGenerationTools _code; + private readonly TypeMapper _typeMapper; + private readonly MetadataTools _ef; + + public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef) + { + ArgumentNotNull(code, "code"); + ArgumentNotNull(typeMapper, "typeMapper"); + ArgumentNotNull(ef, "ef"); + + _code = code; + _typeMapper = typeMapper; + _ef = ef; + } + + public string Property(EdmProperty edmProperty) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2} {{ {3}get; {4}set; }}", + Accessibility.ForProperty(edmProperty), + _typeMapper.GetTypeName(edmProperty.TypeUsage), + _code.Escape(edmProperty), + _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), + _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); + } + + public string NavigationProperty(NavigationProperty navigationProperty) + { + var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType()); + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2} {{ {3}get; {4}set; }}", + AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)), + navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, + _code.Escape(navigationProperty), + _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)), + _code.SpaceAfter(Accessibility.ForSetter(navigationProperty))); + } + + public string AccessibilityAndVirtual(string accessibility) + { + return accessibility + (accessibility != "private" ? " virtual" : ""); + } + + public string EntityClassOpening(EntityType entity) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1}partial class {2}{3}", + Accessibility.ForType(entity), + _code.SpaceAfter(_code.AbstractOption(entity)), + _code.Escape(entity), + _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType))); + } + + public string EnumOpening(SimpleType enumType) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} enum {1} : {2}", + Accessibility.ForType(enumType), + _code.Escape(enumType), + _code.Escape(_typeMapper.UnderlyingClrType(enumType))); + } + + public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter) + { + var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); + foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) + { + var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; + var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")"; + var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + parameter.RawClrTypeName + "))"; + writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit); + } + } + + public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace) + { + var parameters = _typeMapper.GetParameters(edmFunction); + + return string.Format( + CultureInfo.InvariantCulture, + "{0} IQueryable<{1}> {2}{3}", + AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), + _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), + _code.Escape(edmFunction), + string.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray())); + } + + public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace) + { + var parameters = _typeMapper.GetParameters(edmFunction); + + return string.Format( + CultureInfo.InvariantCulture, + "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});", + _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), + edmFunction.NamespaceName, + edmFunction.Name, + string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()), + _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))); + } + + public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) + { + var parameters = _typeMapper.GetParameters(edmFunction); + var returnType = _typeMapper.GetReturnType(edmFunction); + + var paramList = String.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray()); + if (includeMergeOption) + { + paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption"; + } + + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2}({3})", + AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), + returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", + _code.Escape(edmFunction), + paramList); + } + + public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) + { + var parameters = _typeMapper.GetParameters(edmFunction); + var returnType = _typeMapper.GetReturnType(edmFunction); + + var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())); + if (includeMergeOption) + { + callParams = ", mergeOption" + callParams; + } + + return string.Format( + CultureInfo.InvariantCulture, + "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});", + returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", + edmFunction.Name, + callParams); + } + + public string DbSet(EntitySet entitySet) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} DbSet<{1}> {2} {{ get; set; }}", + Accessibility.ForReadOnlyProperty(entitySet), + _typeMapper.GetTypeName(entitySet.ElementType), + _code.Escape(entitySet)); + } + + public string UsingDirectives(bool inHeader, bool includeCollections = true) + { + return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion()) + ? string.Format( + CultureInfo.InvariantCulture, + "{0}using System;{1}" + + "{2}", + inHeader ? Environment.NewLine : "", + includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "", + inHeader ? "" : Environment.NewLine) + : ""; + } +} + +public class TypeMapper +{ + private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; + + private readonly System.Collections.IList _errors; + private readonly CodeGenerationTools _code; + private readonly MetadataTools _ef; + + public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors) + { + ArgumentNotNull(code, "code"); + ArgumentNotNull(ef, "ef"); + ArgumentNotNull(errors, "errors"); + + _code = code; + _ef = ef; + _errors = errors; + } + + public string GetTypeName(TypeUsage typeUsage) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); + } + + public string GetTypeName(EdmType edmType) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: null); + } + + public string GetTypeName(TypeUsage typeUsage, string modelNamespace) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); + } + + public string GetTypeName(EdmType edmType, string modelNamespace) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); + } + + public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) + { + if (edmType == null) + { + return null; + } + + var collectionType = edmType as CollectionType; + if (collectionType != null) + { + return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); + } + + var typeName = _code.Escape(edmType.MetadataProperties + .Where(p => p.Name == ExternalTypeNameAttributeName) + .Select(p => (string)p.Value) + .FirstOrDefault()) + ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ? + _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) : + _code.Escape(edmType)); + + if (edmType is StructuralType) + { + return typeName; + } + + if (edmType is SimpleType) + { + var clrType = UnderlyingClrType(edmType); + if (!IsEnumType(edmType)) + { + typeName = _code.Escape(clrType); + } + + return clrType.IsValueType && isNullable == true ? + String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : + typeName; + } + + throw new ArgumentException("edmType"); + } + + public Type UnderlyingClrType(EdmType edmType) + { + ArgumentNotNull(edmType, "edmType"); + + var primitiveType = edmType as PrimitiveType; + if (primitiveType != null) + { + return primitiveType.ClrEquivalentType; + } + + if (IsEnumType(edmType)) + { + return GetEnumUnderlyingType(edmType).ClrEquivalentType; + } + + return typeof(object); + } + + public object GetEnumMemberValue(MetadataItem enumMember) + { + ArgumentNotNull(enumMember, "enumMember"); + + var valueProperty = enumMember.GetType().GetProperty("Value"); + return valueProperty == null ? null : valueProperty.GetValue(enumMember, null); + } + + public string GetEnumMemberName(MetadataItem enumMember) + { + ArgumentNotNull(enumMember, "enumMember"); + + var nameProperty = enumMember.GetType().GetProperty("Name"); + return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null); + } + + public System.Collections.IEnumerable GetEnumMembers(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + var membersProperty = enumType.GetType().GetProperty("Members"); + return membersProperty != null + ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null) + : Enumerable.Empty(); + } + + public bool EnumIsFlags(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + var isFlagsProperty = enumType.GetType().GetProperty("IsFlags"); + return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null); + } + + public bool IsEnumType(GlobalItem edmType) + { + ArgumentNotNull(edmType, "edmType"); + + return edmType.GetType().Name == "EnumType"; + } + + public PrimitiveType GetEnumUnderlyingType(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null); + } + + public string CreateLiteral(object value) + { + if (value == null || value.GetType() != typeof(TimeSpan)) + { + return _code.CreateLiteral(value); + } + + return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks); + } + + public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) + { + ArgumentNotNull(types, "types"); + ArgumentNotNull(sourceFile, "sourceFile"); + + var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); + if (types.Any(item => !hash.Add(item))) + { + _errors.Add( + new CompilerError(sourceFile, -1, -1, "6023", + String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CaseInsensitiveTypeConflict")))); + return false; + } + return true; + } + + public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection) + { + return GetItemsToGenerate(itemCollection) + .Where(e => IsEnumType(e)); + } + + public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType + { + return itemCollection + .OfType() + .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) + .OrderBy(i => i.Name); + } + + public IEnumerable GetAllGlobalItems(IEnumerable itemCollection) + { + return itemCollection + .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i)) + .Select(g => GetGlobalItemName(g)); + } + + public string GetGlobalItemName(GlobalItem item) + { + if (item is EdmType) + { + return ((EdmType)item).Name; + } + else + { + return ((EntityContainer)item).Name; + } + } + + public IEnumerable GetSimpleProperties(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); + } + + public IEnumerable GetSimpleProperties(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); + } + + public IEnumerable GetComplexProperties(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); + } + + public IEnumerable GetComplexProperties(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); + } + + public IEnumerable GetPropertiesWithDefaultValues(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); + } + + public IEnumerable GetPropertiesWithDefaultValues(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); + } + + public IEnumerable GetNavigationProperties(EntityType type) + { + return type.NavigationProperties.Where(np => np.DeclaringType == type); + } + + public IEnumerable GetCollectionNavigationProperties(EntityType type) + { + return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many); + } + + public FunctionParameter GetReturnParameter(EdmFunction edmFunction) + { + ArgumentNotNull(edmFunction, "edmFunction"); + + var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters"); + return returnParamsProperty == null + ? edmFunction.ReturnParameter + : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault(); + } + + public bool IsComposable(EdmFunction edmFunction) + { + ArgumentNotNull(edmFunction, "edmFunction"); + + var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute"); + return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null); + } + + public IEnumerable GetParameters(EdmFunction edmFunction) + { + return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); + } + + public TypeUsage GetReturnType(EdmFunction edmFunction) + { + var returnParam = GetReturnParameter(edmFunction); + return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage); + } + + public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption) + { + var returnType = GetReturnType(edmFunction); + return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType; + } +} + +public class EdmMetadataLoader +{ + private readonly IDynamicHost _host; + private readonly System.Collections.IList _errors; + + public EdmMetadataLoader(IDynamicHost host, System.Collections.IList errors) + { + ArgumentNotNull(host, "host"); + ArgumentNotNull(errors, "errors"); + + _host = host; + _errors = errors; + } + + public IEnumerable CreateEdmItemCollection(string sourcePath) + { + ArgumentNotNull(sourcePath, "sourcePath"); + + if (!ValidateInputPath(sourcePath)) + { + return new EdmItemCollection(); + } + + var schemaElement = LoadRootElement(_host.ResolvePath(sourcePath)); + if (schemaElement != null) + { + using (var reader = schemaElement.CreateReader()) + { + IList errors; + var itemCollection = MetadataItemCollectionFactory.CreateEdmItemCollection(new[] { reader }, out errors); + + ProcessErrors(errors, sourcePath); + + return itemCollection; + } + } + return new EdmItemCollection(); + } + + public string GetModelNamespace(string sourcePath) + { + ArgumentNotNull(sourcePath, "sourcePath"); + + if (!ValidateInputPath(sourcePath)) + { + return string.Empty; + } + + var model = LoadRootElement(_host.ResolvePath(sourcePath)); + if (model == null) + { + return string.Empty; + } + + var attribute = model.Attribute("Namespace"); + return attribute != null ? attribute.Value : ""; + } + + private bool ValidateInputPath(string sourcePath) + { + if (sourcePath == "$" + "edmxInputFile" + "$") + { + _errors.Add( + new CompilerError(_host.TemplateFile ?? sourcePath, 0, 0, string.Empty, + GetResourceString("Template_ReplaceVsItemTemplateToken"))); + return false; + } + + return true; + } + + public XElement LoadRootElement(string sourcePath) + { + ArgumentNotNull(sourcePath, "sourcePath"); + + var root = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); + return root.Elements() + .Where(e => e.Name.LocalName == "Runtime") + .Elements() + .Where(e => e.Name.LocalName == "ConceptualModels") + .Elements() + .Where(e => e.Name.LocalName == "Schema") + .FirstOrDefault() + ?? root; + } + + private void ProcessErrors(IEnumerable errors, string sourceFilePath) + { + foreach (var error in errors) + { + _errors.Add( + new CompilerError( + error.SchemaLocation ?? sourceFilePath, + error.Line, + error.Column, + error.ErrorCode.ToString(CultureInfo.InvariantCulture), + error.Message) + { + IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning + }); + } + } + + public bool IsLazyLoadingEnabled(EntityContainer container) + { + string lazyLoadingAttributeValue; + var lazyLoadingAttributeName = MetadataConstants.EDM_ANNOTATION_09_02 + ":LazyLoadingEnabled"; + bool isLazyLoading; + return !MetadataTools.TryGetStringMetadataPropertySetting(container, lazyLoadingAttributeName, out lazyLoadingAttributeValue) + || !bool.TryParse(lazyLoadingAttributeValue, out isLazyLoading) + || isLazyLoading; + } +} + +public static void ArgumentNotNull(T arg, string name) where T : class +{ + if (arg == null) + { + throw new ArgumentNullException(name); + } +} + +private static readonly Lazy ResourceManager = + new Lazy( + () => new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(MetadataItemCollectionFactory).Assembly), isThreadSafe: true); + +public static string GetResourceString(string resourceName) +{ + ArgumentNotNull(resourceName, "resourceName"); + + return ResourceManager.Value.GetString(resourceName, null); +} + #> \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/CurrentEmployeeMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/CurrentEmployeeMf.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/CurrentEmployeeMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/CurrentEmployeeMf.cs index fdf6dedd..b8646b12 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/CurrentEmployeeMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/CurrentEmployeeMf.cs @@ -1,22 +1,22 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - using System; - using System.Collections.Generic; - - public partial class CurrentEmployeeMf : EmployeeMf - { - public Nullable LeaveBalance { get; set; } - - public virtual CurrentEmployeeMf Manager { get; set; } - public virtual OfficeMf Office { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + using System; + using System.Collections.Generic; + + public partial class CurrentEmployeeMf : EmployeeMf + { + public Nullable LeaveBalance { get; set; } + + public virtual CurrentEmployeeMf Manager { get; set; } + public virtual OfficeMf Office { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/EF.Utility.CS.ttinclude b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/EF.Utility.CS.ttinclude similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/EF.Utility.CS.ttinclude rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/EF.Utility.CS.ttinclude index 3f40d2a6..ac68740d 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/EF.Utility.CS.ttinclude +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/EF.Utility.CS.ttinclude @@ -1,2549 +1,2549 @@ -<#@ assembly name="System.Core" #> -<#@ assembly name="System.Data" #> -<#@ assembly name="System.Data.Entity" #> -<#@ assembly name="System.Data.Entity.Design" #> -<#@ assembly name="System.Xml" #> -<#@ assembly name="System.Xml.Linq"#> -<#@ assembly name="EnvDTE"#> -<#@ import namespace="System" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.IO" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ import namespace="System.Data.Objects" #> -<#@ import namespace="System.Data.Objects.DataClasses" #> -<#@ import namespace="System.Xml" #> -<#@ import namespace="System.Xml.Linq" #> -<#@ import namespace="System.Globalization" #> -<#@ import namespace="System.Reflection" #> -<#@ import namespace="System.Data.Metadata.Edm" #> -<#@ import namespace="System.Data.Mapping" #> -<#@ import namespace="System.Data.Entity.Design" #> -<#@ import namespace="System.CodeDom" #> -<#@ import namespace="System.CodeDom.Compiler" #> -<#@ import namespace="Microsoft.CSharp"#> -<#@ import namespace="System.Text"#> -<#+ -// Copyright (c) Microsoft Corporation. All rights reserved. - -public static Dictionary TemplateMetadata = new Dictionary(); - -/// -/// Responsible for helping to create source code that is -/// correctly formated and functional -/// -public class CodeGenerationTools -{ - private readonly DynamicTextTransformation _textTransformation; - private readonly CSharpCodeProvider _code; - private readonly MetadataTools _ef; - - /// - /// Initializes a new CodeGenerationTools object with the TextTransformation (T4 generated class) - /// that is currently running - /// - public CodeGenerationTools(object textTransformation) - { - if (textTransformation == null) - { - throw new ArgumentNullException("textTransformation"); - } - - _textTransformation = DynamicTextTransformation.Create(textTransformation); - _code = new CSharpCodeProvider(); - _ef = new MetadataTools(_textTransformation); - FullyQualifySystemTypes = false; - CamelCaseFields = true; - } - - /// - /// When true, all types that are not being generated - /// are fully qualified to keep them from conflicting with - /// types that are being generated. Useful when you have - /// something like a type being generated named System. - /// - /// Default is false. - /// - public bool FullyQualifySystemTypes { get; set; } - - /// - /// When true, the field names are Camel Cased, - /// otherwise they will preserve the case they - /// start with. - /// - /// Default is true. - /// - public bool CamelCaseFields { get; set; } - - /// - /// Returns the NamespaceName suggested by VS if running inside VS. Otherwise, returns - /// null. - /// - public string VsNamespaceSuggestion() - { - string suggestion = _textTransformation.Host.ResolveParameterValue("directiveId", "namespaceDirectiveProcessor", "namespaceHint"); - if (String.IsNullOrEmpty(suggestion)) - { - return null; - } - - return suggestion; - } - - /// - /// Returns a string that is safe for use as an identifier in C#. - /// Keywords are escaped. - /// - public string Escape(string name) - { - if (name == null) - { - return null; - } - - return _code.CreateEscapedIdentifier(name); - } - - /// - /// Returns the name of the TypeUsage's EdmType that is safe for - /// use as an identifier. - /// - public string Escape(TypeUsage typeUsage) - { - if (typeUsage == null) - { - return null; - } - - if (typeUsage.EdmType is ComplexType || - typeUsage.EdmType is EntityType) - { - return Escape(typeUsage.EdmType.Name); - } - else if (typeUsage.EdmType is SimpleType) - { - Type clrType = _ef.UnderlyingClrType(typeUsage.EdmType); - string typeName = typeUsage.EdmType is EnumType ? Escape(typeUsage.EdmType.Name) : Escape(clrType); - if (clrType.IsValueType && _ef.IsNullable(typeUsage)) - { - return String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName); - } - - return typeName; - } - else if (typeUsage.EdmType is CollectionType) - { - return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", Escape(((CollectionType)typeUsage.EdmType).TypeUsage)); - } - - throw new ArgumentException("typeUsage"); - } - - /// - /// Returns the name of the EdmMember that is safe for - /// use as an identifier. - /// - public string Escape(EdmMember member) - { - if (member == null) - { - return null; - } - - return Escape(member.Name); - } - - /// - /// Returns the name of the EdmType that is safe for - /// use as an identifier. - /// - public string Escape(EdmType type) - { - if (type == null) - { - return null; - } - - return Escape(type.Name); - } - - /// - /// Returns the name of the EdmFunction that is safe for - /// use as an identifier. - /// - public string Escape(EdmFunction function) - { - if (function == null) - { - return null; - } - - return Escape(function.Name); - } - - /// - /// Returns the name of the EnumMember that is safe for - /// use as an identifier. - /// - public string Escape(EnumMember member) - { - if (member == null) - { - return null; - } - - return Escape(member.Name); - } - - /// - /// Returns the name of the EntityContainer that is safe for - /// use as an identifier. - /// - public string Escape(EntityContainer container) - { - if (container == null) - { - return null; - } - - return Escape(container.Name); - } - - /// - /// Returns the name of the EntitySet that is safe for - /// use as an identifier. - /// - public string Escape(EntitySet set) - { - if (set == null) - { - return null; - } - - return Escape(set.Name); - } - - /// - /// Returns the name of the StructuralType that is safe for - /// use as an identifier. - /// - public string Escape(StructuralType type) - { - if (type == null) - { - return null; - } - - return Escape(type.Name); - } - - /// - /// Returns the NamespaceName with each segment safe to - /// use as an identifier. - /// - public string EscapeNamespace(string namespaceName) - { - if (String.IsNullOrEmpty(namespaceName)) - { - return namespaceName; - } - - string[] parts = namespaceName.Split('.'); - namespaceName = String.Empty; - foreach (string part in parts) - { - if (namespaceName != String.Empty) - { - namespaceName += "."; - } - - namespaceName += Escape(part); - } - - return namespaceName; - } - - /// - /// Returns the name of the EdmMember formatted for - /// use as a field identifier. - /// - /// This method changes behavior based on the CamelCaseFields - /// setting. - /// - public string FieldName(EdmMember member) - { - if (member == null) - { - return null; - } - - return FieldName(member.Name); - } - - /// - /// Returns the name of the EntitySet formatted for - /// use as a field identifier. - /// - /// This method changes behavior based on the CamelCaseFields - /// setting. - /// - public string FieldName(EntitySet set) - { - if (set == null) - { - return null; - } - - return FieldName(set.Name); - - } - - private string FieldName(string name) - { - if (CamelCaseFields) - { - return "_" + CamelCase(name); - } - else - { - return "_" + name; - } - } - - /// - /// Returns the name of the Type object formatted for - /// use in source code. - /// - /// This method changes behavior based on the FullyQualifySystemTypes - /// setting. - /// - public string Escape(Type clrType) - { - return Escape(clrType, FullyQualifySystemTypes); - } - - /// - /// Returns the name of the Type object formatted for - /// use in source code. - /// - public string Escape(Type clrType, bool fullyQualifySystemTypes) - { - if(clrType == null) - { - return null; - } - - string typeName; - if (fullyQualifySystemTypes) - { - typeName = "global::" + clrType.FullName; - } - else - { - typeName = _code.GetTypeOutput(new CodeTypeReference(clrType)); - } - return typeName; - } - - /// - /// Returns the abstract option if the entity is Abstract, otherwise returns String.Empty - /// - public string AbstractOption(EntityType entity) - { - if (entity.Abstract) - { - return "abstract"; - } - return String.Empty; - } - - /// - /// Returns the passed in identifier with the first letter changed to lowercase - /// - public string CamelCase(string identifier) - { - if (String.IsNullOrEmpty(identifier)) - { - return identifier; - } - - if (identifier.Length == 1) - { - return identifier[0].ToString(CultureInfo.InvariantCulture).ToLowerInvariant(); - } - - return identifier[0].ToString(CultureInfo.InvariantCulture).ToLowerInvariant() + identifier.Substring(1); - } - - /// - /// If the value parameter is null or empty an empty string is returned, - /// otherwise it retuns value with a single space concatenated on the end. - /// - public string SpaceAfter(string value) - { - return StringAfter(value, " "); - } - - /// - /// If the value parameter is null or empty an empty string is returned, - /// otherwise it retuns value with a single space concatenated on the end. - /// - public string SpaceBefore(string value) - { - return StringBefore(" ", value); - } - - /// - /// If the value parameter is null or empty an empty string is returned, - /// otherwise it retuns value with append concatenated on the end. - /// - public string StringAfter(string value, string append) - { - if (String.IsNullOrEmpty(value)) - { - return String.Empty; - } - - return value + append; - } - - /// - /// If the value parameter is null or empty an empty string is returned, - /// otherwise it retuns value with prepend concatenated on the front. - /// - public string StringBefore(string prepend, string value) - { - if (String.IsNullOrEmpty(value)) - { - return String.Empty; - } - - return prepend + value; - } - - /// - /// Returns false and shows an error if the supplied type names aren't case-insensitively unique, - /// otherwise returns true. - /// - public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) - { - return VerifyCaseInsensitiveUniqueness(types, t => string.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CaseInsensitiveTypeConflict"), t), sourceFile); - } - - /// - /// Returns false and shows an error if the supplied strings aren't case-insensitively unique, - /// otherwise returns true. - /// - private bool VerifyCaseInsensitiveUniqueness(IEnumerable items, Func formatMessage, string sourceFile) - { - HashSet hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); - foreach (string item in items) - { - if (!hash.Add(item)) - { - _textTransformation.Errors.Add(new System.CodeDom.Compiler.CompilerError(sourceFile, -1, -1, "6023", formatMessage(item))); - return false; - } - } - return true; - } - - /// - /// Returns the names of the items in the supplied collection that correspond to O-Space types. - /// - public IEnumerable GetAllGlobalItems(EdmItemCollection itemCollection) - { - return itemCollection.GetItems().Where(i => i is EntityType || i is ComplexType || i is EnumType || i is EntityContainer).Select(g => GetGlobalItemName(g)); - } - - /// - /// Returns the name of the supplied GlobalItem. - /// - public string GetGlobalItemName(GlobalItem item) - { - if (item is EdmType) - { - return ((EdmType)item).Name; - } - else - { - return ((EntityContainer)item).Name; - } - } - - /// - /// Retuns as full of a name as possible, if a namespace is provided - /// the namespace and name are combined with a period, otherwise just - /// the name is returned. - /// - public string CreateFullName(string namespaceName, string name) - { - if (String.IsNullOrEmpty(namespaceName)) - { - return name; - } - - return namespaceName + "." + name; - } - - /// - /// Retuns a literal representing the supplied value. - /// - public string CreateLiteral(object value) - { - if (value == null) - { - return string.Empty; - } - - Type type = value.GetType(); - if (type.IsEnum) - { - return type.FullName + "." + value.ToString(); - } - if (type == typeof(Guid)) - { - return string.Format(CultureInfo.InvariantCulture, "new Guid(\"{0}\")", - ((Guid)value).ToString("D", CultureInfo.InvariantCulture)); - } - else if (type == typeof(DateTime)) - { - return string.Format(CultureInfo.InvariantCulture, "new DateTime({0}, DateTimeKind.Unspecified)", - ((DateTime)value).Ticks); - } - else if (type == typeof(byte[])) - { - var arrayInit = string.Join(", ", ((byte[])value).Select(b => b.ToString(CultureInfo.InvariantCulture)).ToArray()); - return string.Format(CultureInfo.InvariantCulture, "new Byte[] {{{0}}}", arrayInit); - } - else if (type == typeof(DateTimeOffset)) - { - var dto = (DateTimeOffset)value; - return string.Format(CultureInfo.InvariantCulture, "new DateTimeOffset({0}, new TimeSpan({1}))", - dto.Ticks, dto.Offset.Ticks); - } - else if (type == typeof(TimeSpan)) - { - return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", - ((TimeSpan)value).Ticks); - } - - var expression = new CodePrimitiveExpression(value); - var writer = new StringWriter(); - CSharpCodeProvider code = new CSharpCodeProvider(); - code.GenerateCodeFromExpression(expression, writer, new CodeGeneratorOptions()); - return writer.ToString(); - } - - /// - /// Returns a resource string from the System.Data.Entity.Design assembly. - /// - public static string GetResourceString(string resourceName, CultureInfo culture = null) - { - if(_resourceManager == null) - { - _resourceManager = new System.Resources.ResourceManager("System.Data.Entity.Design", - typeof(System.Data.Entity.Design.MetadataItemCollectionFactory).Assembly); - } - - return _resourceManager.GetString(resourceName, culture); - } - static System.Resources.ResourceManager _resourceManager; - - private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; - - /// - /// Gets the entity, complex, or enum types for which code should be generated from the given item collection. - /// Any types for which an ExternalTypeName annotation has been applied in the conceptual model - /// metadata (CSDL) are filtered out of the returned list. - /// - /// The type of item to return. - /// The item collection to look in. - /// The items to generate. - public IEnumerable GetItemsToGenerate(ItemCollection itemCollection) where T: GlobalItem - { - return itemCollection.GetItems().Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)); - } - - /// - /// Returns the escaped type name to use for the given usage of a c-space type in o-space. This might be - /// an external type name if the ExternalTypeName annotation has been specified in the - /// conceptual model metadata (CSDL). - /// - /// The c-space type usage to get a name for. - /// The type name to use. - public string GetTypeName(TypeUsage typeUsage) - { - return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); - } - - /// - /// Returns the escaped type name to use for the given c-space type in o-space. This might be - /// an external type name if the ExternalTypeName annotation has been specified in the - /// conceptual model metadata (CSDL). - /// - /// The c-space type to get a name for. - /// The type name to use. - public string GetTypeName(EdmType edmType) - { - return GetTypeName(edmType, isNullable: null, modelNamespace: null); - } - - /// - /// Returns the escaped type name to use for the given usage of an c-space type in o-space. This might be - /// an external type name if the ExternalTypeName annotation has been specified in the - /// conceptual model metadata (CSDL). - /// - /// The c-space type usage to get a name for. - /// If not null and the type's namespace does not match this namespace, then a - /// fully qualified name will be returned. - /// The type name to use. - public string GetTypeName(TypeUsage typeUsage, string modelNamespace) - { - return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); - } - - /// - /// Returns the escaped type name to use for the given c-space type in o-space. This might be - /// an external type name if the ExternalTypeName annotation has been specified in the - /// conceptual model metadata (CSDL). - /// - /// The c-space type to get a name for. - /// If not null and the type's namespace does not match this namespace, then a - /// fully qualified name will be returned. - /// The type name to use. - public string GetTypeName(EdmType edmType, string modelNamespace) - { - return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); - } - - /// - /// Returns the escaped type name to use for the given c-space type in o-space. This might be - /// an external type name if the ExternalTypeName annotation has been specified in the - /// conceptual model metadata (CSDL). - /// - /// The c-space type to get a name for. - /// Set this to true for nullable usage of this type. - /// If not null and the type's namespace does not match this namespace, then a - /// fully qualified name will be returned. - /// The type name to use. - private string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) - { - if (edmType == null) - { - return null; - } - - var collectionType = edmType as CollectionType; - if (collectionType != null) - { - return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); - } - - // Try to get an external type name, and if that is null, then try to get escape the name from metadata, - // possibly namespace-qualifying it. - var typeName = Escape(edmType.MetadataProperties - .Where(p => p.Name == ExternalTypeNameAttributeName) - .Select(p => (string)p.Value) - .FirstOrDefault()) - ?? - (modelNamespace != null && edmType.NamespaceName != modelNamespace ? - CreateFullName(EscapeNamespace(edmType.NamespaceName), Escape(edmType)) : - Escape(edmType)); - - if (edmType is StructuralType) - { - return typeName; - } - - if (edmType is SimpleType) - { - var clrType = _ef.UnderlyingClrType(edmType); - if (!(edmType is EnumType)) - { - typeName = Escape(clrType); - } - - return clrType.IsValueType && isNullable == true ? - String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : - typeName; - } - - throw new ArgumentException("typeUsage"); - } -} - -/// -/// Responsible for making the Entity Framework Metadata more -/// accessible for code generation. -/// -public class MetadataTools -{ - private readonly DynamicTextTransformation _textTransformation; - - /// - /// Initializes an MetadataTools Instance with the - /// TextTransformation (T4 generated class) that is currently running - /// - public MetadataTools(object textTransformation) - { - if (textTransformation == null) - { - throw new ArgumentNullException("textTransformation"); - } - - _textTransformation = DynamicTextTransformation.Create(textTransformation); - } - - /// - /// This method returns the underlying CLR type of the o-space type corresponding to the supplied - /// Note that for an enum type this means that the type backing the enum will be returned, not the enum type itself. - /// - public Type ClrType(TypeUsage typeUsage) - { - return UnderlyingClrType(typeUsage.EdmType); - } - - /// - /// This method returns the underlying CLR type given the c-space type. - /// Note that for an enum type this means that the type backing the enum will be returned, not the enum type itself. - /// - public Type UnderlyingClrType(EdmType edmType) - { - var primitiveType = edmType as PrimitiveType; - if (primitiveType != null) - { - return primitiveType.ClrEquivalentType; - } - - var enumType = edmType as EnumType; - if (enumType != null) - { - return enumType.UnderlyingType.ClrEquivalentType; - } - - return typeof(object); - } - - /// - /// True if the EdmProperty is a key of its DeclaringType, False otherwise. - /// - public bool IsKey(EdmProperty property) - { - if (property != null && property.DeclaringType.BuiltInTypeKind == BuiltInTypeKind.EntityType) - { - return ((EntityType)property.DeclaringType).KeyMembers.Contains(property); - } - - return false; - } - - /// - /// True if the EdmProperty TypeUsage is Nullable, False otherwise. - /// - public bool IsNullable(EdmProperty property) - { - return property != null && IsNullable(property.TypeUsage); - } - - /// - /// True if the TypeUsage is Nullable, False otherwise. - /// - public bool IsNullable(TypeUsage typeUsage) - { - Facet nullableFacet = null; - if (typeUsage != null && - typeUsage.Facets.TryGetValue("Nullable", true, out nullableFacet)) - { - return (bool)nullableFacet.Value; - } - - return false; - } - - /// - /// If the passed in TypeUsage represents a collection this method returns final element - /// type of the collection, otherwise it returns the value passed in. - /// - public TypeUsage GetElementType(TypeUsage typeUsage) - { - if (typeUsage == null) - { - return null; - } - - if (typeUsage.EdmType is CollectionType) - { - return GetElementType(((CollectionType)typeUsage.EdmType).TypeUsage); - } - else - { - return typeUsage; - } - } - - /// - /// Returns the NavigationProperty that is the other end of the same association set if it is - /// available, otherwise it returns null. - /// - public NavigationProperty Inverse(NavigationProperty navProperty) - { - if(navProperty == null) - { - return null; - } - - EntityType toEntity = navProperty.ToEndMember.GetEntityType(); - return toEntity.NavigationProperties - .SingleOrDefault(n => Object.ReferenceEquals(n.RelationshipType, navProperty.RelationshipType) && !Object.ReferenceEquals(n, navProperty)); - } - - /// - /// Given a property on the dependent end of a referential constraint, returns the corresponding property on the principal end. - /// Requires: The association has a referential constraint, and the specified dependentProperty is one of the properties on the dependent end. - /// - public EdmProperty GetCorrespondingPrincipalProperty(NavigationProperty navProperty, EdmProperty dependentProperty) - { - if (navProperty == null) - { - throw new ArgumentNullException("navProperty"); - } - - if (dependentProperty == null) - { - throw new ArgumentNullException("dependentProperty"); - } - - ReadOnlyMetadataCollection fromProperties = GetPrincipalProperties(navProperty); - ReadOnlyMetadataCollection toProperties = GetDependentProperties(navProperty); - return fromProperties[toProperties.IndexOf(dependentProperty)]; - } - - /// - /// Given a property on the principal end of a referential constraint, returns the corresponding property on the dependent end. - /// Requires: The association has a referential constraint, and the specified principalProperty is one of the properties on the principal end. - /// - public EdmProperty GetCorrespondingDependentProperty(NavigationProperty navProperty, EdmProperty principalProperty) - { - if (navProperty == null) - { - throw new ArgumentNullException("navProperty"); - } - - if (principalProperty == null) - { - throw new ArgumentNullException("principalProperty"); - } - - ReadOnlyMetadataCollection fromProperties = GetPrincipalProperties(navProperty); - ReadOnlyMetadataCollection toProperties = GetDependentProperties(navProperty); - return toProperties[fromProperties.IndexOf(principalProperty)]; - } - - /// - /// Gets the collection of properties that are on the principal end of a referential constraint for the specified navigation property. - /// Requires: The association has a referential constraint. - /// - public ReadOnlyMetadataCollection GetPrincipalProperties(NavigationProperty navProperty) - { - if (navProperty == null) - { - throw new ArgumentNullException("navProperty"); - } - - return ((AssociationType)navProperty.RelationshipType).ReferentialConstraints[0].FromProperties; - } - - /// - /// Gets the collection of properties that are on the dependent end of a referential constraint for the specified navigation property. - /// Requires: The association has a referential constraint. - /// - public ReadOnlyMetadataCollection GetDependentProperties(NavigationProperty navProperty) - { - if (navProperty == null) - { - throw new ArgumentNullException("navProperty"); - } - - return ((AssociationType)navProperty.RelationshipType).ReferentialConstraints[0].ToProperties; - } - - /// - /// True if this entity type requires the HandleCascadeDelete method defined and the method has - /// not been defined on any base type - /// - public bool NeedsHandleCascadeDeleteMethod(ItemCollection itemCollection, EntityType entity) - { - bool needsMethod = ContainsCascadeDeleteAssociation(itemCollection, entity); - // Check to make sure no base types have already declared this method - EntityType baseType = entity.BaseType as EntityType; - while(needsMethod && baseType != null) - { - needsMethod = !ContainsCascadeDeleteAssociation(itemCollection, baseType); - baseType = baseType.BaseType as EntityType; - } - return needsMethod; - } - - /// - /// True if this entity type participates in any relationships where the other end has an OnDelete - /// cascade delete defined, or if it is the dependent in any identifying relationships - /// - private bool ContainsCascadeDeleteAssociation(ItemCollection itemCollection, EntityType entity) - { - return itemCollection.GetItems().Where(a => - ((RefType)a.AssociationEndMembers[0].TypeUsage.EdmType).ElementType == entity && IsCascadeDeletePrincipal(a.AssociationEndMembers[1]) || - ((RefType)a.AssociationEndMembers[1].TypeUsage.EdmType).ElementType == entity && IsCascadeDeletePrincipal(a.AssociationEndMembers[0])).Any(); - } - - /// - /// True if the source end of the specified navigation property is the principal in an identifying relationship. - /// or if the source end has cascade delete defined. - /// - public bool IsCascadeDeletePrincipal(NavigationProperty navProperty) - { - if (navProperty == null) - { - throw new ArgumentNullException("navProperty"); - } - - return IsCascadeDeletePrincipal((AssociationEndMember)navProperty.FromEndMember); - } - - /// - /// True if the specified association end is the principal in an identifying relationship. - /// or if the association end has cascade delete defined. - /// - public bool IsCascadeDeletePrincipal(AssociationEndMember associationEnd) - { - if (associationEnd == null) - { - throw new ArgumentNullException("associationEnd"); - } - - return associationEnd.DeleteBehavior == OperationAction.Cascade || IsPrincipalEndOfIdentifyingRelationship(associationEnd); - } - - /// - /// True if the specified association end is the principal end in an identifying relationship. - /// In order to be an identifying relationship, the association must have a referential constraint where all of the dependent properties are part of the dependent type's primary key. - /// - public bool IsPrincipalEndOfIdentifyingRelationship(AssociationEndMember associationEnd) - { - if (associationEnd == null) - { - throw new ArgumentNullException("associationEnd"); - } - - ReferentialConstraint refConstraint = ((AssociationType)associationEnd.DeclaringType).ReferentialConstraints.Where(rc => rc.FromRole == associationEnd).SingleOrDefault(); - if (refConstraint != null) - { - EntityType entity = refConstraint.ToRole.GetEntityType(); - return !refConstraint.ToProperties.Where(tp => !entity.KeyMembers.Contains(tp)).Any(); - } - return false; - } - - /// - /// True if the specified association type is an identifying relationship. - /// In order to be an identifying relationship, the association must have a referential constraint where all of the dependent properties are part of the dependent type's primary key. - /// - public bool IsIdentifyingRelationship(AssociationType association) - { - if (association == null) - { - throw new ArgumentNullException("association"); - } - - return IsPrincipalEndOfIdentifyingRelationship(association.AssociationEndMembers[0]) || IsPrincipalEndOfIdentifyingRelationship(association.AssociationEndMembers[1]); - } - - /// - /// requires: firstType is not null - /// effects: if secondType is among the base types of the firstType, return true, - /// otherwise returns false. - /// when firstType is same as the secondType, return false. - /// - public bool IsSubtypeOf(EdmType firstType, EdmType secondType) - { - if (secondType == null) - { - return false; - } - - // walk up firstType hierarchy list - for (EdmType t = firstType.BaseType; t != null; t = t.BaseType) - { - if (t == secondType) - return true; - } - return false; - } - - /// - /// Returns the subtype of the EntityType in the current itemCollection - /// - public IEnumerable GetSubtypesOf(EntityType type, ItemCollection itemCollection, bool includeAbstractTypes) - { - if (type != null) - { - IEnumerable typesInCollection = itemCollection.GetItems(); - foreach (EntityType typeInCollection in typesInCollection) - { - if (type.Equals(typeInCollection) == false && this.IsSubtypeOf(typeInCollection, type)) - { - if ( includeAbstractTypes || !typeInCollection.Abstract) - { - yield return typeInCollection; - } - } - } - } - } - - public static bool TryGetStringMetadataPropertySetting(MetadataItem item, string propertyName, out string value) - { - value = null; - MetadataProperty property = item.MetadataProperties.FirstOrDefault(p => p.Name == propertyName); - if (property != null) - { - value = (string)property.Value; - } - return value != null; - } -} - -/// -/// Responsible for loading an EdmItemCollection from a .edmx file or .csdl files -/// -public class MetadataLoader -{ - private readonly DynamicTextTransformation _textTransformation; - - /// - /// Initializes an MetadataLoader Instance with the - /// TextTransformation (T4 generated class) that is currently running - /// - public MetadataLoader(object textTransformation) - { - if (textTransformation == null) - { - throw new ArgumentNullException("textTransformation"); - } - - _textTransformation = DynamicTextTransformation.Create(textTransformation); - } - - /// - /// Load the metadata for Edm, Store, and Mapping collections and register them - /// with a new MetadataWorkspace, returns false if any of the parts can't be - /// created, some of the ItemCollections may be registered and usable even if false is - /// returned - /// - public bool TryLoadAllMetadata(string inputFile, out MetadataWorkspace metadataWorkspace) - { - metadataWorkspace = new MetadataWorkspace(); - - EdmItemCollection edmItemCollection = CreateEdmItemCollection(inputFile); - metadataWorkspace.RegisterItemCollection(edmItemCollection); - - StoreItemCollection storeItemCollection = null; - if (TryCreateStoreItemCollection(inputFile, out storeItemCollection)) - { - StorageMappingItemCollection storageMappingItemCollection = null; - if (TryCreateStorageMappingItemCollection(inputFile, edmItemCollection, storeItemCollection, out storageMappingItemCollection)) - { - metadataWorkspace.RegisterItemCollection(storeItemCollection); - metadataWorkspace.RegisterItemCollection(storageMappingItemCollection); - return true; - } - } - - return false; - } - - /// - /// Create an EdmItemCollection loaded with the metadata provided - /// - public EdmItemCollection CreateEdmItemCollection(string sourcePath, params string[] referenceSchemas) - { - EdmItemCollection edmItemCollection; - if(TryCreateEdmItemCollection(sourcePath, referenceSchemas, out edmItemCollection)) - { - return edmItemCollection; - } - - return new EdmItemCollection(); - } - - /// - /// Attempts to create a EdmItemCollection from the specified metadata file - /// - public bool TryCreateEdmItemCollection(string sourcePath, out EdmItemCollection edmItemCollection) - { - return TryCreateEdmItemCollection(sourcePath, null, out edmItemCollection); - } - - /// - /// Attempts to create a EdmItemCollection from the specified metadata file - /// - public bool TryCreateEdmItemCollection(string sourcePath, string[] referenceSchemas, out EdmItemCollection edmItemCollection) - { - edmItemCollection = null; - - if (!ValidateInputPath(sourcePath, _textTransformation)) - { - return false; - } - - if (referenceSchemas == null) - { - referenceSchemas = new string[0]; - } - - ItemCollection itemCollection = null; - sourcePath = _textTransformation.Host.ResolvePath(sourcePath); - EdmItemCollectionBuilder collectionBuilder = new EdmItemCollectionBuilder(_textTransformation, referenceSchemas.Select(s => _textTransformation.Host.ResolvePath(s)).Where(s => s != sourcePath)); - if (collectionBuilder.TryCreateItemCollection(sourcePath, out itemCollection)) - { - edmItemCollection = (EdmItemCollection)itemCollection; - } - - return edmItemCollection != null; - } - - /// - /// Attempts to create a StoreItemCollection from the specified metadata file - /// - public bool TryCreateStoreItemCollection(string sourcePath, out StoreItemCollection storeItemCollection) - { - storeItemCollection = null; - - if (!ValidateInputPath(sourcePath, _textTransformation)) - { - return false; - } - - ItemCollection itemCollection = null; - StoreItemCollectionBuilder collectionBuilder = new StoreItemCollectionBuilder(_textTransformation); - if (collectionBuilder.TryCreateItemCollection(_textTransformation.Host.ResolvePath(sourcePath), out itemCollection)) - { - storeItemCollection = (StoreItemCollection)itemCollection; - } - return storeItemCollection != null; - } - - /// - /// Attempts to create a StorageMappingItemCollection from the specified metadata file, EdmItemCollection, and StoreItemCollection - /// - public bool TryCreateStorageMappingItemCollection(string sourcePath, EdmItemCollection edmItemCollection, StoreItemCollection storeItemCollection, out StorageMappingItemCollection storageMappingItemCollection) - { - storageMappingItemCollection = null; - - if (!ValidateInputPath(sourcePath, _textTransformation)) - { - return false; - } - - if (edmItemCollection == null) - { - throw new ArgumentNullException("edmItemCollection"); - } - - if (storeItemCollection == null) - { - throw new ArgumentNullException("storeItemCollection"); - } - - ItemCollection itemCollection = null; - StorageMappingItemCollectionBuilder collectionBuilder = new StorageMappingItemCollectionBuilder(_textTransformation, edmItemCollection, storeItemCollection); - if (collectionBuilder.TryCreateItemCollection(_textTransformation.Host.ResolvePath(sourcePath), out itemCollection)) - { - storageMappingItemCollection = (StorageMappingItemCollection)itemCollection; - } - return storageMappingItemCollection != null; - } - - /// - /// Gets the Model Namespace from the provided schema file. - /// - public string GetModelNamespace(string sourcePath) - { - if (!ValidateInputPath(sourcePath, _textTransformation)) - { - return String.Empty; - } - - EdmItemCollectionBuilder builder = new EdmItemCollectionBuilder(_textTransformation); - XElement model; - if(builder.TryLoadRootElement(_textTransformation.Host.ResolvePath(sourcePath), out model)) - { - XAttribute attribute = model.Attribute("Namespace"); - if (attribute != null) - { - return attribute.Value; - } - } - - return String.Empty; - } - - /// - /// Returns true if the specified file path is valid - /// - private static bool ValidateInputPath(string sourcePath, DynamicTextTransformation textTransformation) - { - if (String.IsNullOrEmpty(sourcePath)) - { - throw new ArgumentException("sourcePath"); - } - - if(sourcePath == "$edmxInputFile$") - { - textTransformation.Errors.Add(new CompilerError(textTransformation.Host.TemplateFile ?? CodeGenerationTools.GetResourceString("Template_CurrentlyRunningTemplate"), -1, -1, string.Empty, - CodeGenerationTools.GetResourceString("Template_ReplaceVsItemTemplateToken"))); - return false; - } - - return true; - } - - /// - /// Base class for ItemCollectionBuilder classes that - /// loads the specific types of metadata - /// - private abstract class ItemCollectionBuilder - { - private readonly DynamicTextTransformation _textTransformation; - private readonly string _fileExtension; - private readonly string _edmxSectionName; - private readonly string _rootElementName; - - /// - /// FileExtension for individual (non-edmx) metadata file for this - /// specific ItemCollection type - /// - public string FileExtension - { - get { return _fileExtension; } - } - - /// - /// The name of the XmlElement in the .edmx element - /// to find this ItemCollection's metadata - /// - public string EdmxSectionName - { - get { return _edmxSectionName; } - } - - /// - /// The name of the root element of this ItemCollection's metadata - /// - public string RootElementName - { - get { return _rootElementName; } - } - - /// - /// Method to build the appropriate ItemCollection - /// - protected abstract ItemCollection CreateItemCollection(IEnumerable readers, out IList errors); - - /// - /// Ctor to setup the ItemCollectionBuilder members - /// - protected ItemCollectionBuilder(DynamicTextTransformation textTransformation, string fileExtension, string edmxSectionName, string rootElementName) - { - _textTransformation = textTransformation; - _fileExtension = fileExtension; - _edmxSectionName = edmxSectionName; - _rootElementName = rootElementName; - } - - /// - /// Selects a namespace from the supplied constants. - /// - protected abstract string GetNamespace(SchemaConstants constants); - - /// - /// Try to create an ItemCollection loaded with the metadata provided - /// - public bool TryCreateItemCollection(string sourcePath, out ItemCollection itemCollection) - { - itemCollection = null; - - if (!ValidateInputPath(sourcePath, _textTransformation)) - { - return false; - } - - XElement schemaElement = null; - if (TryLoadRootElement(sourcePath, out schemaElement)) - { - List readers = new List(); - try - { - readers.Add(schemaElement.CreateReader()); - IList errors = null; - - ItemCollection tempItemCollection = CreateItemCollection(readers, out errors); - if (ProcessErrors(errors, sourcePath)) - { - return false; - } - - itemCollection = tempItemCollection; - return true; - } - finally - { - foreach (XmlReader reader in readers) - { - ((IDisposable)reader).Dispose(); - } - } - } - - return false; - } - - /// - /// Tries to load the root element from the metadata file provided - /// - public bool TryLoadRootElement(string sourcePath, out XElement schemaElement) - { - schemaElement = null; - string extension = Path.GetExtension(sourcePath); - if (extension.Equals(".edmx", StringComparison.InvariantCultureIgnoreCase)) - { - return TryLoadRootElementFromEdmx(sourcePath, out schemaElement); - } - else if(extension.Equals(FileExtension, StringComparison.InvariantCultureIgnoreCase)) - { - // load from single metadata file (.csdl, .ssdl, or .msl) - schemaElement = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); - return true; - } - - return false; - } - - /// - /// Tries to load the root element from the provided edmxDocument - /// - private bool TryLoadRootElementFromEdmx(XElement edmxDocument, SchemaConstants schemaConstants, string sectionName, string rootElementName, out XElement rootElement) - { - rootElement = null; - - XNamespace edmxNs = schemaConstants.EdmxNamespace; - XNamespace sectionNs = GetNamespace(schemaConstants); - - XElement runtime = edmxDocument.Element(edmxNs + "Runtime"); - if (runtime == null) - { - return false; - } - - XElement section = runtime.Element(edmxNs + sectionName); - if (section == null) - { - return false; - } - - string templateVersion; - - if (!TemplateMetadata.TryGetValue(MetadataConstants.TT_TEMPLATE_VERSION, out templateVersion)) - { - templateVersion = MetadataConstants.DEFAULT_TEMPLATE_VERSION; - } - - if (schemaConstants.MinimumTemplateVersion > new Version(templateVersion)) - { - _textTransformation.Errors.Add(new CompilerError( - _textTransformation.Host.TemplateFile ?? CodeGenerationTools.GetResourceString("Template_CurrentlyRunningTemplate"), -1, -1, string.Empty, - CodeGenerationTools.GetResourceString("Template_UnsupportedSchema")) - {IsWarning = true}); - } - - rootElement = section.Element(sectionNs + rootElementName); - return rootElement != null; - } - - /// - /// Tries to load the root element from the provided .edmx metadata file - /// - private bool TryLoadRootElementFromEdmx(string edmxPath, out XElement rootElement) - { - rootElement = null; - - XElement element = XElement.Load(edmxPath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); - - return TryLoadRootElementFromEdmx(element, MetadataConstants.V3_SCHEMA_CONSTANTS, EdmxSectionName, RootElementName, out rootElement) - || TryLoadRootElementFromEdmx(element, MetadataConstants.V2_SCHEMA_CONSTANTS, EdmxSectionName, RootElementName, out rootElement) - || TryLoadRootElementFromEdmx(element, MetadataConstants.V1_SCHEMA_CONSTANTS, EdmxSectionName, RootElementName, out rootElement); - } - - /// - /// Takes an Enumerable of EdmSchemaErrors, and adds them - /// to the errors collection of the template class - /// - private bool ProcessErrors(IEnumerable errors, string sourceFilePath) - { - bool foundErrors = false; - foreach (EdmSchemaError error in errors) - { - CompilerError newError = new CompilerError(error.SchemaLocation, error.Line, error.Column, - error.ErrorCode.ToString(CultureInfo.InvariantCulture), - error.Message); - newError.IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning; - foundErrors |= error.Severity == EdmSchemaErrorSeverity.Error; - if (error.SchemaLocation == null) - { - newError.FileName = sourceFilePath; - } - _textTransformation.Errors.Add(newError); - } - - return foundErrors; - } - } - - /// - /// Builder class for creating a StorageMappingItemCollection - /// - private class StorageMappingItemCollectionBuilder : ItemCollectionBuilder - { - private readonly EdmItemCollection _edmItemCollection; - private readonly StoreItemCollection _storeItemCollection; - - public StorageMappingItemCollectionBuilder(DynamicTextTransformation textTransformation, EdmItemCollection edmItemCollection, StoreItemCollection storeItemCollection) - : base(textTransformation, MetadataConstants.MSL_EXTENSION, MetadataConstants.MSL_EDMX_SECTION_NAME, MetadataConstants.MSL_ROOT_ELEMENT_NAME) - { - _edmItemCollection = edmItemCollection; - _storeItemCollection = storeItemCollection; - } - - protected override ItemCollection CreateItemCollection(IEnumerable readers, out IList errors) - { - return MetadataItemCollectionFactory.CreateStorageMappingItemCollection(_edmItemCollection, _storeItemCollection, readers, out errors); - } - - /// - /// Selects a namespace from the supplied constants. - /// - protected override string GetNamespace(SchemaConstants constants) - { - return constants.MslNamespace; - } - } - - /// - /// Builder class for creating a StoreItemCollection - /// - private class StoreItemCollectionBuilder : ItemCollectionBuilder - { - public StoreItemCollectionBuilder(DynamicTextTransformation textTransformation) - : base(textTransformation, MetadataConstants.SSDL_EXTENSION, MetadataConstants.SSDL_EDMX_SECTION_NAME, MetadataConstants.SSDL_ROOT_ELEMENT_NAME) - { - } - - protected override ItemCollection CreateItemCollection(IEnumerable readers, out IList errors) - { - return MetadataItemCollectionFactory.CreateStoreItemCollection(readers, out errors); - } - - /// - /// Selects a namespace from the supplied constants. - /// - protected override string GetNamespace(SchemaConstants constants) - { - return constants.SsdlNamespace; - } - } - - /// - /// Builder class for creating a EdmItemCollection - /// - private class EdmItemCollectionBuilder : ItemCollectionBuilder - { - private List _referenceSchemas = new List(); - - public EdmItemCollectionBuilder(DynamicTextTransformation textTransformation) - : base(textTransformation, MetadataConstants.CSDL_EXTENSION, MetadataConstants.CSDL_EDMX_SECTION_NAME, MetadataConstants.CSDL_ROOT_ELEMENT_NAME) - { - } - - public EdmItemCollectionBuilder(DynamicTextTransformation textTransformation, IEnumerable referenceSchemas) - : this(textTransformation) - { - _referenceSchemas.AddRange(referenceSchemas); - } - - protected override ItemCollection CreateItemCollection(IEnumerable readers, out IList errors) - { - List ownedReaders = new List(); - List allReaders = new List(); - try - { - allReaders.AddRange(readers); - foreach (string path in _referenceSchemas.Distinct()) - { - XElement reference; - if(TryLoadRootElement(path, out reference)) - { - XmlReader reader = reference.CreateReader(); - allReaders.Add(reader); - ownedReaders.Add(reader); - } - } - - return MetadataItemCollectionFactory.CreateEdmItemCollection(allReaders, out errors); - } - finally - { - foreach (XmlReader reader in ownedReaders) - { - ((IDisposable)reader).Dispose(); - } - } - } - - /// - /// Selects a namespace from the supplied constants. - /// - protected override string GetNamespace(SchemaConstants constants) - { - return constants.CsdlNamespace; - } - } -} - -/// -/// Responsible for encapsulating the retrieval and translation of the CodeGeneration -/// annotations in the EntityFramework Metadata to a form that is useful in code generation. -/// -public static class Accessibility -{ - private const string GETTER_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:GetterAccess"; - private const string SETTER_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:SetterAccess"; - private const string TYPE_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:TypeAccess"; - private const string METHOD_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:MethodAccess"; - private const string ACCESS_PROTECTED = "Protected"; - private const string ACCESS_INTERNAL = "Internal"; - private const string ACCESS_PRIVATE = "Private"; - private static readonly Dictionary AccessibilityRankIdLookup = new Dictionary - { - { "private", 1}, - { "internal", 2}, - { "protected", 3}, - { "public", 4}, - }; - - /// - /// Gets the accessibility that should be applied to a type being generated from the provided GlobalItem. - /// - /// defaults to public if no annotation is found. - /// - public static string ForType(GlobalItem item) - { - if (item == null) - { - return null; - } - - return GetAccessibility(item, TYPE_ACCESS); - } - - /// - /// Gets the accessibility that should be applied at the property level for a property being - /// generated from the provided EdmMember. - /// - /// defaults to public if no annotation is found. - /// - public static string ForProperty(EdmMember member) - { - if (member == null) - { - return null; - } - - string getterAccess, setterAccess, propertyAccess; - CalculatePropertyAccessibility(member, out propertyAccess, out getterAccess, out setterAccess); - return propertyAccess; - } - - /// - /// Gets the accessibility that should be applied at the property level for a Read-Only property being - /// generated from the provided EdmMember. - /// - /// defaults to public if no annotation is found. - /// - public static string ForReadOnlyProperty(EdmMember member) - { - if (member == null) - { - return null; - } - - return GetAccessibility(member, GETTER_ACCESS); - } - - /// - /// Gets the accessibility that should be applied at the property level for a property being - /// generated from the provided EntitySet. - /// - /// defaults to public if no annotation is found. - /// - public static string ForReadOnlyProperty(EntitySet set) - { - if (set == null) - { - return null; - } - - return GetAccessibility(set, GETTER_ACCESS); - } - - /// - /// Gets the accessibility that should be applied at the property level for a Write-Only property being - /// generated from the provided EdmMember. - /// - /// defaults to public if no annotation is found. - /// - public static string ForWriteOnlyProperty(EdmMember member) - { - if (member == null) - { - return null; - } - - return GetAccessibility(member, SETTER_ACCESS); - } - - - /// - /// Gets the accessibility that should be applied at the get level for a property being - /// generated from the provided EdmMember. - /// - /// defaults to empty if no annotation is found or the accessibility is the same as the property level. - /// - public static string ForGetter(EdmMember member) - { - if (member == null) - { - return null; - } - - string getterAccess, setterAccess, propertyAccess; - CalculatePropertyAccessibility(member, out propertyAccess, out getterAccess, out setterAccess); - return getterAccess; - } - - /// - /// Gets the accessibility that should be applied at the set level for a property being - /// generated from the provided EdmMember. - /// - /// defaults to empty if no annotation is found or the accessibility is the same as the property level. - /// - public static string ForSetter(EdmMember member) - { - if (member == null) - { - return null; - } - - string getterAccess, setterAccess, propertyAccess; - CalculatePropertyAccessibility(member, out propertyAccess, out getterAccess, out setterAccess); - return setterAccess; - } - - /// - /// Gets the accessibility that should be applied to a method being generated from the provided EdmFunction. - /// - /// defaults to public if no annotation is found. - /// - public static string ForMethod(EdmFunction function) - { - if (function == null) - { - return null; - } - - return GetAccessibility(function, METHOD_ACCESS); - } - - private static void CalculatePropertyAccessibility(MetadataItem item, - out string propertyAccessibility, - out string getterAccessibility, - out string setterAccessibility) - { - getterAccessibility = GetAccessibility(item, GETTER_ACCESS); - int getterRank = AccessibilityRankIdLookup[getterAccessibility]; - - setterAccessibility = GetAccessibility(item, SETTER_ACCESS); - int setterRank = AccessibilityRankIdLookup[setterAccessibility]; - - int propertyRank = Math.Max(getterRank, setterRank); - if (setterRank == propertyRank) - { - setterAccessibility = String.Empty; - } - - if (getterRank == propertyRank) - { - getterAccessibility = String.Empty; - } - - propertyAccessibility = AccessibilityRankIdLookup.Where(v => v.Value == propertyRank).Select(v => v.Key).Single(); - } - - private static string GetAccessibility(MetadataItem item, string name) - { - string accessibility; - if (MetadataTools.TryGetStringMetadataPropertySetting(item, name, out accessibility)) - { - return TranslateUserAccessibilityToCSharpAccessibility(accessibility); - } - - return "public"; - } - - private static string TranslateUserAccessibilityToCSharpAccessibility(string userAccessibility) - { - if (userAccessibility == ACCESS_PROTECTED) - { - return "protected"; - } - else if (userAccessibility == ACCESS_INTERNAL) - { - return "internal"; - } - else if (userAccessibility == ACCESS_PRIVATE) - { - return "private"; - } - else - { - // default to public - return "public"; - } - } -} - -/// -/// Responsible for creating source code regions in code when the loop inside -/// actually produces something. -/// -public class CodeRegion -{ - private const int STANDARD_INDENT_LENGTH = 4; - - private readonly DynamicTextTransformation _textTransformation; - private int _beforeRegionLength; - private int _emptyRegionLength; - private int _regionIndentLevel = -1; - - /// - /// Initializes an CodeRegion instance with the - /// TextTransformation (T4 generated class) that is currently running - /// - public CodeRegion(object textTransformation) - { - if (textTransformation == null) - { - throw new ArgumentNullException("textTransformation"); - } - - _textTransformation = DynamicTextTransformation.Create(textTransformation); - } - - /// - /// Initializes an CodeRegion instance with the - /// TextTransformation (T4 generated class) that is currently running, - /// and the indent level to start the first region at. - /// - public CodeRegion(object textTransformation, int firstIndentLevel) - : this(textTransformation) - { - if (firstIndentLevel < 0) - { - throw new ArgumentException("firstIndentLevel"); - } - - _regionIndentLevel = firstIndentLevel - 1; - } - - /// - /// Starts the begining of a region - /// - public void Begin(string regionName) - { - if (regionName == null) - { - throw new ArgumentNullException("regionName"); - } - - Begin(regionName, 1); - } - - /// - /// Start the begining of a region, indented - /// the numbers of levels specified - /// - public void Begin(string regionName, int levelsToIncreaseIndent) - { - if (regionName == null) - { - throw new ArgumentNullException("regionName"); - } - - _beforeRegionLength = _textTransformation.GenerationEnvironment.Length; - _regionIndentLevel += levelsToIncreaseIndent; - _textTransformation.Write(GetIndent(_regionIndentLevel)); - _textTransformation.WriteLine("#region " + regionName); - _emptyRegionLength = _textTransformation.GenerationEnvironment.Length; - } - - /// - /// Ends a region, or totaly removes it if nothing - /// was generted since the begining of the region. - /// - public void End() - { - End(1); - } - - /// - /// Ends a region, or totaly removes it if nothing - /// was generted since the begining of the region, also outdents - /// the number of levels specified. - /// - public void End(int levelsToDecrease) - { - int indentLevel = _regionIndentLevel; - _regionIndentLevel -= levelsToDecrease; - - if (_emptyRegionLength == _textTransformation.GenerationEnvironment.Length) - _textTransformation.GenerationEnvironment.Length = _beforeRegionLength; - else - { - _textTransformation.WriteLine(String.Empty); - _textTransformation.Write(GetIndent(indentLevel)); - _textTransformation.WriteLine("#endregion"); - _textTransformation.WriteLine(String.Empty); - } - } - - /// - /// Gets the current indent level that the next end region statement will be written - /// at - /// - public int CurrentIndentLevel { get { return _regionIndentLevel; } } - - /// - /// Get a string of spaces equivelent to the number of indents - /// desired. - /// - public static string GetIndent(int indentLevel) - { - if (indentLevel < 0) - { - throw new ArgumentException("indentLevel"); - } - - return String.Empty.PadLeft(indentLevel * STANDARD_INDENT_LENGTH); - } -} - - -/// -/// Responsible for collecting together the actual method parameters -/// and the parameters that need to be sent to the Execute method. -/// -public class FunctionImportParameter -{ - public FunctionParameter Source { get; set; } - public string RawFunctionParameterName { get; set; } - public string FunctionParameterName { get; set; } - public string FunctionParameterType { get; set; } - public string LocalVariableName { get; set; } - public string RawClrTypeName { get; set; } - public string ExecuteParameterName { get; set; } - public string EsqlParameterName { get; set; } - public bool NeedsLocalVariable { get; set; } - public bool IsNullableOfT { get; set; } - - - /// - /// Creates a set of FunctionImportParameter objects from the parameters passed in. - /// - public static IEnumerable Create(IEnumerable parameters, CodeGenerationTools code, MetadataTools ef) - { - if (parameters == null) - { - throw new ArgumentNullException("parameters"); - } - - if (code == null) - { - throw new ArgumentNullException("code"); - } - - if (ef == null) - { - throw new ArgumentNullException("ef"); - } - - UniqueIdentifierService unique = new UniqueIdentifierService(); - List importParameters = new List(); - foreach (FunctionParameter parameter in parameters) - { - FunctionImportParameter importParameter = new FunctionImportParameter(); - importParameter.Source = parameter; - importParameter.RawFunctionParameterName = unique.AdjustIdentifier(code.CamelCase(parameter.Name)); - importParameter.FunctionParameterName = code.Escape(importParameter.RawFunctionParameterName); - if (parameter.Mode == ParameterMode.In) - { - TypeUsage typeUsage = parameter.TypeUsage; - importParameter.NeedsLocalVariable = true; - importParameter.FunctionParameterType = code.GetTypeName(typeUsage); - importParameter.EsqlParameterName = parameter.Name; - Type clrType = ef.UnderlyingClrType(parameter.TypeUsage.EdmType); - importParameter.RawClrTypeName = typeUsage.EdmType is EnumType ? code.GetTypeName(typeUsage.EdmType) : code.Escape(clrType); - importParameter.IsNullableOfT = clrType.IsValueType; - } - else - { - importParameter.NeedsLocalVariable = false; - importParameter.FunctionParameterType = "ObjectParameter"; - importParameter.ExecuteParameterName = importParameter.FunctionParameterName; - } - importParameters.Add(importParameter); - } - - // we save the local parameter uniquification for a second pass to make the visible parameters - // as pretty and sensible as possible - for (int i = 0; i < importParameters.Count; i++) - { - FunctionImportParameter importParameter = importParameters[i]; - if (importParameter.NeedsLocalVariable) - { - importParameter.LocalVariableName = unique.AdjustIdentifier(importParameter.RawFunctionParameterName + "Parameter"); - importParameter.ExecuteParameterName = importParameter.LocalVariableName; - } - } - - return importParameters; - } - - // - // Class to create unique variables within the same scope - // - private sealed class UniqueIdentifierService - { - private readonly HashSet _knownIdentifiers; - - public UniqueIdentifierService() - { - _knownIdentifiers = new HashSet(StringComparer.Ordinal); - } - - /// - /// Given an identifier, makes it unique within the scope by adding - /// a suffix (1, 2, 3, ...), and returns the adjusted identifier. - /// - public string AdjustIdentifier(string identifier) - { - // find a unique name by adding suffix as necessary - int numberOfConflicts = 0; - string adjustedIdentifier = identifier; - - while (!_knownIdentifiers.Add(adjustedIdentifier)) - { - ++numberOfConflicts; - adjustedIdentifier = identifier + numberOfConflicts.ToString(CultureInfo.InvariantCulture); - } - - return adjustedIdentifier; - } - } -} - -/// -/// Responsible for marking the various sections of the generation, -/// so they can be split up into separate files -/// -public class EntityFrameworkTemplateFileManager -{ - /// - /// Creates the VsEntityFrameworkTemplateFileManager if VS is detected, otherwise - /// creates the file system version. - /// - public static EntityFrameworkTemplateFileManager Create(object textTransformation) - { - DynamicTextTransformation transformation = DynamicTextTransformation.Create(textTransformation); - IDynamicHost host = transformation.Host; - -#if !PREPROCESSED_TEMPLATE - var hostServiceProvider = host.AsIServiceProvider(); - - if (hostServiceProvider != null) - { - EnvDTE.DTE dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE)); - - if (dte != null) - { - return new VsEntityFrameworkTemplateFileManager(transformation); - } - } -#endif - return new EntityFrameworkTemplateFileManager(transformation); - } - - private sealed class Block - { - public String Name; - public int Start, Length; - } - - private readonly List files = new List(); - private readonly Block footer = new Block(); - private readonly Block header = new Block(); - private readonly DynamicTextTransformation _textTransformation; - - // reference to the GenerationEnvironment StringBuilder on the - // TextTransformation object - private readonly StringBuilder _generationEnvironment; - - private Block currentBlock; - - /// - /// Initializes an EntityFrameworkTemplateFileManager Instance with the - /// TextTransformation (T4 generated class) that is currently running - /// - private EntityFrameworkTemplateFileManager(object textTransformation) - { - if (textTransformation == null) - { - throw new ArgumentNullException("textTransformation"); - } - - _textTransformation = DynamicTextTransformation.Create(textTransformation); - _generationEnvironment = _textTransformation.GenerationEnvironment; - } - - /// - /// Marks the end of the last file if there was one, and starts a new - /// and marks this point in generation as a new file. - /// - public void StartNewFile(string name) - { - if (name == null) - { - throw new ArgumentNullException("name"); - } - - CurrentBlock = new Block { Name = name }; - } - - public void StartFooter() - { - CurrentBlock = footer; - } - - public void StartHeader() - { - CurrentBlock = header; - } - - public void EndBlock() - { - if (CurrentBlock == null) - { - return; - } - - CurrentBlock.Length = _generationEnvironment.Length - CurrentBlock.Start; - - if (CurrentBlock != header && CurrentBlock != footer) - { - files.Add(CurrentBlock); - } - - currentBlock = null; - } - - /// - /// Produce the template output files. - /// - public virtual IEnumerable Process(bool split = true) - { - var generatedFileNames = new List(); - - if (split) - { - EndBlock(); - - var headerText = _generationEnvironment.ToString(header.Start, header.Length); - var footerText = _generationEnvironment.ToString(footer.Start, footer.Length); - var outputPath = Path.GetDirectoryName(_textTransformation.Host.TemplateFile); - - files.Reverse(); - - foreach (var block in files) - { - var fileName = Path.Combine(outputPath, block.Name); - var content = headerText + _generationEnvironment.ToString(block.Start, block.Length) + footerText; - - generatedFileNames.Add(fileName); - CreateFile(fileName, content); - _generationEnvironment.Remove(block.Start, block.Length); - } - } - - return generatedFileNames; - } - - protected virtual void CreateFile(string fileName, string content) - { - if (IsFileContentDifferent(fileName, content)) - { - File.WriteAllText(fileName, content); - } - } - - protected bool IsFileContentDifferent(String fileName, string newContent) - { - return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent); - } - - private Block CurrentBlock - { - get { return currentBlock; } - set - { - if (CurrentBlock != null) - { - EndBlock(); - } - - if (value != null) - { - value.Start = _generationEnvironment.Length; - } - - currentBlock = value; - } - } - -#if !PREPROCESSED_TEMPLATE - private sealed class VsEntityFrameworkTemplateFileManager : EntityFrameworkTemplateFileManager - { - private EnvDTE.ProjectItem templateProjectItem; - private EnvDTE.DTE dte; - private Action checkOutAction; - private Action> projectSyncAction; - - /// - /// Creates an instance of the VsEntityFrameworkTemplateFileManager class with the IDynamicHost instance - /// - public VsEntityFrameworkTemplateFileManager(object textTemplating) - : base(textTemplating) - { - var hostServiceProvider = _textTransformation.Host.AsIServiceProvider(); - if (hostServiceProvider == null) - { - throw new ArgumentNullException("Could not obtain hostServiceProvider"); - } - - dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE)); - if (dte == null) - { - throw new ArgumentNullException("Could not obtain DTE from host"); - } - - templateProjectItem = dte.Solution.FindProjectItem(_textTransformation.Host.TemplateFile); - - checkOutAction = fileName => dte.SourceControl.CheckOutItem(fileName); - projectSyncAction = keepFileNames => ProjectSync(templateProjectItem, keepFileNames); - } - - public override IEnumerable Process(bool split) - { - if (templateProjectItem.ProjectItems == null) - { - return new List(); - } - - var generatedFileNames = base.Process(split); - - projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null)); - - return generatedFileNames; - } - - protected override void CreateFile(string fileName, string content) - { - if (IsFileContentDifferent(fileName, content)) - { - CheckoutFileIfRequired(fileName); - File.WriteAllText(fileName, content); - } - } - - private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable keepFileNames) - { - var keepFileNameSet = new HashSet(keepFileNames); - var projectFiles = new Dictionary(); - var originalOutput = Path.GetFileNameWithoutExtension(templateProjectItem.FileNames[0]); - - foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) - { - projectFiles.Add(projectItem.FileNames[0], projectItem); - } - - // Remove unused items from the project - foreach (var pair in projectFiles) - { - if (!keepFileNames.Contains(pair.Key) - && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalOutput + ".")) - { - pair.Value.Delete(); - } - } - - // Add missing files to the project - foreach (string fileName in keepFileNameSet) - { - if (!projectFiles.ContainsKey(fileName)) - { - templateProjectItem.ProjectItems.AddFromFile(fileName); - } - } - } - - private void CheckoutFileIfRequired(string fileName) - { - if (dte.SourceControl == null - || !dte.SourceControl.IsItemUnderSCC(fileName) - || dte.SourceControl.IsItemCheckedOut(fileName)) - { - return; - } - - // run on worker thread to prevent T4 calling back into VS - checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null)); - } - } -#endif -} - -/// -/// Responsible creating an instance that can be passed -/// to helper classes that need to access the TextTransformation -/// members. It accesses member by name and signature rather than -/// by type. This is necessary when the -/// template is being used in Preprocessed mode -/// and there is no common known type that can be -/// passed instead -/// -public class DynamicTextTransformation -{ - private object _instance; - IDynamicHost _dynamicHost; - - private readonly MethodInfo _write; - private readonly MethodInfo _writeLine; - private readonly PropertyInfo _generationEnvironment; - private readonly PropertyInfo _errors; - private readonly PropertyInfo _host; - - /// - /// Creates an instance of the DynamicTextTransformation class around the passed in - /// TextTransformation shapped instance passed in, or if the passed in instance - /// already is a DynamicTextTransformation, it casts it and sends it back. - /// - public static DynamicTextTransformation Create(object instance) - { - if (instance == null) - { - throw new ArgumentNullException("instance"); - } - - DynamicTextTransformation textTransformation = instance as DynamicTextTransformation; - if (textTransformation != null) - { - return textTransformation; - } - - return new DynamicTextTransformation(instance); - } - - private DynamicTextTransformation(object instance) - { - _instance = instance; - Type type = _instance.GetType(); - _write = type.GetMethod("Write", new Type[] { typeof(string) }); - _writeLine = type.GetMethod("WriteLine", new Type[] { typeof(string) }); - _generationEnvironment = type.GetProperty("GenerationEnvironment", BindingFlags.Instance | BindingFlags.NonPublic); - _host = type.GetProperty("Host"); - _errors = type.GetProperty("Errors"); - } - - /// - /// Gets the value of the wrapped TextTranformation instance's GenerationEnvironment property - /// - public StringBuilder GenerationEnvironment { get { return (StringBuilder)_generationEnvironment.GetValue(_instance, null); } } - - /// - /// Gets the value of the wrapped TextTranformation instance's Errors property - /// - public System.CodeDom.Compiler.CompilerErrorCollection Errors { get { return (System.CodeDom.Compiler.CompilerErrorCollection)_errors.GetValue(_instance, null); } } - - /// - /// Calls the wrapped TextTranformation instance's Write method. - /// - public void Write(string text) - { - _write.Invoke(_instance, new object[] { text }); - } - - /// - /// Calls the wrapped TextTranformation instance's WriteLine method. - /// - public void WriteLine(string text) - { - _writeLine.Invoke(_instance, new object[] { text }); - } - - /// - /// Gets the value of the wrapped TextTranformation instance's Host property - /// if available (shows up when hostspecific is set to true in the template directive) and returns - /// the appropriate implementation of IDynamicHost - /// - public IDynamicHost Host - { - get - { - if (_dynamicHost == null) - { - if(_host == null) - { - _dynamicHost = new NullHost(); - } - else - { - _dynamicHost = new DynamicHost(_host.GetValue(_instance, null)); - } - } - return _dynamicHost; - } - } -} - - -/// -/// Reponsible for abstracting the use of Host between times -/// when it is available and not -/// -public interface IDynamicHost -{ - /// - /// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue - /// - string ResolveParameterValue(string id, string name, string otherName); - - /// - /// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath - /// - string ResolvePath(string path); - - /// - /// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile - /// - string TemplateFile { get; } - - /// - /// Returns the Host instance cast as an IServiceProvider - /// - IServiceProvider AsIServiceProvider(); -} - -/// -/// Reponsible for implementing the IDynamicHost as a dynamic -/// shape wrapper over the Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost interface -/// rather than type dependent wrapper. We don't use the -/// interface type so that the code can be run in preprocessed mode -/// on a .net framework only installed machine. -/// -public class DynamicHost : IDynamicHost -{ - private readonly object _instance; - private readonly MethodInfo _resolveParameterValue; - private readonly MethodInfo _resolvePath; - private readonly PropertyInfo _templateFile; - - /// - /// Creates an instance of the DynamicHost class around the passed in - /// Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost shapped instance passed in. - /// - public DynamicHost(object instance) - { - _instance = instance; - Type type = _instance.GetType(); - _resolveParameterValue = type.GetMethod("ResolveParameterValue", new Type[] { typeof(string), typeof(string), typeof(string) }); - _resolvePath = type.GetMethod("ResolvePath", new Type[] { typeof(string) }); - _templateFile = type.GetProperty("TemplateFile"); - - } - - /// - /// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue - /// - public string ResolveParameterValue(string id, string name, string otherName) - { - return (string)_resolveParameterValue.Invoke(_instance, new object[] { id, name, otherName }); - } - - /// - /// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath - /// - public string ResolvePath(string path) - { - return (string)_resolvePath.Invoke(_instance, new object[] { path }); - } - - /// - /// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile - /// - public string TemplateFile - { - get - { - return (string)_templateFile.GetValue(_instance, null); - } - } - - /// - /// Returns the Host instance cast as an IServiceProvider - /// - public IServiceProvider AsIServiceProvider() - { - return _instance as IServiceProvider; - } -} - -/// -/// Reponsible for implementing the IDynamicHost when the -/// Host property is not available on the TextTemplating type. The Host -/// property only exists when the hostspecific attribute of the template -/// directive is set to true. -/// -public class NullHost : IDynamicHost -{ - /// - /// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue - /// that simply retuns null. - /// - public string ResolveParameterValue(string id, string name, string otherName) - { - return null; - } - - /// - /// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath - /// that simply retuns the path passed in. - /// - public string ResolvePath(string path) - { - return path; - } - - /// - /// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile - /// that returns null. - /// - public string TemplateFile - { - get - { - return null; - } - } - - /// - /// Returns null. - /// - public IServiceProvider AsIServiceProvider() - { - return null; - } -} - -/// -/// Responsible for encapsulating the constants defined in Metadata -/// -public static class MetadataConstants -{ - public const string CSDL_EXTENSION = ".csdl"; - - public const string CSDL_EDMX_SECTION_NAME = "ConceptualModels"; - public const string CSDL_ROOT_ELEMENT_NAME = "Schema"; - public const string EDM_ANNOTATION_09_02 = "http://schemas.microsoft.com/ado/2009/02/edm/annotation"; - - public const string SSDL_EXTENSION = ".ssdl"; - - public const string SSDL_EDMX_SECTION_NAME = "StorageModels"; - public const string SSDL_ROOT_ELEMENT_NAME = "Schema"; - - public const string MSL_EXTENSION = ".msl"; - - public const string MSL_EDMX_SECTION_NAME = "Mappings"; - public const string MSL_ROOT_ELEMENT_NAME = "Mapping"; - - public const string TT_TEMPLATE_NAME = "TemplateName"; - public const string TT_TEMPLATE_VERSION = "TemplateVersion"; - public const string TT_MINIMUM_ENTITY_FRAMEWORK_VERSION = "MinimumEntityFrameworkVersion"; - - public const string DEFAULT_TEMPLATE_VERSION = "4.0"; - - public static readonly SchemaConstants V1_SCHEMA_CONSTANTS = new SchemaConstants( - "http://schemas.microsoft.com/ado/2007/06/edmx", - "http://schemas.microsoft.com/ado/2006/04/edm", - "http://schemas.microsoft.com/ado/2006/04/edm/ssdl", - "urn:schemas-microsoft-com:windows:storage:mapping:CS", - new Version("3.5")); - - public static readonly SchemaConstants V2_SCHEMA_CONSTANTS = new SchemaConstants( - "http://schemas.microsoft.com/ado/2008/10/edmx", - "http://schemas.microsoft.com/ado/2008/09/edm", - "http://schemas.microsoft.com/ado/2009/02/edm/ssdl", - "http://schemas.microsoft.com/ado/2008/09/mapping/cs", - new Version("4.0")); - - public static readonly SchemaConstants V3_SCHEMA_CONSTANTS = new SchemaConstants( - "http://schemas.microsoft.com/ado/2009/11/edmx", - "http://schemas.microsoft.com/ado/2009/11/edm", - "http://schemas.microsoft.com/ado/2009/11/edm/ssdl", - "http://schemas.microsoft.com/ado/2009/11/mapping/cs", - new Version("5.0")); -} - -public struct SchemaConstants -{ - public SchemaConstants(string edmxNamespace, string csdlNamespace, string ssdlNamespace, string mslNamespace, Version minimumTemplateVersion) : this() - { - EdmxNamespace = edmxNamespace; - CsdlNamespace = csdlNamespace; - SsdlNamespace = ssdlNamespace; - MslNamespace = mslNamespace; - MinimumTemplateVersion = minimumTemplateVersion; - } - - public string EdmxNamespace { get; private set; } - public string CsdlNamespace { get; private set; } - public string SsdlNamespace { get; private set; } - public string MslNamespace { get; private set; } - public Version MinimumTemplateVersion { get; private set; } -} +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Entity.Design" #> +<#@ assembly name="System.Xml" #> +<#@ assembly name="System.Xml.Linq"#> +<#@ assembly name="EnvDTE"#> +<#@ import namespace="System" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.IO" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Data.Objects" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Xml" #> +<#@ import namespace="System.Xml.Linq" #> +<#@ import namespace="System.Globalization" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="System.Data.Metadata.Edm" #> +<#@ import namespace="System.Data.Mapping" #> +<#@ import namespace="System.Data.Entity.Design" #> +<#@ import namespace="System.CodeDom" #> +<#@ import namespace="System.CodeDom.Compiler" #> +<#@ import namespace="Microsoft.CSharp"#> +<#@ import namespace="System.Text"#> +<#+ +// Copyright (c) Microsoft Corporation. All rights reserved. + +public static Dictionary TemplateMetadata = new Dictionary(); + +/// +/// Responsible for helping to create source code that is +/// correctly formated and functional +/// +public class CodeGenerationTools +{ + private readonly DynamicTextTransformation _textTransformation; + private readonly CSharpCodeProvider _code; + private readonly MetadataTools _ef; + + /// + /// Initializes a new CodeGenerationTools object with the TextTransformation (T4 generated class) + /// that is currently running + /// + public CodeGenerationTools(object textTransformation) + { + if (textTransformation == null) + { + throw new ArgumentNullException("textTransformation"); + } + + _textTransformation = DynamicTextTransformation.Create(textTransformation); + _code = new CSharpCodeProvider(); + _ef = new MetadataTools(_textTransformation); + FullyQualifySystemTypes = false; + CamelCaseFields = true; + } + + /// + /// When true, all types that are not being generated + /// are fully qualified to keep them from conflicting with + /// types that are being generated. Useful when you have + /// something like a type being generated named System. + /// + /// Default is false. + /// + public bool FullyQualifySystemTypes { get; set; } + + /// + /// When true, the field names are Camel Cased, + /// otherwise they will preserve the case they + /// start with. + /// + /// Default is true. + /// + public bool CamelCaseFields { get; set; } + + /// + /// Returns the NamespaceName suggested by VS if running inside VS. Otherwise, returns + /// null. + /// + public string VsNamespaceSuggestion() + { + string suggestion = _textTransformation.Host.ResolveParameterValue("directiveId", "namespaceDirectiveProcessor", "namespaceHint"); + if (String.IsNullOrEmpty(suggestion)) + { + return null; + } + + return suggestion; + } + + /// + /// Returns a string that is safe for use as an identifier in C#. + /// Keywords are escaped. + /// + public string Escape(string name) + { + if (name == null) + { + return null; + } + + return _code.CreateEscapedIdentifier(name); + } + + /// + /// Returns the name of the TypeUsage's EdmType that is safe for + /// use as an identifier. + /// + public string Escape(TypeUsage typeUsage) + { + if (typeUsage == null) + { + return null; + } + + if (typeUsage.EdmType is ComplexType || + typeUsage.EdmType is EntityType) + { + return Escape(typeUsage.EdmType.Name); + } + else if (typeUsage.EdmType is SimpleType) + { + Type clrType = _ef.UnderlyingClrType(typeUsage.EdmType); + string typeName = typeUsage.EdmType is EnumType ? Escape(typeUsage.EdmType.Name) : Escape(clrType); + if (clrType.IsValueType && _ef.IsNullable(typeUsage)) + { + return String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName); + } + + return typeName; + } + else if (typeUsage.EdmType is CollectionType) + { + return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", Escape(((CollectionType)typeUsage.EdmType).TypeUsage)); + } + + throw new ArgumentException("typeUsage"); + } + + /// + /// Returns the name of the EdmMember that is safe for + /// use as an identifier. + /// + public string Escape(EdmMember member) + { + if (member == null) + { + return null; + } + + return Escape(member.Name); + } + + /// + /// Returns the name of the EdmType that is safe for + /// use as an identifier. + /// + public string Escape(EdmType type) + { + if (type == null) + { + return null; + } + + return Escape(type.Name); + } + + /// + /// Returns the name of the EdmFunction that is safe for + /// use as an identifier. + /// + public string Escape(EdmFunction function) + { + if (function == null) + { + return null; + } + + return Escape(function.Name); + } + + /// + /// Returns the name of the EnumMember that is safe for + /// use as an identifier. + /// + public string Escape(EnumMember member) + { + if (member == null) + { + return null; + } + + return Escape(member.Name); + } + + /// + /// Returns the name of the EntityContainer that is safe for + /// use as an identifier. + /// + public string Escape(EntityContainer container) + { + if (container == null) + { + return null; + } + + return Escape(container.Name); + } + + /// + /// Returns the name of the EntitySet that is safe for + /// use as an identifier. + /// + public string Escape(EntitySet set) + { + if (set == null) + { + return null; + } + + return Escape(set.Name); + } + + /// + /// Returns the name of the StructuralType that is safe for + /// use as an identifier. + /// + public string Escape(StructuralType type) + { + if (type == null) + { + return null; + } + + return Escape(type.Name); + } + + /// + /// Returns the NamespaceName with each segment safe to + /// use as an identifier. + /// + public string EscapeNamespace(string namespaceName) + { + if (String.IsNullOrEmpty(namespaceName)) + { + return namespaceName; + } + + string[] parts = namespaceName.Split('.'); + namespaceName = String.Empty; + foreach (string part in parts) + { + if (namespaceName != String.Empty) + { + namespaceName += "."; + } + + namespaceName += Escape(part); + } + + return namespaceName; + } + + /// + /// Returns the name of the EdmMember formatted for + /// use as a field identifier. + /// + /// This method changes behavior based on the CamelCaseFields + /// setting. + /// + public string FieldName(EdmMember member) + { + if (member == null) + { + return null; + } + + return FieldName(member.Name); + } + + /// + /// Returns the name of the EntitySet formatted for + /// use as a field identifier. + /// + /// This method changes behavior based on the CamelCaseFields + /// setting. + /// + public string FieldName(EntitySet set) + { + if (set == null) + { + return null; + } + + return FieldName(set.Name); + + } + + private string FieldName(string name) + { + if (CamelCaseFields) + { + return "_" + CamelCase(name); + } + else + { + return "_" + name; + } + } + + /// + /// Returns the name of the Type object formatted for + /// use in source code. + /// + /// This method changes behavior based on the FullyQualifySystemTypes + /// setting. + /// + public string Escape(Type clrType) + { + return Escape(clrType, FullyQualifySystemTypes); + } + + /// + /// Returns the name of the Type object formatted for + /// use in source code. + /// + public string Escape(Type clrType, bool fullyQualifySystemTypes) + { + if(clrType == null) + { + return null; + } + + string typeName; + if (fullyQualifySystemTypes) + { + typeName = "global::" + clrType.FullName; + } + else + { + typeName = _code.GetTypeOutput(new CodeTypeReference(clrType)); + } + return typeName; + } + + /// + /// Returns the abstract option if the entity is Abstract, otherwise returns String.Empty + /// + public string AbstractOption(EntityType entity) + { + if (entity.Abstract) + { + return "abstract"; + } + return String.Empty; + } + + /// + /// Returns the passed in identifier with the first letter changed to lowercase + /// + public string CamelCase(string identifier) + { + if (String.IsNullOrEmpty(identifier)) + { + return identifier; + } + + if (identifier.Length == 1) + { + return identifier[0].ToString(CultureInfo.InvariantCulture).ToLowerInvariant(); + } + + return identifier[0].ToString(CultureInfo.InvariantCulture).ToLowerInvariant() + identifier.Substring(1); + } + + /// + /// If the value parameter is null or empty an empty string is returned, + /// otherwise it retuns value with a single space concatenated on the end. + /// + public string SpaceAfter(string value) + { + return StringAfter(value, " "); + } + + /// + /// If the value parameter is null or empty an empty string is returned, + /// otherwise it retuns value with a single space concatenated on the end. + /// + public string SpaceBefore(string value) + { + return StringBefore(" ", value); + } + + /// + /// If the value parameter is null or empty an empty string is returned, + /// otherwise it retuns value with append concatenated on the end. + /// + public string StringAfter(string value, string append) + { + if (String.IsNullOrEmpty(value)) + { + return String.Empty; + } + + return value + append; + } + + /// + /// If the value parameter is null or empty an empty string is returned, + /// otherwise it retuns value with prepend concatenated on the front. + /// + public string StringBefore(string prepend, string value) + { + if (String.IsNullOrEmpty(value)) + { + return String.Empty; + } + + return prepend + value; + } + + /// + /// Returns false and shows an error if the supplied type names aren't case-insensitively unique, + /// otherwise returns true. + /// + public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) + { + return VerifyCaseInsensitiveUniqueness(types, t => string.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CaseInsensitiveTypeConflict"), t), sourceFile); + } + + /// + /// Returns false and shows an error if the supplied strings aren't case-insensitively unique, + /// otherwise returns true. + /// + private bool VerifyCaseInsensitiveUniqueness(IEnumerable items, Func formatMessage, string sourceFile) + { + HashSet hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); + foreach (string item in items) + { + if (!hash.Add(item)) + { + _textTransformation.Errors.Add(new System.CodeDom.Compiler.CompilerError(sourceFile, -1, -1, "6023", formatMessage(item))); + return false; + } + } + return true; + } + + /// + /// Returns the names of the items in the supplied collection that correspond to O-Space types. + /// + public IEnumerable GetAllGlobalItems(EdmItemCollection itemCollection) + { + return itemCollection.GetItems().Where(i => i is EntityType || i is ComplexType || i is EnumType || i is EntityContainer).Select(g => GetGlobalItemName(g)); + } + + /// + /// Returns the name of the supplied GlobalItem. + /// + public string GetGlobalItemName(GlobalItem item) + { + if (item is EdmType) + { + return ((EdmType)item).Name; + } + else + { + return ((EntityContainer)item).Name; + } + } + + /// + /// Retuns as full of a name as possible, if a namespace is provided + /// the namespace and name are combined with a period, otherwise just + /// the name is returned. + /// + public string CreateFullName(string namespaceName, string name) + { + if (String.IsNullOrEmpty(namespaceName)) + { + return name; + } + + return namespaceName + "." + name; + } + + /// + /// Retuns a literal representing the supplied value. + /// + public string CreateLiteral(object value) + { + if (value == null) + { + return string.Empty; + } + + Type type = value.GetType(); + if (type.IsEnum) + { + return type.FullName + "." + value.ToString(); + } + if (type == typeof(Guid)) + { + return string.Format(CultureInfo.InvariantCulture, "new Guid(\"{0}\")", + ((Guid)value).ToString("D", CultureInfo.InvariantCulture)); + } + else if (type == typeof(DateTime)) + { + return string.Format(CultureInfo.InvariantCulture, "new DateTime({0}, DateTimeKind.Unspecified)", + ((DateTime)value).Ticks); + } + else if (type == typeof(byte[])) + { + var arrayInit = string.Join(", ", ((byte[])value).Select(b => b.ToString(CultureInfo.InvariantCulture)).ToArray()); + return string.Format(CultureInfo.InvariantCulture, "new Byte[] {{{0}}}", arrayInit); + } + else if (type == typeof(DateTimeOffset)) + { + var dto = (DateTimeOffset)value; + return string.Format(CultureInfo.InvariantCulture, "new DateTimeOffset({0}, new TimeSpan({1}))", + dto.Ticks, dto.Offset.Ticks); + } + else if (type == typeof(TimeSpan)) + { + return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", + ((TimeSpan)value).Ticks); + } + + var expression = new CodePrimitiveExpression(value); + var writer = new StringWriter(); + CSharpCodeProvider code = new CSharpCodeProvider(); + code.GenerateCodeFromExpression(expression, writer, new CodeGeneratorOptions()); + return writer.ToString(); + } + + /// + /// Returns a resource string from the System.Data.Entity.Design assembly. + /// + public static string GetResourceString(string resourceName, CultureInfo culture = null) + { + if(_resourceManager == null) + { + _resourceManager = new System.Resources.ResourceManager("System.Data.Entity.Design", + typeof(System.Data.Entity.Design.MetadataItemCollectionFactory).Assembly); + } + + return _resourceManager.GetString(resourceName, culture); + } + static System.Resources.ResourceManager _resourceManager; + + private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; + + /// + /// Gets the entity, complex, or enum types for which code should be generated from the given item collection. + /// Any types for which an ExternalTypeName annotation has been applied in the conceptual model + /// metadata (CSDL) are filtered out of the returned list. + /// + /// The type of item to return. + /// The item collection to look in. + /// The items to generate. + public IEnumerable GetItemsToGenerate(ItemCollection itemCollection) where T: GlobalItem + { + return itemCollection.GetItems().Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)); + } + + /// + /// Returns the escaped type name to use for the given usage of a c-space type in o-space. This might be + /// an external type name if the ExternalTypeName annotation has been specified in the + /// conceptual model metadata (CSDL). + /// + /// The c-space type usage to get a name for. + /// The type name to use. + public string GetTypeName(TypeUsage typeUsage) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); + } + + /// + /// Returns the escaped type name to use for the given c-space type in o-space. This might be + /// an external type name if the ExternalTypeName annotation has been specified in the + /// conceptual model metadata (CSDL). + /// + /// The c-space type to get a name for. + /// The type name to use. + public string GetTypeName(EdmType edmType) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: null); + } + + /// + /// Returns the escaped type name to use for the given usage of an c-space type in o-space. This might be + /// an external type name if the ExternalTypeName annotation has been specified in the + /// conceptual model metadata (CSDL). + /// + /// The c-space type usage to get a name for. + /// If not null and the type's namespace does not match this namespace, then a + /// fully qualified name will be returned. + /// The type name to use. + public string GetTypeName(TypeUsage typeUsage, string modelNamespace) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); + } + + /// + /// Returns the escaped type name to use for the given c-space type in o-space. This might be + /// an external type name if the ExternalTypeName annotation has been specified in the + /// conceptual model metadata (CSDL). + /// + /// The c-space type to get a name for. + /// If not null and the type's namespace does not match this namespace, then a + /// fully qualified name will be returned. + /// The type name to use. + public string GetTypeName(EdmType edmType, string modelNamespace) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); + } + + /// + /// Returns the escaped type name to use for the given c-space type in o-space. This might be + /// an external type name if the ExternalTypeName annotation has been specified in the + /// conceptual model metadata (CSDL). + /// + /// The c-space type to get a name for. + /// Set this to true for nullable usage of this type. + /// If not null and the type's namespace does not match this namespace, then a + /// fully qualified name will be returned. + /// The type name to use. + private string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) + { + if (edmType == null) + { + return null; + } + + var collectionType = edmType as CollectionType; + if (collectionType != null) + { + return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); + } + + // Try to get an external type name, and if that is null, then try to get escape the name from metadata, + // possibly namespace-qualifying it. + var typeName = Escape(edmType.MetadataProperties + .Where(p => p.Name == ExternalTypeNameAttributeName) + .Select(p => (string)p.Value) + .FirstOrDefault()) + ?? + (modelNamespace != null && edmType.NamespaceName != modelNamespace ? + CreateFullName(EscapeNamespace(edmType.NamespaceName), Escape(edmType)) : + Escape(edmType)); + + if (edmType is StructuralType) + { + return typeName; + } + + if (edmType is SimpleType) + { + var clrType = _ef.UnderlyingClrType(edmType); + if (!(edmType is EnumType)) + { + typeName = Escape(clrType); + } + + return clrType.IsValueType && isNullable == true ? + String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : + typeName; + } + + throw new ArgumentException("typeUsage"); + } +} + +/// +/// Responsible for making the Entity Framework Metadata more +/// accessible for code generation. +/// +public class MetadataTools +{ + private readonly DynamicTextTransformation _textTransformation; + + /// + /// Initializes an MetadataTools Instance with the + /// TextTransformation (T4 generated class) that is currently running + /// + public MetadataTools(object textTransformation) + { + if (textTransformation == null) + { + throw new ArgumentNullException("textTransformation"); + } + + _textTransformation = DynamicTextTransformation.Create(textTransformation); + } + + /// + /// This method returns the underlying CLR type of the o-space type corresponding to the supplied + /// Note that for an enum type this means that the type backing the enum will be returned, not the enum type itself. + /// + public Type ClrType(TypeUsage typeUsage) + { + return UnderlyingClrType(typeUsage.EdmType); + } + + /// + /// This method returns the underlying CLR type given the c-space type. + /// Note that for an enum type this means that the type backing the enum will be returned, not the enum type itself. + /// + public Type UnderlyingClrType(EdmType edmType) + { + var primitiveType = edmType as PrimitiveType; + if (primitiveType != null) + { + return primitiveType.ClrEquivalentType; + } + + var enumType = edmType as EnumType; + if (enumType != null) + { + return enumType.UnderlyingType.ClrEquivalentType; + } + + return typeof(object); + } + + /// + /// True if the EdmProperty is a key of its DeclaringType, False otherwise. + /// + public bool IsKey(EdmProperty property) + { + if (property != null && property.DeclaringType.BuiltInTypeKind == BuiltInTypeKind.EntityType) + { + return ((EntityType)property.DeclaringType).KeyMembers.Contains(property); + } + + return false; + } + + /// + /// True if the EdmProperty TypeUsage is Nullable, False otherwise. + /// + public bool IsNullable(EdmProperty property) + { + return property != null && IsNullable(property.TypeUsage); + } + + /// + /// True if the TypeUsage is Nullable, False otherwise. + /// + public bool IsNullable(TypeUsage typeUsage) + { + Facet nullableFacet = null; + if (typeUsage != null && + typeUsage.Facets.TryGetValue("Nullable", true, out nullableFacet)) + { + return (bool)nullableFacet.Value; + } + + return false; + } + + /// + /// If the passed in TypeUsage represents a collection this method returns final element + /// type of the collection, otherwise it returns the value passed in. + /// + public TypeUsage GetElementType(TypeUsage typeUsage) + { + if (typeUsage == null) + { + return null; + } + + if (typeUsage.EdmType is CollectionType) + { + return GetElementType(((CollectionType)typeUsage.EdmType).TypeUsage); + } + else + { + return typeUsage; + } + } + + /// + /// Returns the NavigationProperty that is the other end of the same association set if it is + /// available, otherwise it returns null. + /// + public NavigationProperty Inverse(NavigationProperty navProperty) + { + if(navProperty == null) + { + return null; + } + + EntityType toEntity = navProperty.ToEndMember.GetEntityType(); + return toEntity.NavigationProperties + .SingleOrDefault(n => Object.ReferenceEquals(n.RelationshipType, navProperty.RelationshipType) && !Object.ReferenceEquals(n, navProperty)); + } + + /// + /// Given a property on the dependent end of a referential constraint, returns the corresponding property on the principal end. + /// Requires: The association has a referential constraint, and the specified dependentProperty is one of the properties on the dependent end. + /// + public EdmProperty GetCorrespondingPrincipalProperty(NavigationProperty navProperty, EdmProperty dependentProperty) + { + if (navProperty == null) + { + throw new ArgumentNullException("navProperty"); + } + + if (dependentProperty == null) + { + throw new ArgumentNullException("dependentProperty"); + } + + ReadOnlyMetadataCollection fromProperties = GetPrincipalProperties(navProperty); + ReadOnlyMetadataCollection toProperties = GetDependentProperties(navProperty); + return fromProperties[toProperties.IndexOf(dependentProperty)]; + } + + /// + /// Given a property on the principal end of a referential constraint, returns the corresponding property on the dependent end. + /// Requires: The association has a referential constraint, and the specified principalProperty is one of the properties on the principal end. + /// + public EdmProperty GetCorrespondingDependentProperty(NavigationProperty navProperty, EdmProperty principalProperty) + { + if (navProperty == null) + { + throw new ArgumentNullException("navProperty"); + } + + if (principalProperty == null) + { + throw new ArgumentNullException("principalProperty"); + } + + ReadOnlyMetadataCollection fromProperties = GetPrincipalProperties(navProperty); + ReadOnlyMetadataCollection toProperties = GetDependentProperties(navProperty); + return toProperties[fromProperties.IndexOf(principalProperty)]; + } + + /// + /// Gets the collection of properties that are on the principal end of a referential constraint for the specified navigation property. + /// Requires: The association has a referential constraint. + /// + public ReadOnlyMetadataCollection GetPrincipalProperties(NavigationProperty navProperty) + { + if (navProperty == null) + { + throw new ArgumentNullException("navProperty"); + } + + return ((AssociationType)navProperty.RelationshipType).ReferentialConstraints[0].FromProperties; + } + + /// + /// Gets the collection of properties that are on the dependent end of a referential constraint for the specified navigation property. + /// Requires: The association has a referential constraint. + /// + public ReadOnlyMetadataCollection GetDependentProperties(NavigationProperty navProperty) + { + if (navProperty == null) + { + throw new ArgumentNullException("navProperty"); + } + + return ((AssociationType)navProperty.RelationshipType).ReferentialConstraints[0].ToProperties; + } + + /// + /// True if this entity type requires the HandleCascadeDelete method defined and the method has + /// not been defined on any base type + /// + public bool NeedsHandleCascadeDeleteMethod(ItemCollection itemCollection, EntityType entity) + { + bool needsMethod = ContainsCascadeDeleteAssociation(itemCollection, entity); + // Check to make sure no base types have already declared this method + EntityType baseType = entity.BaseType as EntityType; + while(needsMethod && baseType != null) + { + needsMethod = !ContainsCascadeDeleteAssociation(itemCollection, baseType); + baseType = baseType.BaseType as EntityType; + } + return needsMethod; + } + + /// + /// True if this entity type participates in any relationships where the other end has an OnDelete + /// cascade delete defined, or if it is the dependent in any identifying relationships + /// + private bool ContainsCascadeDeleteAssociation(ItemCollection itemCollection, EntityType entity) + { + return itemCollection.GetItems().Where(a => + ((RefType)a.AssociationEndMembers[0].TypeUsage.EdmType).ElementType == entity && IsCascadeDeletePrincipal(a.AssociationEndMembers[1]) || + ((RefType)a.AssociationEndMembers[1].TypeUsage.EdmType).ElementType == entity && IsCascadeDeletePrincipal(a.AssociationEndMembers[0])).Any(); + } + + /// + /// True if the source end of the specified navigation property is the principal in an identifying relationship. + /// or if the source end has cascade delete defined. + /// + public bool IsCascadeDeletePrincipal(NavigationProperty navProperty) + { + if (navProperty == null) + { + throw new ArgumentNullException("navProperty"); + } + + return IsCascadeDeletePrincipal((AssociationEndMember)navProperty.FromEndMember); + } + + /// + /// True if the specified association end is the principal in an identifying relationship. + /// or if the association end has cascade delete defined. + /// + public bool IsCascadeDeletePrincipal(AssociationEndMember associationEnd) + { + if (associationEnd == null) + { + throw new ArgumentNullException("associationEnd"); + } + + return associationEnd.DeleteBehavior == OperationAction.Cascade || IsPrincipalEndOfIdentifyingRelationship(associationEnd); + } + + /// + /// True if the specified association end is the principal end in an identifying relationship. + /// In order to be an identifying relationship, the association must have a referential constraint where all of the dependent properties are part of the dependent type's primary key. + /// + public bool IsPrincipalEndOfIdentifyingRelationship(AssociationEndMember associationEnd) + { + if (associationEnd == null) + { + throw new ArgumentNullException("associationEnd"); + } + + ReferentialConstraint refConstraint = ((AssociationType)associationEnd.DeclaringType).ReferentialConstraints.Where(rc => rc.FromRole == associationEnd).SingleOrDefault(); + if (refConstraint != null) + { + EntityType entity = refConstraint.ToRole.GetEntityType(); + return !refConstraint.ToProperties.Where(tp => !entity.KeyMembers.Contains(tp)).Any(); + } + return false; + } + + /// + /// True if the specified association type is an identifying relationship. + /// In order to be an identifying relationship, the association must have a referential constraint where all of the dependent properties are part of the dependent type's primary key. + /// + public bool IsIdentifyingRelationship(AssociationType association) + { + if (association == null) + { + throw new ArgumentNullException("association"); + } + + return IsPrincipalEndOfIdentifyingRelationship(association.AssociationEndMembers[0]) || IsPrincipalEndOfIdentifyingRelationship(association.AssociationEndMembers[1]); + } + + /// + /// requires: firstType is not null + /// effects: if secondType is among the base types of the firstType, return true, + /// otherwise returns false. + /// when firstType is same as the secondType, return false. + /// + public bool IsSubtypeOf(EdmType firstType, EdmType secondType) + { + if (secondType == null) + { + return false; + } + + // walk up firstType hierarchy list + for (EdmType t = firstType.BaseType; t != null; t = t.BaseType) + { + if (t == secondType) + return true; + } + return false; + } + + /// + /// Returns the subtype of the EntityType in the current itemCollection + /// + public IEnumerable GetSubtypesOf(EntityType type, ItemCollection itemCollection, bool includeAbstractTypes) + { + if (type != null) + { + IEnumerable typesInCollection = itemCollection.GetItems(); + foreach (EntityType typeInCollection in typesInCollection) + { + if (type.Equals(typeInCollection) == false && this.IsSubtypeOf(typeInCollection, type)) + { + if ( includeAbstractTypes || !typeInCollection.Abstract) + { + yield return typeInCollection; + } + } + } + } + } + + public static bool TryGetStringMetadataPropertySetting(MetadataItem item, string propertyName, out string value) + { + value = null; + MetadataProperty property = item.MetadataProperties.FirstOrDefault(p => p.Name == propertyName); + if (property != null) + { + value = (string)property.Value; + } + return value != null; + } +} + +/// +/// Responsible for loading an EdmItemCollection from a .edmx file or .csdl files +/// +public class MetadataLoader +{ + private readonly DynamicTextTransformation _textTransformation; + + /// + /// Initializes an MetadataLoader Instance with the + /// TextTransformation (T4 generated class) that is currently running + /// + public MetadataLoader(object textTransformation) + { + if (textTransformation == null) + { + throw new ArgumentNullException("textTransformation"); + } + + _textTransformation = DynamicTextTransformation.Create(textTransformation); + } + + /// + /// Load the metadata for Edm, Store, and Mapping collections and register them + /// with a new MetadataWorkspace, returns false if any of the parts can't be + /// created, some of the ItemCollections may be registered and usable even if false is + /// returned + /// + public bool TryLoadAllMetadata(string inputFile, out MetadataWorkspace metadataWorkspace) + { + metadataWorkspace = new MetadataWorkspace(); + + EdmItemCollection edmItemCollection = CreateEdmItemCollection(inputFile); + metadataWorkspace.RegisterItemCollection(edmItemCollection); + + StoreItemCollection storeItemCollection = null; + if (TryCreateStoreItemCollection(inputFile, out storeItemCollection)) + { + StorageMappingItemCollection storageMappingItemCollection = null; + if (TryCreateStorageMappingItemCollection(inputFile, edmItemCollection, storeItemCollection, out storageMappingItemCollection)) + { + metadataWorkspace.RegisterItemCollection(storeItemCollection); + metadataWorkspace.RegisterItemCollection(storageMappingItemCollection); + return true; + } + } + + return false; + } + + /// + /// Create an EdmItemCollection loaded with the metadata provided + /// + public EdmItemCollection CreateEdmItemCollection(string sourcePath, params string[] referenceSchemas) + { + EdmItemCollection edmItemCollection; + if(TryCreateEdmItemCollection(sourcePath, referenceSchemas, out edmItemCollection)) + { + return edmItemCollection; + } + + return new EdmItemCollection(); + } + + /// + /// Attempts to create a EdmItemCollection from the specified metadata file + /// + public bool TryCreateEdmItemCollection(string sourcePath, out EdmItemCollection edmItemCollection) + { + return TryCreateEdmItemCollection(sourcePath, null, out edmItemCollection); + } + + /// + /// Attempts to create a EdmItemCollection from the specified metadata file + /// + public bool TryCreateEdmItemCollection(string sourcePath, string[] referenceSchemas, out EdmItemCollection edmItemCollection) + { + edmItemCollection = null; + + if (!ValidateInputPath(sourcePath, _textTransformation)) + { + return false; + } + + if (referenceSchemas == null) + { + referenceSchemas = new string[0]; + } + + ItemCollection itemCollection = null; + sourcePath = _textTransformation.Host.ResolvePath(sourcePath); + EdmItemCollectionBuilder collectionBuilder = new EdmItemCollectionBuilder(_textTransformation, referenceSchemas.Select(s => _textTransformation.Host.ResolvePath(s)).Where(s => s != sourcePath)); + if (collectionBuilder.TryCreateItemCollection(sourcePath, out itemCollection)) + { + edmItemCollection = (EdmItemCollection)itemCollection; + } + + return edmItemCollection != null; + } + + /// + /// Attempts to create a StoreItemCollection from the specified metadata file + /// + public bool TryCreateStoreItemCollection(string sourcePath, out StoreItemCollection storeItemCollection) + { + storeItemCollection = null; + + if (!ValidateInputPath(sourcePath, _textTransformation)) + { + return false; + } + + ItemCollection itemCollection = null; + StoreItemCollectionBuilder collectionBuilder = new StoreItemCollectionBuilder(_textTransformation); + if (collectionBuilder.TryCreateItemCollection(_textTransformation.Host.ResolvePath(sourcePath), out itemCollection)) + { + storeItemCollection = (StoreItemCollection)itemCollection; + } + return storeItemCollection != null; + } + + /// + /// Attempts to create a StorageMappingItemCollection from the specified metadata file, EdmItemCollection, and StoreItemCollection + /// + public bool TryCreateStorageMappingItemCollection(string sourcePath, EdmItemCollection edmItemCollection, StoreItemCollection storeItemCollection, out StorageMappingItemCollection storageMappingItemCollection) + { + storageMappingItemCollection = null; + + if (!ValidateInputPath(sourcePath, _textTransformation)) + { + return false; + } + + if (edmItemCollection == null) + { + throw new ArgumentNullException("edmItemCollection"); + } + + if (storeItemCollection == null) + { + throw new ArgumentNullException("storeItemCollection"); + } + + ItemCollection itemCollection = null; + StorageMappingItemCollectionBuilder collectionBuilder = new StorageMappingItemCollectionBuilder(_textTransformation, edmItemCollection, storeItemCollection); + if (collectionBuilder.TryCreateItemCollection(_textTransformation.Host.ResolvePath(sourcePath), out itemCollection)) + { + storageMappingItemCollection = (StorageMappingItemCollection)itemCollection; + } + return storageMappingItemCollection != null; + } + + /// + /// Gets the Model Namespace from the provided schema file. + /// + public string GetModelNamespace(string sourcePath) + { + if (!ValidateInputPath(sourcePath, _textTransformation)) + { + return String.Empty; + } + + EdmItemCollectionBuilder builder = new EdmItemCollectionBuilder(_textTransformation); + XElement model; + if(builder.TryLoadRootElement(_textTransformation.Host.ResolvePath(sourcePath), out model)) + { + XAttribute attribute = model.Attribute("Namespace"); + if (attribute != null) + { + return attribute.Value; + } + } + + return String.Empty; + } + + /// + /// Returns true if the specified file path is valid + /// + private static bool ValidateInputPath(string sourcePath, DynamicTextTransformation textTransformation) + { + if (String.IsNullOrEmpty(sourcePath)) + { + throw new ArgumentException("sourcePath"); + } + + if(sourcePath == "$edmxInputFile$") + { + textTransformation.Errors.Add(new CompilerError(textTransformation.Host.TemplateFile ?? CodeGenerationTools.GetResourceString("Template_CurrentlyRunningTemplate"), -1, -1, string.Empty, + CodeGenerationTools.GetResourceString("Template_ReplaceVsItemTemplateToken"))); + return false; + } + + return true; + } + + /// + /// Base class for ItemCollectionBuilder classes that + /// loads the specific types of metadata + /// + private abstract class ItemCollectionBuilder + { + private readonly DynamicTextTransformation _textTransformation; + private readonly string _fileExtension; + private readonly string _edmxSectionName; + private readonly string _rootElementName; + + /// + /// FileExtension for individual (non-edmx) metadata file for this + /// specific ItemCollection type + /// + public string FileExtension + { + get { return _fileExtension; } + } + + /// + /// The name of the XmlElement in the .edmx element + /// to find this ItemCollection's metadata + /// + public string EdmxSectionName + { + get { return _edmxSectionName; } + } + + /// + /// The name of the root element of this ItemCollection's metadata + /// + public string RootElementName + { + get { return _rootElementName; } + } + + /// + /// Method to build the appropriate ItemCollection + /// + protected abstract ItemCollection CreateItemCollection(IEnumerable readers, out IList errors); + + /// + /// Ctor to setup the ItemCollectionBuilder members + /// + protected ItemCollectionBuilder(DynamicTextTransformation textTransformation, string fileExtension, string edmxSectionName, string rootElementName) + { + _textTransformation = textTransformation; + _fileExtension = fileExtension; + _edmxSectionName = edmxSectionName; + _rootElementName = rootElementName; + } + + /// + /// Selects a namespace from the supplied constants. + /// + protected abstract string GetNamespace(SchemaConstants constants); + + /// + /// Try to create an ItemCollection loaded with the metadata provided + /// + public bool TryCreateItemCollection(string sourcePath, out ItemCollection itemCollection) + { + itemCollection = null; + + if (!ValidateInputPath(sourcePath, _textTransformation)) + { + return false; + } + + XElement schemaElement = null; + if (TryLoadRootElement(sourcePath, out schemaElement)) + { + List readers = new List(); + try + { + readers.Add(schemaElement.CreateReader()); + IList errors = null; + + ItemCollection tempItemCollection = CreateItemCollection(readers, out errors); + if (ProcessErrors(errors, sourcePath)) + { + return false; + } + + itemCollection = tempItemCollection; + return true; + } + finally + { + foreach (XmlReader reader in readers) + { + ((IDisposable)reader).Dispose(); + } + } + } + + return false; + } + + /// + /// Tries to load the root element from the metadata file provided + /// + public bool TryLoadRootElement(string sourcePath, out XElement schemaElement) + { + schemaElement = null; + string extension = Path.GetExtension(sourcePath); + if (extension.Equals(".edmx", StringComparison.InvariantCultureIgnoreCase)) + { + return TryLoadRootElementFromEdmx(sourcePath, out schemaElement); + } + else if(extension.Equals(FileExtension, StringComparison.InvariantCultureIgnoreCase)) + { + // load from single metadata file (.csdl, .ssdl, or .msl) + schemaElement = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); + return true; + } + + return false; + } + + /// + /// Tries to load the root element from the provided edmxDocument + /// + private bool TryLoadRootElementFromEdmx(XElement edmxDocument, SchemaConstants schemaConstants, string sectionName, string rootElementName, out XElement rootElement) + { + rootElement = null; + + XNamespace edmxNs = schemaConstants.EdmxNamespace; + XNamespace sectionNs = GetNamespace(schemaConstants); + + XElement runtime = edmxDocument.Element(edmxNs + "Runtime"); + if (runtime == null) + { + return false; + } + + XElement section = runtime.Element(edmxNs + sectionName); + if (section == null) + { + return false; + } + + string templateVersion; + + if (!TemplateMetadata.TryGetValue(MetadataConstants.TT_TEMPLATE_VERSION, out templateVersion)) + { + templateVersion = MetadataConstants.DEFAULT_TEMPLATE_VERSION; + } + + if (schemaConstants.MinimumTemplateVersion > new Version(templateVersion)) + { + _textTransformation.Errors.Add(new CompilerError( + _textTransformation.Host.TemplateFile ?? CodeGenerationTools.GetResourceString("Template_CurrentlyRunningTemplate"), -1, -1, string.Empty, + CodeGenerationTools.GetResourceString("Template_UnsupportedSchema")) + {IsWarning = true}); + } + + rootElement = section.Element(sectionNs + rootElementName); + return rootElement != null; + } + + /// + /// Tries to load the root element from the provided .edmx metadata file + /// + private bool TryLoadRootElementFromEdmx(string edmxPath, out XElement rootElement) + { + rootElement = null; + + XElement element = XElement.Load(edmxPath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); + + return TryLoadRootElementFromEdmx(element, MetadataConstants.V3_SCHEMA_CONSTANTS, EdmxSectionName, RootElementName, out rootElement) + || TryLoadRootElementFromEdmx(element, MetadataConstants.V2_SCHEMA_CONSTANTS, EdmxSectionName, RootElementName, out rootElement) + || TryLoadRootElementFromEdmx(element, MetadataConstants.V1_SCHEMA_CONSTANTS, EdmxSectionName, RootElementName, out rootElement); + } + + /// + /// Takes an Enumerable of EdmSchemaErrors, and adds them + /// to the errors collection of the template class + /// + private bool ProcessErrors(IEnumerable errors, string sourceFilePath) + { + bool foundErrors = false; + foreach (EdmSchemaError error in errors) + { + CompilerError newError = new CompilerError(error.SchemaLocation, error.Line, error.Column, + error.ErrorCode.ToString(CultureInfo.InvariantCulture), + error.Message); + newError.IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning; + foundErrors |= error.Severity == EdmSchemaErrorSeverity.Error; + if (error.SchemaLocation == null) + { + newError.FileName = sourceFilePath; + } + _textTransformation.Errors.Add(newError); + } + + return foundErrors; + } + } + + /// + /// Builder class for creating a StorageMappingItemCollection + /// + private class StorageMappingItemCollectionBuilder : ItemCollectionBuilder + { + private readonly EdmItemCollection _edmItemCollection; + private readonly StoreItemCollection _storeItemCollection; + + public StorageMappingItemCollectionBuilder(DynamicTextTransformation textTransformation, EdmItemCollection edmItemCollection, StoreItemCollection storeItemCollection) + : base(textTransformation, MetadataConstants.MSL_EXTENSION, MetadataConstants.MSL_EDMX_SECTION_NAME, MetadataConstants.MSL_ROOT_ELEMENT_NAME) + { + _edmItemCollection = edmItemCollection; + _storeItemCollection = storeItemCollection; + } + + protected override ItemCollection CreateItemCollection(IEnumerable readers, out IList errors) + { + return MetadataItemCollectionFactory.CreateStorageMappingItemCollection(_edmItemCollection, _storeItemCollection, readers, out errors); + } + + /// + /// Selects a namespace from the supplied constants. + /// + protected override string GetNamespace(SchemaConstants constants) + { + return constants.MslNamespace; + } + } + + /// + /// Builder class for creating a StoreItemCollection + /// + private class StoreItemCollectionBuilder : ItemCollectionBuilder + { + public StoreItemCollectionBuilder(DynamicTextTransformation textTransformation) + : base(textTransformation, MetadataConstants.SSDL_EXTENSION, MetadataConstants.SSDL_EDMX_SECTION_NAME, MetadataConstants.SSDL_ROOT_ELEMENT_NAME) + { + } + + protected override ItemCollection CreateItemCollection(IEnumerable readers, out IList errors) + { + return MetadataItemCollectionFactory.CreateStoreItemCollection(readers, out errors); + } + + /// + /// Selects a namespace from the supplied constants. + /// + protected override string GetNamespace(SchemaConstants constants) + { + return constants.SsdlNamespace; + } + } + + /// + /// Builder class for creating a EdmItemCollection + /// + private class EdmItemCollectionBuilder : ItemCollectionBuilder + { + private List _referenceSchemas = new List(); + + public EdmItemCollectionBuilder(DynamicTextTransformation textTransformation) + : base(textTransformation, MetadataConstants.CSDL_EXTENSION, MetadataConstants.CSDL_EDMX_SECTION_NAME, MetadataConstants.CSDL_ROOT_ELEMENT_NAME) + { + } + + public EdmItemCollectionBuilder(DynamicTextTransformation textTransformation, IEnumerable referenceSchemas) + : this(textTransformation) + { + _referenceSchemas.AddRange(referenceSchemas); + } + + protected override ItemCollection CreateItemCollection(IEnumerable readers, out IList errors) + { + List ownedReaders = new List(); + List allReaders = new List(); + try + { + allReaders.AddRange(readers); + foreach (string path in _referenceSchemas.Distinct()) + { + XElement reference; + if(TryLoadRootElement(path, out reference)) + { + XmlReader reader = reference.CreateReader(); + allReaders.Add(reader); + ownedReaders.Add(reader); + } + } + + return MetadataItemCollectionFactory.CreateEdmItemCollection(allReaders, out errors); + } + finally + { + foreach (XmlReader reader in ownedReaders) + { + ((IDisposable)reader).Dispose(); + } + } + } + + /// + /// Selects a namespace from the supplied constants. + /// + protected override string GetNamespace(SchemaConstants constants) + { + return constants.CsdlNamespace; + } + } +} + +/// +/// Responsible for encapsulating the retrieval and translation of the CodeGeneration +/// annotations in the EntityFramework Metadata to a form that is useful in code generation. +/// +public static class Accessibility +{ + private const string GETTER_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:GetterAccess"; + private const string SETTER_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:SetterAccess"; + private const string TYPE_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:TypeAccess"; + private const string METHOD_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:MethodAccess"; + private const string ACCESS_PROTECTED = "Protected"; + private const string ACCESS_INTERNAL = "Internal"; + private const string ACCESS_PRIVATE = "Private"; + private static readonly Dictionary AccessibilityRankIdLookup = new Dictionary + { + { "private", 1}, + { "internal", 2}, + { "protected", 3}, + { "public", 4}, + }; + + /// + /// Gets the accessibility that should be applied to a type being generated from the provided GlobalItem. + /// + /// defaults to public if no annotation is found. + /// + public static string ForType(GlobalItem item) + { + if (item == null) + { + return null; + } + + return GetAccessibility(item, TYPE_ACCESS); + } + + /// + /// Gets the accessibility that should be applied at the property level for a property being + /// generated from the provided EdmMember. + /// + /// defaults to public if no annotation is found. + /// + public static string ForProperty(EdmMember member) + { + if (member == null) + { + return null; + } + + string getterAccess, setterAccess, propertyAccess; + CalculatePropertyAccessibility(member, out propertyAccess, out getterAccess, out setterAccess); + return propertyAccess; + } + + /// + /// Gets the accessibility that should be applied at the property level for a Read-Only property being + /// generated from the provided EdmMember. + /// + /// defaults to public if no annotation is found. + /// + public static string ForReadOnlyProperty(EdmMember member) + { + if (member == null) + { + return null; + } + + return GetAccessibility(member, GETTER_ACCESS); + } + + /// + /// Gets the accessibility that should be applied at the property level for a property being + /// generated from the provided EntitySet. + /// + /// defaults to public if no annotation is found. + /// + public static string ForReadOnlyProperty(EntitySet set) + { + if (set == null) + { + return null; + } + + return GetAccessibility(set, GETTER_ACCESS); + } + + /// + /// Gets the accessibility that should be applied at the property level for a Write-Only property being + /// generated from the provided EdmMember. + /// + /// defaults to public if no annotation is found. + /// + public static string ForWriteOnlyProperty(EdmMember member) + { + if (member == null) + { + return null; + } + + return GetAccessibility(member, SETTER_ACCESS); + } + + + /// + /// Gets the accessibility that should be applied at the get level for a property being + /// generated from the provided EdmMember. + /// + /// defaults to empty if no annotation is found or the accessibility is the same as the property level. + /// + public static string ForGetter(EdmMember member) + { + if (member == null) + { + return null; + } + + string getterAccess, setterAccess, propertyAccess; + CalculatePropertyAccessibility(member, out propertyAccess, out getterAccess, out setterAccess); + return getterAccess; + } + + /// + /// Gets the accessibility that should be applied at the set level for a property being + /// generated from the provided EdmMember. + /// + /// defaults to empty if no annotation is found or the accessibility is the same as the property level. + /// + public static string ForSetter(EdmMember member) + { + if (member == null) + { + return null; + } + + string getterAccess, setterAccess, propertyAccess; + CalculatePropertyAccessibility(member, out propertyAccess, out getterAccess, out setterAccess); + return setterAccess; + } + + /// + /// Gets the accessibility that should be applied to a method being generated from the provided EdmFunction. + /// + /// defaults to public if no annotation is found. + /// + public static string ForMethod(EdmFunction function) + { + if (function == null) + { + return null; + } + + return GetAccessibility(function, METHOD_ACCESS); + } + + private static void CalculatePropertyAccessibility(MetadataItem item, + out string propertyAccessibility, + out string getterAccessibility, + out string setterAccessibility) + { + getterAccessibility = GetAccessibility(item, GETTER_ACCESS); + int getterRank = AccessibilityRankIdLookup[getterAccessibility]; + + setterAccessibility = GetAccessibility(item, SETTER_ACCESS); + int setterRank = AccessibilityRankIdLookup[setterAccessibility]; + + int propertyRank = Math.Max(getterRank, setterRank); + if (setterRank == propertyRank) + { + setterAccessibility = String.Empty; + } + + if (getterRank == propertyRank) + { + getterAccessibility = String.Empty; + } + + propertyAccessibility = AccessibilityRankIdLookup.Where(v => v.Value == propertyRank).Select(v => v.Key).Single(); + } + + private static string GetAccessibility(MetadataItem item, string name) + { + string accessibility; + if (MetadataTools.TryGetStringMetadataPropertySetting(item, name, out accessibility)) + { + return TranslateUserAccessibilityToCSharpAccessibility(accessibility); + } + + return "public"; + } + + private static string TranslateUserAccessibilityToCSharpAccessibility(string userAccessibility) + { + if (userAccessibility == ACCESS_PROTECTED) + { + return "protected"; + } + else if (userAccessibility == ACCESS_INTERNAL) + { + return "internal"; + } + else if (userAccessibility == ACCESS_PRIVATE) + { + return "private"; + } + else + { + // default to public + return "public"; + } + } +} + +/// +/// Responsible for creating source code regions in code when the loop inside +/// actually produces something. +/// +public class CodeRegion +{ + private const int STANDARD_INDENT_LENGTH = 4; + + private readonly DynamicTextTransformation _textTransformation; + private int _beforeRegionLength; + private int _emptyRegionLength; + private int _regionIndentLevel = -1; + + /// + /// Initializes an CodeRegion instance with the + /// TextTransformation (T4 generated class) that is currently running + /// + public CodeRegion(object textTransformation) + { + if (textTransformation == null) + { + throw new ArgumentNullException("textTransformation"); + } + + _textTransformation = DynamicTextTransformation.Create(textTransformation); + } + + /// + /// Initializes an CodeRegion instance with the + /// TextTransformation (T4 generated class) that is currently running, + /// and the indent level to start the first region at. + /// + public CodeRegion(object textTransformation, int firstIndentLevel) + : this(textTransformation) + { + if (firstIndentLevel < 0) + { + throw new ArgumentException("firstIndentLevel"); + } + + _regionIndentLevel = firstIndentLevel - 1; + } + + /// + /// Starts the begining of a region + /// + public void Begin(string regionName) + { + if (regionName == null) + { + throw new ArgumentNullException("regionName"); + } + + Begin(regionName, 1); + } + + /// + /// Start the begining of a region, indented + /// the numbers of levels specified + /// + public void Begin(string regionName, int levelsToIncreaseIndent) + { + if (regionName == null) + { + throw new ArgumentNullException("regionName"); + } + + _beforeRegionLength = _textTransformation.GenerationEnvironment.Length; + _regionIndentLevel += levelsToIncreaseIndent; + _textTransformation.Write(GetIndent(_regionIndentLevel)); + _textTransformation.WriteLine("#region " + regionName); + _emptyRegionLength = _textTransformation.GenerationEnvironment.Length; + } + + /// + /// Ends a region, or totaly removes it if nothing + /// was generted since the begining of the region. + /// + public void End() + { + End(1); + } + + /// + /// Ends a region, or totaly removes it if nothing + /// was generted since the begining of the region, also outdents + /// the number of levels specified. + /// + public void End(int levelsToDecrease) + { + int indentLevel = _regionIndentLevel; + _regionIndentLevel -= levelsToDecrease; + + if (_emptyRegionLength == _textTransformation.GenerationEnvironment.Length) + _textTransformation.GenerationEnvironment.Length = _beforeRegionLength; + else + { + _textTransformation.WriteLine(String.Empty); + _textTransformation.Write(GetIndent(indentLevel)); + _textTransformation.WriteLine("#endregion"); + _textTransformation.WriteLine(String.Empty); + } + } + + /// + /// Gets the current indent level that the next end region statement will be written + /// at + /// + public int CurrentIndentLevel { get { return _regionIndentLevel; } } + + /// + /// Get a string of spaces equivelent to the number of indents + /// desired. + /// + public static string GetIndent(int indentLevel) + { + if (indentLevel < 0) + { + throw new ArgumentException("indentLevel"); + } + + return String.Empty.PadLeft(indentLevel * STANDARD_INDENT_LENGTH); + } +} + + +/// +/// Responsible for collecting together the actual method parameters +/// and the parameters that need to be sent to the Execute method. +/// +public class FunctionImportParameter +{ + public FunctionParameter Source { get; set; } + public string RawFunctionParameterName { get; set; } + public string FunctionParameterName { get; set; } + public string FunctionParameterType { get; set; } + public string LocalVariableName { get; set; } + public string RawClrTypeName { get; set; } + public string ExecuteParameterName { get; set; } + public string EsqlParameterName { get; set; } + public bool NeedsLocalVariable { get; set; } + public bool IsNullableOfT { get; set; } + + + /// + /// Creates a set of FunctionImportParameter objects from the parameters passed in. + /// + public static IEnumerable Create(IEnumerable parameters, CodeGenerationTools code, MetadataTools ef) + { + if (parameters == null) + { + throw new ArgumentNullException("parameters"); + } + + if (code == null) + { + throw new ArgumentNullException("code"); + } + + if (ef == null) + { + throw new ArgumentNullException("ef"); + } + + UniqueIdentifierService unique = new UniqueIdentifierService(); + List importParameters = new List(); + foreach (FunctionParameter parameter in parameters) + { + FunctionImportParameter importParameter = new FunctionImportParameter(); + importParameter.Source = parameter; + importParameter.RawFunctionParameterName = unique.AdjustIdentifier(code.CamelCase(parameter.Name)); + importParameter.FunctionParameterName = code.Escape(importParameter.RawFunctionParameterName); + if (parameter.Mode == ParameterMode.In) + { + TypeUsage typeUsage = parameter.TypeUsage; + importParameter.NeedsLocalVariable = true; + importParameter.FunctionParameterType = code.GetTypeName(typeUsage); + importParameter.EsqlParameterName = parameter.Name; + Type clrType = ef.UnderlyingClrType(parameter.TypeUsage.EdmType); + importParameter.RawClrTypeName = typeUsage.EdmType is EnumType ? code.GetTypeName(typeUsage.EdmType) : code.Escape(clrType); + importParameter.IsNullableOfT = clrType.IsValueType; + } + else + { + importParameter.NeedsLocalVariable = false; + importParameter.FunctionParameterType = "ObjectParameter"; + importParameter.ExecuteParameterName = importParameter.FunctionParameterName; + } + importParameters.Add(importParameter); + } + + // we save the local parameter uniquification for a second pass to make the visible parameters + // as pretty and sensible as possible + for (int i = 0; i < importParameters.Count; i++) + { + FunctionImportParameter importParameter = importParameters[i]; + if (importParameter.NeedsLocalVariable) + { + importParameter.LocalVariableName = unique.AdjustIdentifier(importParameter.RawFunctionParameterName + "Parameter"); + importParameter.ExecuteParameterName = importParameter.LocalVariableName; + } + } + + return importParameters; + } + + // + // Class to create unique variables within the same scope + // + private sealed class UniqueIdentifierService + { + private readonly HashSet _knownIdentifiers; + + public UniqueIdentifierService() + { + _knownIdentifiers = new HashSet(StringComparer.Ordinal); + } + + /// + /// Given an identifier, makes it unique within the scope by adding + /// a suffix (1, 2, 3, ...), and returns the adjusted identifier. + /// + public string AdjustIdentifier(string identifier) + { + // find a unique name by adding suffix as necessary + int numberOfConflicts = 0; + string adjustedIdentifier = identifier; + + while (!_knownIdentifiers.Add(adjustedIdentifier)) + { + ++numberOfConflicts; + adjustedIdentifier = identifier + numberOfConflicts.ToString(CultureInfo.InvariantCulture); + } + + return adjustedIdentifier; + } + } +} + +/// +/// Responsible for marking the various sections of the generation, +/// so they can be split up into separate files +/// +public class EntityFrameworkTemplateFileManager +{ + /// + /// Creates the VsEntityFrameworkTemplateFileManager if VS is detected, otherwise + /// creates the file system version. + /// + public static EntityFrameworkTemplateFileManager Create(object textTransformation) + { + DynamicTextTransformation transformation = DynamicTextTransformation.Create(textTransformation); + IDynamicHost host = transformation.Host; + +#if !PREPROCESSED_TEMPLATE + var hostServiceProvider = host.AsIServiceProvider(); + + if (hostServiceProvider != null) + { + EnvDTE.DTE dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE)); + + if (dte != null) + { + return new VsEntityFrameworkTemplateFileManager(transformation); + } + } +#endif + return new EntityFrameworkTemplateFileManager(transformation); + } + + private sealed class Block + { + public String Name; + public int Start, Length; + } + + private readonly List files = new List(); + private readonly Block footer = new Block(); + private readonly Block header = new Block(); + private readonly DynamicTextTransformation _textTransformation; + + // reference to the GenerationEnvironment StringBuilder on the + // TextTransformation object + private readonly StringBuilder _generationEnvironment; + + private Block currentBlock; + + /// + /// Initializes an EntityFrameworkTemplateFileManager Instance with the + /// TextTransformation (T4 generated class) that is currently running + /// + private EntityFrameworkTemplateFileManager(object textTransformation) + { + if (textTransformation == null) + { + throw new ArgumentNullException("textTransformation"); + } + + _textTransformation = DynamicTextTransformation.Create(textTransformation); + _generationEnvironment = _textTransformation.GenerationEnvironment; + } + + /// + /// Marks the end of the last file if there was one, and starts a new + /// and marks this point in generation as a new file. + /// + public void StartNewFile(string name) + { + if (name == null) + { + throw new ArgumentNullException("name"); + } + + CurrentBlock = new Block { Name = name }; + } + + public void StartFooter() + { + CurrentBlock = footer; + } + + public void StartHeader() + { + CurrentBlock = header; + } + + public void EndBlock() + { + if (CurrentBlock == null) + { + return; + } + + CurrentBlock.Length = _generationEnvironment.Length - CurrentBlock.Start; + + if (CurrentBlock != header && CurrentBlock != footer) + { + files.Add(CurrentBlock); + } + + currentBlock = null; + } + + /// + /// Produce the template output files. + /// + public virtual IEnumerable Process(bool split = true) + { + var generatedFileNames = new List(); + + if (split) + { + EndBlock(); + + var headerText = _generationEnvironment.ToString(header.Start, header.Length); + var footerText = _generationEnvironment.ToString(footer.Start, footer.Length); + var outputPath = Path.GetDirectoryName(_textTransformation.Host.TemplateFile); + + files.Reverse(); + + foreach (var block in files) + { + var fileName = Path.Combine(outputPath, block.Name); + var content = headerText + _generationEnvironment.ToString(block.Start, block.Length) + footerText; + + generatedFileNames.Add(fileName); + CreateFile(fileName, content); + _generationEnvironment.Remove(block.Start, block.Length); + } + } + + return generatedFileNames; + } + + protected virtual void CreateFile(string fileName, string content) + { + if (IsFileContentDifferent(fileName, content)) + { + File.WriteAllText(fileName, content); + } + } + + protected bool IsFileContentDifferent(String fileName, string newContent) + { + return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent); + } + + private Block CurrentBlock + { + get { return currentBlock; } + set + { + if (CurrentBlock != null) + { + EndBlock(); + } + + if (value != null) + { + value.Start = _generationEnvironment.Length; + } + + currentBlock = value; + } + } + +#if !PREPROCESSED_TEMPLATE + private sealed class VsEntityFrameworkTemplateFileManager : EntityFrameworkTemplateFileManager + { + private EnvDTE.ProjectItem templateProjectItem; + private EnvDTE.DTE dte; + private Action checkOutAction; + private Action> projectSyncAction; + + /// + /// Creates an instance of the VsEntityFrameworkTemplateFileManager class with the IDynamicHost instance + /// + public VsEntityFrameworkTemplateFileManager(object textTemplating) + : base(textTemplating) + { + var hostServiceProvider = _textTransformation.Host.AsIServiceProvider(); + if (hostServiceProvider == null) + { + throw new ArgumentNullException("Could not obtain hostServiceProvider"); + } + + dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE)); + if (dte == null) + { + throw new ArgumentNullException("Could not obtain DTE from host"); + } + + templateProjectItem = dte.Solution.FindProjectItem(_textTransformation.Host.TemplateFile); + + checkOutAction = fileName => dte.SourceControl.CheckOutItem(fileName); + projectSyncAction = keepFileNames => ProjectSync(templateProjectItem, keepFileNames); + } + + public override IEnumerable Process(bool split) + { + if (templateProjectItem.ProjectItems == null) + { + return new List(); + } + + var generatedFileNames = base.Process(split); + + projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null)); + + return generatedFileNames; + } + + protected override void CreateFile(string fileName, string content) + { + if (IsFileContentDifferent(fileName, content)) + { + CheckoutFileIfRequired(fileName); + File.WriteAllText(fileName, content); + } + } + + private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable keepFileNames) + { + var keepFileNameSet = new HashSet(keepFileNames); + var projectFiles = new Dictionary(); + var originalOutput = Path.GetFileNameWithoutExtension(templateProjectItem.FileNames[0]); + + foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) + { + projectFiles.Add(projectItem.FileNames[0], projectItem); + } + + // Remove unused items from the project + foreach (var pair in projectFiles) + { + if (!keepFileNames.Contains(pair.Key) + && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalOutput + ".")) + { + pair.Value.Delete(); + } + } + + // Add missing files to the project + foreach (string fileName in keepFileNameSet) + { + if (!projectFiles.ContainsKey(fileName)) + { + templateProjectItem.ProjectItems.AddFromFile(fileName); + } + } + } + + private void CheckoutFileIfRequired(string fileName) + { + if (dte.SourceControl == null + || !dte.SourceControl.IsItemUnderSCC(fileName) + || dte.SourceControl.IsItemCheckedOut(fileName)) + { + return; + } + + // run on worker thread to prevent T4 calling back into VS + checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null)); + } + } +#endif +} + +/// +/// Responsible creating an instance that can be passed +/// to helper classes that need to access the TextTransformation +/// members. It accesses member by name and signature rather than +/// by type. This is necessary when the +/// template is being used in Preprocessed mode +/// and there is no common known type that can be +/// passed instead +/// +public class DynamicTextTransformation +{ + private object _instance; + IDynamicHost _dynamicHost; + + private readonly MethodInfo _write; + private readonly MethodInfo _writeLine; + private readonly PropertyInfo _generationEnvironment; + private readonly PropertyInfo _errors; + private readonly PropertyInfo _host; + + /// + /// Creates an instance of the DynamicTextTransformation class around the passed in + /// TextTransformation shapped instance passed in, or if the passed in instance + /// already is a DynamicTextTransformation, it casts it and sends it back. + /// + public static DynamicTextTransformation Create(object instance) + { + if (instance == null) + { + throw new ArgumentNullException("instance"); + } + + DynamicTextTransformation textTransformation = instance as DynamicTextTransformation; + if (textTransformation != null) + { + return textTransformation; + } + + return new DynamicTextTransformation(instance); + } + + private DynamicTextTransformation(object instance) + { + _instance = instance; + Type type = _instance.GetType(); + _write = type.GetMethod("Write", new Type[] { typeof(string) }); + _writeLine = type.GetMethod("WriteLine", new Type[] { typeof(string) }); + _generationEnvironment = type.GetProperty("GenerationEnvironment", BindingFlags.Instance | BindingFlags.NonPublic); + _host = type.GetProperty("Host"); + _errors = type.GetProperty("Errors"); + } + + /// + /// Gets the value of the wrapped TextTranformation instance's GenerationEnvironment property + /// + public StringBuilder GenerationEnvironment { get { return (StringBuilder)_generationEnvironment.GetValue(_instance, null); } } + + /// + /// Gets the value of the wrapped TextTranformation instance's Errors property + /// + public System.CodeDom.Compiler.CompilerErrorCollection Errors { get { return (System.CodeDom.Compiler.CompilerErrorCollection)_errors.GetValue(_instance, null); } } + + /// + /// Calls the wrapped TextTranformation instance's Write method. + /// + public void Write(string text) + { + _write.Invoke(_instance, new object[] { text }); + } + + /// + /// Calls the wrapped TextTranformation instance's WriteLine method. + /// + public void WriteLine(string text) + { + _writeLine.Invoke(_instance, new object[] { text }); + } + + /// + /// Gets the value of the wrapped TextTranformation instance's Host property + /// if available (shows up when hostspecific is set to true in the template directive) and returns + /// the appropriate implementation of IDynamicHost + /// + public IDynamicHost Host + { + get + { + if (_dynamicHost == null) + { + if(_host == null) + { + _dynamicHost = new NullHost(); + } + else + { + _dynamicHost = new DynamicHost(_host.GetValue(_instance, null)); + } + } + return _dynamicHost; + } + } +} + + +/// +/// Reponsible for abstracting the use of Host between times +/// when it is available and not +/// +public interface IDynamicHost +{ + /// + /// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue + /// + string ResolveParameterValue(string id, string name, string otherName); + + /// + /// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath + /// + string ResolvePath(string path); + + /// + /// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile + /// + string TemplateFile { get; } + + /// + /// Returns the Host instance cast as an IServiceProvider + /// + IServiceProvider AsIServiceProvider(); +} + +/// +/// Reponsible for implementing the IDynamicHost as a dynamic +/// shape wrapper over the Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost interface +/// rather than type dependent wrapper. We don't use the +/// interface type so that the code can be run in preprocessed mode +/// on a .net framework only installed machine. +/// +public class DynamicHost : IDynamicHost +{ + private readonly object _instance; + private readonly MethodInfo _resolveParameterValue; + private readonly MethodInfo _resolvePath; + private readonly PropertyInfo _templateFile; + + /// + /// Creates an instance of the DynamicHost class around the passed in + /// Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost shapped instance passed in. + /// + public DynamicHost(object instance) + { + _instance = instance; + Type type = _instance.GetType(); + _resolveParameterValue = type.GetMethod("ResolveParameterValue", new Type[] { typeof(string), typeof(string), typeof(string) }); + _resolvePath = type.GetMethod("ResolvePath", new Type[] { typeof(string) }); + _templateFile = type.GetProperty("TemplateFile"); + + } + + /// + /// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue + /// + public string ResolveParameterValue(string id, string name, string otherName) + { + return (string)_resolveParameterValue.Invoke(_instance, new object[] { id, name, otherName }); + } + + /// + /// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath + /// + public string ResolvePath(string path) + { + return (string)_resolvePath.Invoke(_instance, new object[] { path }); + } + + /// + /// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile + /// + public string TemplateFile + { + get + { + return (string)_templateFile.GetValue(_instance, null); + } + } + + /// + /// Returns the Host instance cast as an IServiceProvider + /// + public IServiceProvider AsIServiceProvider() + { + return _instance as IServiceProvider; + } +} + +/// +/// Reponsible for implementing the IDynamicHost when the +/// Host property is not available on the TextTemplating type. The Host +/// property only exists when the hostspecific attribute of the template +/// directive is set to true. +/// +public class NullHost : IDynamicHost +{ + /// + /// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue + /// that simply retuns null. + /// + public string ResolveParameterValue(string id, string name, string otherName) + { + return null; + } + + /// + /// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath + /// that simply retuns the path passed in. + /// + public string ResolvePath(string path) + { + return path; + } + + /// + /// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile + /// that returns null. + /// + public string TemplateFile + { + get + { + return null; + } + } + + /// + /// Returns null. + /// + public IServiceProvider AsIServiceProvider() + { + return null; + } +} + +/// +/// Responsible for encapsulating the constants defined in Metadata +/// +public static class MetadataConstants +{ + public const string CSDL_EXTENSION = ".csdl"; + + public const string CSDL_EDMX_SECTION_NAME = "ConceptualModels"; + public const string CSDL_ROOT_ELEMENT_NAME = "Schema"; + public const string EDM_ANNOTATION_09_02 = "http://schemas.microsoft.com/ado/2009/02/edm/annotation"; + + public const string SSDL_EXTENSION = ".ssdl"; + + public const string SSDL_EDMX_SECTION_NAME = "StorageModels"; + public const string SSDL_ROOT_ELEMENT_NAME = "Schema"; + + public const string MSL_EXTENSION = ".msl"; + + public const string MSL_EDMX_SECTION_NAME = "Mappings"; + public const string MSL_ROOT_ELEMENT_NAME = "Mapping"; + + public const string TT_TEMPLATE_NAME = "TemplateName"; + public const string TT_TEMPLATE_VERSION = "TemplateVersion"; + public const string TT_MINIMUM_ENTITY_FRAMEWORK_VERSION = "MinimumEntityFrameworkVersion"; + + public const string DEFAULT_TEMPLATE_VERSION = "4.0"; + + public static readonly SchemaConstants V1_SCHEMA_CONSTANTS = new SchemaConstants( + "http://schemas.microsoft.com/ado/2007/06/edmx", + "http://schemas.microsoft.com/ado/2006/04/edm", + "http://schemas.microsoft.com/ado/2006/04/edm/ssdl", + "urn:schemas-microsoft-com:windows:storage:mapping:CS", + new Version("3.5")); + + public static readonly SchemaConstants V2_SCHEMA_CONSTANTS = new SchemaConstants( + "http://schemas.microsoft.com/ado/2008/10/edmx", + "http://schemas.microsoft.com/ado/2008/09/edm", + "http://schemas.microsoft.com/ado/2009/02/edm/ssdl", + "http://schemas.microsoft.com/ado/2008/09/mapping/cs", + new Version("4.0")); + + public static readonly SchemaConstants V3_SCHEMA_CONSTANTS = new SchemaConstants( + "http://schemas.microsoft.com/ado/2009/11/edmx", + "http://schemas.microsoft.com/ado/2009/11/edm", + "http://schemas.microsoft.com/ado/2009/11/edm/ssdl", + "http://schemas.microsoft.com/ado/2009/11/mapping/cs", + new Version("5.0")); +} + +public struct SchemaConstants +{ + public SchemaConstants(string edmxNamespace, string csdlNamespace, string ssdlNamespace, string mslNamespace, Version minimumTemplateVersion) : this() + { + EdmxNamespace = edmxNamespace; + CsdlNamespace = csdlNamespace; + SsdlNamespace = ssdlNamespace; + MslNamespace = mslNamespace; + MinimumTemplateVersion = minimumTemplateVersion; + } + + public string EdmxNamespace { get; private set; } + public string CsdlNamespace { get; private set; } + public string SsdlNamespace { get; private set; } + public string MslNamespace { get; private set; } + public Version MinimumTemplateVersion { get; private set; } +} #> \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/EmployeeMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/EmployeeMf.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/EmployeeMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/EmployeeMf.cs index 14efe103..ae7afe41 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/EmployeeMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/EmployeeMf.cs @@ -1,21 +1,21 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - using System; - using System.Collections.Generic; - - public abstract partial class EmployeeMf - { - public int EmployeeId { get; set; } - public string FirstName { get; private set; } - internal string LastName { private get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + using System; + using System.Collections.Generic; + + public abstract partial class EmployeeMf + { + public int EmployeeId { get; set; } + public string FirstName { get; private set; } + internal string LastName { private get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/MailRoomMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/MailRoomMf.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/MailRoomMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/MailRoomMf.cs index 4a20a6e5..61753d81 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/MailRoomMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/MailRoomMf.cs @@ -1,22 +1,22 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - using System; - using System.Collections.Generic; - - internal partial class MailRoomMf - { - public int id { get; set; } - public System.Guid BuildingId { get; set; } - - public virtual BuildingMf Building { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + using System; + using System.Collections.Generic; + + internal partial class MailRoomMf + { + public int id { get; set; } + public System.Guid BuildingId { get; set; } + + public virtual BuildingMf Building { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/OfficeMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/OfficeMf.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/OfficeMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/OfficeMf.cs index 4ebbe855..33c9cfb2 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/OfficeMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/OfficeMf.cs @@ -1,29 +1,29 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - using System; - using System.Collections.Generic; - - public partial class OfficeMf - { - public OfficeMf() - { - this.WhiteBoards = new HashSet(); - } - - public string Number { get; set; } - public System.Guid BuildingId { get; set; } - internal string Description { get; private set; } - - private BuildingMf Building { get; set; } - public virtual ICollection WhiteBoards { internal get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + using System; + using System.Collections.Generic; + + public partial class OfficeMf + { + public OfficeMf() + { + this.WhiteBoards = new HashSet(); + } + + public string Number { get; set; } + public System.Guid BuildingId { get; set; } + internal string Description { get; private set; } + + private BuildingMf Building { get; set; } + public virtual ICollection WhiteBoards { internal get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/AddressMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/AddressMf.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/AddressMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/AddressMf.cs index 1c086ac8..e0f92031 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/AddressMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/AddressMf.cs @@ -1,16 +1,16 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - public partial class AddressMf - { - public AddressMf(string street, string city, string state, string zipCode, int? zone, string environment) - { - Street = street; - City = city; - State = state; - ZipCode = zipCode; - SiteInfo = new SiteInfoMf(zone, environment); - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + public partial class AddressMf + { + public AddressMf(string street, string city, string state, string zipCode, int? zone, string environment) + { + Street = street; + City = city; + State = state; + ZipCode = zipCode; + SiteInfo = new SiteInfoMf(zone, environment); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/AdvancedPatternsModelFirstContext.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/AdvancedPatternsModelFirstContext.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/AdvancedPatternsModelFirstContext.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/AdvancedPatternsModelFirstContext.cs index 4a7021b0..3cc3c9f2 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/AdvancedPatternsModelFirstContext.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/AdvancedPatternsModelFirstContext.cs @@ -1,13 +1,13 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - internal partial class AdvancedPatternsModelFirstContext - { - public AdvancedPatternsModelFirstContext(string nameOrConnectionString) - : base(nameOrConnectionString) - { - Configuration.LazyLoadingEnabled = false; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + internal partial class AdvancedPatternsModelFirstContext + { + public AdvancedPatternsModelFirstContext(string nameOrConnectionString) + : base(nameOrConnectionString) + { + Configuration.LazyLoadingEnabled = false; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/BuildingMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/BuildingMf.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/BuildingMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/BuildingMf.cs index 897d754e..1fc9e2be 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/BuildingMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/BuildingMf.cs @@ -1,18 +1,18 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - using System; - - public partial class BuildingMf - { - public BuildingMf(Guid buildingId, string name, decimal value, AddressMf address) - : this() - { - BuildingId = buildingId; - Name = name; - Value = value; - Address = address; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + using System; + + public partial class BuildingMf + { + public BuildingMf(Guid buildingId, string name, decimal value, AddressMf address) + : this() + { + BuildingId = buildingId; + Name = name; + Value = value; + Address = address; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/CurrentEmployeeMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/CurrentEmployeeMf.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/CurrentEmployeeMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/CurrentEmployeeMf.cs index e8adb905..13406a83 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/CurrentEmployeeMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/CurrentEmployeeMf.cs @@ -1,16 +1,16 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - public partial class CurrentEmployeeMf - { - public CurrentEmployeeMf() - { - } - - public CurrentEmployeeMf(string firstName, string lastName) - : base(firstName, lastName) - { - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + public partial class CurrentEmployeeMf + { + public CurrentEmployeeMf() + { + } + + public CurrentEmployeeMf(string firstName, string lastName) + : base(firstName, lastName) + { + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/EmployeeMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/EmployeeMf.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/EmployeeMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/EmployeeMf.cs index f1ece88c..f98848c1 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/EmployeeMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/EmployeeMf.cs @@ -1,17 +1,17 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - public abstract partial class EmployeeMf - { - protected EmployeeMf() - { - } - - protected EmployeeMf(string firstName, string lastName) - { - FirstName = firstName; - LastName = lastName; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + public abstract partial class EmployeeMf + { + protected EmployeeMf() + { + } + + protected EmployeeMf(string firstName, string lastName) + { + FirstName = firstName; + LastName = lastName; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/OfficeMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/OfficeMf.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/OfficeMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/OfficeMf.cs index fed34948..3895cea5 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/OfficeMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/OfficeMf.cs @@ -1,12 +1,12 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - public partial class OfficeMf - { - public BuildingMf GetBuilding() - { - return Building; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + public partial class OfficeMf + { + public BuildingMf GetBuilding() + { + return Building; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/PastEmployeeMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/PastEmployeeMf.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/PastEmployeeMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/PastEmployeeMf.cs index f90794ee..6b4c02e1 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/PastEmployeeMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/PastEmployeeMf.cs @@ -1,16 +1,16 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - public partial class PastEmployeeMf - { - public PastEmployeeMf() - { - } - - public PastEmployeeMf(string firstName, string lastName) - : base(firstName, lastName) - { - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + public partial class PastEmployeeMf + { + public PastEmployeeMf() + { + } + + public PastEmployeeMf(string firstName, string lastName) + : base(firstName, lastName) + { + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/SiteInfoMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/SiteInfoMf.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/SiteInfoMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/SiteInfoMf.cs index 82f2da94..abd10237 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/Partials/SiteInfoMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/Partials/SiteInfoMf.cs @@ -1,17 +1,17 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - internal partial class SiteInfoMf - { - public SiteInfoMf() - { - } - - public SiteInfoMf(int? zone, string environment) - { - Zone = zone; - Environment = environment; - } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + internal partial class SiteInfoMf + { + public SiteInfoMf() + { + } + + public SiteInfoMf(int? zone, string environment) + { + Zone = zone; + Environment = environment; + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/PastEmployeeMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/PastEmployeeMf.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/PastEmployeeMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/PastEmployeeMf.cs index 98bef3e2..f675e590 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/PastEmployeeMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/PastEmployeeMf.cs @@ -1,19 +1,19 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - using System; - using System.Collections.Generic; - - public partial class PastEmployeeMf : EmployeeMf - { - public System.DateTime TerminationDate { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + using System; + using System.Collections.Generic; + + public partial class PastEmployeeMf : EmployeeMf + { + public System.DateTime TerminationDate { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/SiteInfoMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/SiteInfoMf.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/SiteInfoMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/SiteInfoMf.cs index bdf2b380..e585cae4 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/SiteInfoMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/SiteInfoMf.cs @@ -1,19 +1,19 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - using System; - - internal partial class SiteInfoMf - { - protected Nullable Zone { get; private set; } - public string Environment { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + using System; + + internal partial class SiteInfoMf + { + protected Nullable Zone { get; private set; } + public string Environment { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/WhiteboardMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/WhiteboardMf.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/WhiteboardMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/WhiteboardMf.cs index cefaf91c..b6cb0ad1 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/WhiteboardMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/WhiteboardMf.cs @@ -1,22 +1,22 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - using System; - using System.Collections.Generic; - - public partial class WhiteboardMf - { - public byte[] iD { get; set; } - public string AssetTag { get; set; } - - public virtual OfficeMf Office { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + using System; + using System.Collections.Generic; + + public partial class WhiteboardMf + { + public byte[] iD { get; set; } + public string AssetTag { get; set; } + + public virtual OfficeMf Office { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/WorkOrderMf.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/WorkOrderMf.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/WorkOrderMf.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/WorkOrderMf.cs index 52904461..c138d696 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsAdvancedPatterns/WorkOrderMf.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsAdvancedPatterns/WorkOrderMf.cs @@ -1,23 +1,23 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns -{ - using System; - using System.Collections.Generic; - - public partial class WorkOrderMf - { - public int WorkOrderId { get; set; } - public int EmployeeId { get; set; } - public string Details { get; set; } - - internal virtual EmployeeMf Employee { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns +{ + using System; + using System.Collections.Generic; + + public partial class WorkOrderMf + { + public int WorkOrderId { get; set; } + public int EmployeeId { get; set; } + public string Details { get; set; } + + internal virtual EmployeeMf Employee { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/BackOrderLine2Mm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/BackOrderLine2Mm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/BackOrderLine2Mm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/BackOrderLine2Mm.cs index 4f2c4d0d..2af38af4 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/BackOrderLine2Mm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/BackOrderLine2Mm.cs @@ -1,18 +1,18 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class BackOrderLine2Mm : BackOrderLineMm - { - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class BackOrderLine2Mm : BackOrderLineMm + { + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/BackOrderLineMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/BackOrderLineMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/BackOrderLineMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/BackOrderLineMm.cs index df153c68..f9371192 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/BackOrderLineMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/BackOrderLineMm.cs @@ -1,21 +1,21 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class BackOrderLineMm : OrderLineMm - { - public System.DateTime ETA { get; set; } - - public virtual SupplierMm Supplier { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class BackOrderLineMm : OrderLineMm + { + public System.DateTime ETA { get; set; } + + public virtual SupplierMm Supplier { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/BarcodeDetailMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/BarcodeDetailMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/BarcodeDetailMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/BarcodeDetailMm.cs index ef08471e..a3fa9989 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/BarcodeDetailMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/BarcodeDetailMm.cs @@ -1,20 +1,20 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class BarcodeDetailMm - { - public byte[] Code { get; set; } - public string RegisteredTo { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class BarcodeDetailMm + { + public byte[] Code { get; set; } + public string RegisteredTo { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/BarcodeMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/BarcodeMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/BarcodeMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/BarcodeMm.cs index 14f60871..d32b9d4c 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/BarcodeMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/BarcodeMm.cs @@ -1,30 +1,30 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class BarcodeMm - { - public BarcodeMm() - { - this.BadScans = new HashSet(); - } - - public byte[] Code { get; set; } - public int ProductId { get; set; } - public string Text { get; set; } - - public virtual ProductMm Product { get; set; } - public virtual ICollection BadScans { get; set; } - public virtual BarcodeDetailMm Detail { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class BarcodeMm + { + public BarcodeMm() + { + this.BadScans = new HashSet(); + } + + public byte[] Code { get; set; } + public int ProductId { get; set; } + public string Text { get; set; } + + public virtual ProductMm Product { get; set; } + public virtual ICollection BadScans { get; set; } + public virtual BarcodeDetailMm Detail { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ComplaintMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ComplaintMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ComplaintMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ComplaintMm.cs index db9f8d13..dbe0bb77 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ComplaintMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ComplaintMm.cs @@ -1,25 +1,25 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class ComplaintMm - { - public int ComplaintId { get; set; } - public Nullable CustomerId { get; set; } - public System.DateTime Logged { get; set; } - public string Details { get; set; } - - public virtual Another.Place.CustomerMm Customer { get; set; } - public virtual ResolutionMm Resolution { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class ComplaintMm + { + public int ComplaintId { get; set; } + public Nullable CustomerId { get; set; } + public System.DateTime Logged { get; set; } + public string Details { get; set; } + + public virtual Another.Place.CustomerMm Customer { get; set; } + public virtual ResolutionMm Resolution { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ComputerDetailMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ComputerDetailMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ComputerDetailMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ComputerDetailMm.cs index c097b96b..013e93f6 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ComputerDetailMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ComputerDetailMm.cs @@ -1,33 +1,33 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class ComputerDetailMm - { - public ComputerDetailMm() - { - this.Dimensions = new DimensionsMm(); - } - - public int ComputerDetailId { get; set; } - public string Manufacturer { get; set; } - public string Model { get; set; } - public string Serial { get; set; } - public string Specifications { get; set; } - public System.DateTime PurchaseDate { get; set; } - - public DimensionsMm Dimensions { get; set; } - - public virtual ComputerMm Computer { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class ComputerDetailMm + { + public ComputerDetailMm() + { + this.Dimensions = new DimensionsMm(); + } + + public int ComputerDetailId { get; set; } + public string Manufacturer { get; set; } + public string Model { get; set; } + public string Serial { get; set; } + public string Specifications { get; set; } + public System.DateTime PurchaseDate { get; set; } + + public DimensionsMm Dimensions { get; set; } + + public virtual ComputerMm Computer { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ComputerMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ComputerMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ComputerMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ComputerMm.cs index 803b0ae4..9bc9bfa8 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ComputerMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ComputerMm.cs @@ -1,22 +1,22 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class ComputerMm - { - public int ComputerId { get; set; } - public string Name { get; set; } - - public virtual ComputerDetailMm ComputerDetail { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class ComputerMm + { + public int ComputerId { get; set; } + public string Name { get; set; } + + public virtual ComputerDetailMm ComputerDetail { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ConcurrencyInfoMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ConcurrencyInfoMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ConcurrencyInfoMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ConcurrencyInfoMm.cs index db9800e8..79dafbb3 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ConcurrencyInfoMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ConcurrencyInfoMm.cs @@ -1,19 +1,19 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - - public partial class ConcurrencyInfoMm - { - public string Token { get; set; } - public Nullable QueriedDateTime { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + + public partial class ConcurrencyInfoMm + { + public string Token { get; set; } + public Nullable QueriedDateTime { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ContactDetailsMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ContactDetailsMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ContactDetailsMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ContactDetailsMm.cs index bf08c12c..a6978d19 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ContactDetailsMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ContactDetailsMm.cs @@ -1,29 +1,29 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - - public partial class ContactDetailsMm - { - public ContactDetailsMm() - { - this.HomePhone = new Another.Place.PhoneMm(); - this.WorkPhone = new Another.Place.PhoneMm(); - this.MobilePhone = new Another.Place.PhoneMm(); - } - - public string Email { get; set; } - - public Another.Place.PhoneMm HomePhone { get; set; } - public Another.Place.PhoneMm WorkPhone { get; set; } - public Another.Place.PhoneMm MobilePhone { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + + public partial class ContactDetailsMm + { + public ContactDetailsMm() + { + this.HomePhone = new Another.Place.PhoneMm(); + this.WorkPhone = new Another.Place.PhoneMm(); + this.MobilePhone = new Another.Place.PhoneMm(); + } + + public string Email { get; set; } + + public Another.Place.PhoneMm HomePhone { get; set; } + public Another.Place.PhoneMm WorkPhone { get; set; } + public Another.Place.PhoneMm MobilePhone { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.Context.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.Context.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.Context.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.Context.cs index 74ea20c6..c402296c 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.Context.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.Context.cs @@ -1,117 +1,117 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Data.Entity; - using System.Data.Entity.Infrastructure; - using System.Data.Entity.Core.Objects; - using System.Data.Entity.Core.Objects.DataClasses; - using System.Linq; - - public partial class MonsterModel : DbContext - { - public MonsterModel() - : base("name=MonsterModel") - { - } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - throw new UnintentionalCodeFirstException(); - } - - public DbSet Customer { get; set; } - public DbSet Barcode { get; set; } - public DbSet IncorrectScan { get; set; } - public DbSet BarcodeDetail { get; set; } - public DbSet Complaint { get; set; } - public DbSet Resolution { get; set; } - public DbSet Login { get; set; } - public DbSet SuspiciousActivity { get; set; } - public DbSet SmartCard { get; set; } - public DbSet RSAToken { get; set; } - public DbSet PasswordReset { get; set; } - public DbSet PageView { get; set; } - public DbSet LastLogin { get; set; } - public DbSet Message { get; set; } - public DbSet Order { get; set; } - public DbSet OrderNote { get; set; } - public DbSet OrderQualityCheck { get; set; } - public DbSet OrderLine { get; set; } - public DbSet Product { get; set; } - public DbSet ProductDetail { get; set; } - public DbSet ProductReview { get; set; } - public DbSet ProductPhoto { get; set; } - public DbSet ProductWebFeature { get; set; } - public DbSet Supplier { get; set; } - public DbSet SupplierLogo { get; set; } - public DbSet SupplierInfo { get; set; } - public DbSet CustomerInfo { get; set; } - public DbSet Computer { get; set; } - public DbSet ComputerDetail { get; set; } - public DbSet Driver { get; set; } - public DbSet License { get; set; } - - private ObjectResult FunctionImport1(ObjectParameter modifiedDate) - { - return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("FunctionImport1", modifiedDate); - } - - internal virtual ObjectResult FunctionImport2() - { - return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("FunctionImport2"); - } - - internal virtual ObjectResult FunctionImport2(MergeOption mergeOption) - { - return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("FunctionImport2", mergeOption); - } - - public virtual int ParameterTest(byte[] binary, Nullable @bool, Nullable dateTime, Nullable @decimal, Nullable @float, Nullable guid, ObjectParameter @int, ObjectParameter @string) - { - var binaryParameter = binary != null ? - new ObjectParameter("binary", binary) : - new ObjectParameter("binary", typeof(byte[])); - - var boolParameter = @bool.HasValue ? - new ObjectParameter("bool", @bool) : - new ObjectParameter("bool", typeof(bool)); - - var dateTimeParameter = dateTime.HasValue ? - new ObjectParameter("dateTime", dateTime) : - new ObjectParameter("dateTime", typeof(System.DateTime)); - - var decimalParameter = @decimal.HasValue ? - new ObjectParameter("decimal", @decimal) : - new ObjectParameter("decimal", typeof(decimal)); - - var floatParameter = @float.HasValue ? - new ObjectParameter("float", @float) : - new ObjectParameter("float", typeof(double)); - - var guidParameter = guid.HasValue ? - new ObjectParameter("guid", guid) : - new ObjectParameter("guid", typeof(System.Guid)); - - return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("ParameterTest", binaryParameter, boolParameter, dateTimeParameter, decimalParameter, floatParameter, guidParameter, @int, @string); - } - - public virtual ObjectResult EntityTypeTest() - { - return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("EntityTypeTest"); - } - - public virtual ObjectResult EntityTypeTest(MergeOption mergeOption) - { - return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("EntityTypeTest", mergeOption); - } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Data.Entity; + using System.Data.Entity.Infrastructure; + using System.Data.Entity.Core.Objects; + using System.Data.Entity.Core.Objects.DataClasses; + using System.Linq; + + public partial class MonsterModel : DbContext + { + public MonsterModel() + : base("name=MonsterModel") + { + } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + throw new UnintentionalCodeFirstException(); + } + + public DbSet Customer { get; set; } + public DbSet Barcode { get; set; } + public DbSet IncorrectScan { get; set; } + public DbSet BarcodeDetail { get; set; } + public DbSet Complaint { get; set; } + public DbSet Resolution { get; set; } + public DbSet Login { get; set; } + public DbSet SuspiciousActivity { get; set; } + public DbSet SmartCard { get; set; } + public DbSet RSAToken { get; set; } + public DbSet PasswordReset { get; set; } + public DbSet PageView { get; set; } + public DbSet LastLogin { get; set; } + public DbSet Message { get; set; } + public DbSet Order { get; set; } + public DbSet OrderNote { get; set; } + public DbSet OrderQualityCheck { get; set; } + public DbSet OrderLine { get; set; } + public DbSet Product { get; set; } + public DbSet ProductDetail { get; set; } + public DbSet ProductReview { get; set; } + public DbSet ProductPhoto { get; set; } + public DbSet ProductWebFeature { get; set; } + public DbSet Supplier { get; set; } + public DbSet SupplierLogo { get; set; } + public DbSet SupplierInfo { get; set; } + public DbSet CustomerInfo { get; set; } + public DbSet Computer { get; set; } + public DbSet ComputerDetail { get; set; } + public DbSet Driver { get; set; } + public DbSet License { get; set; } + + private ObjectResult FunctionImport1(ObjectParameter modifiedDate) + { + return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("FunctionImport1", modifiedDate); + } + + internal virtual ObjectResult FunctionImport2() + { + return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("FunctionImport2"); + } + + internal virtual ObjectResult FunctionImport2(MergeOption mergeOption) + { + return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("FunctionImport2", mergeOption); + } + + public virtual int ParameterTest(byte[] binary, Nullable @bool, Nullable dateTime, Nullable @decimal, Nullable @float, Nullable guid, ObjectParameter @int, ObjectParameter @string) + { + var binaryParameter = binary != null ? + new ObjectParameter("binary", binary) : + new ObjectParameter("binary", typeof(byte[])); + + var boolParameter = @bool.HasValue ? + new ObjectParameter("bool", @bool) : + new ObjectParameter("bool", typeof(bool)); + + var dateTimeParameter = dateTime.HasValue ? + new ObjectParameter("dateTime", dateTime) : + new ObjectParameter("dateTime", typeof(System.DateTime)); + + var decimalParameter = @decimal.HasValue ? + new ObjectParameter("decimal", @decimal) : + new ObjectParameter("decimal", typeof(decimal)); + + var floatParameter = @float.HasValue ? + new ObjectParameter("float", @float) : + new ObjectParameter("float", typeof(double)); + + var guidParameter = guid.HasValue ? + new ObjectParameter("guid", guid) : + new ObjectParameter("guid", typeof(System.Guid)); + + return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("ParameterTest", binaryParameter, boolParameter, dateTimeParameter, decimalParameter, floatParameter, guidParameter, @int, @string); + } + + public virtual ObjectResult EntityTypeTest() + { + return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("EntityTypeTest"); + } + + public virtual ObjectResult EntityTypeTest(MergeOption mergeOption) + { + return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("EntityTypeTest", mergeOption); + } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.Context.tt b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.Context.tt similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.Context.tt rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.Context.tt index 9e0d3a46..34fa0e06 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.Context.tt +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.Context.tt @@ -1,735 +1,735 @@ -<#@ template language="C#" debug="false" hostspecific="true"#> -<#@ include file="EF.Utility.CS.ttinclude"#><#@ - output extension=".cs"#><# - -const string inputFile = @"..\Schemas\MonsterModel.csdl"; -var textTransform = DynamicTextTransformation.Create(this); -var code = new CodeGenerationTools(this); -var ef = new MetadataTools(this); -var typeMapper = new TypeMapper(code, ef, textTransform.Errors); -var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors); -var itemCollection = loader.CreateEdmItemCollection(inputFile); -var modelNamespace = loader.GetModelNamespace(inputFile); -var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); - -var container = itemCollection.OfType().FirstOrDefault(); -if (container == null) -{ - return string.Empty; -} -#> -//------------------------------------------------------------------------------ -// -// <#=GetResourceString("Template_GeneratedCodeCommentLine1")#> -// -// <#=GetResourceString("Template_GeneratedCodeCommentLine2")#> -// <#=GetResourceString("Template_GeneratedCodeCommentLine3")#> -// -//------------------------------------------------------------------------------ - -<# - -var codeNamespace = code.VsNamespaceSuggestion(); -if (!String.IsNullOrEmpty(codeNamespace)) -{ -#> -namespace <#=code.EscapeNamespace(codeNamespace)#> -{ -<# - PushIndent(" "); -} - -#> -using System; -using System.Data.Entity; -using System.Data.Entity.Infrastructure; -<# -if (container.FunctionImports.Any()) -{ -#> -using System.Data.Entity.Core.Objects; -using System.Data.Entity.Core.Objects.DataClasses; -using System.Linq; -<# -} -#> - -<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext -{ - public <#=code.Escape(container)#>() - : base("name=<#=container.Name#>") - { -<# -if (!loader.IsLazyLoadingEnabled(container)) -{ -#> - this.Configuration.LazyLoadingEnabled = false; -<# -} -#> - } - - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - throw new UnintentionalCodeFirstException(); - } - -<# - foreach (var entitySet in container.BaseEntitySets.OfType()) - { -#> - <#=codeStringGenerator.DbSet(entitySet)#> -<# - } - - foreach (var edmFunction in container.FunctionImports) - { - WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false); - } -#> -} -<# - -if (!String.IsNullOrEmpty(codeNamespace)) -{ - PopIndent(); -#> -} -<# -} -#> -<#+ - -private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) -{ - if (typeMapper.IsComposable(edmFunction)) - { -#> - - [EdmFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")] - <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#> - { -<#+ - codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter); -#> - <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#> - } -<#+ - } - else - { -#> - - <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#> - { -<#+ - codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter); -#> - <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#> - } -<#+ - if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption)) - { - WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true); - } - } -} - -public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit) -{ -#> - var <#=name#> = <#=isNotNull#> ? - <#=notNullInit#> : - <#=nullInit#>; - -<#+ -} - -public const string TemplateId = "CSharp_DbContext_Context_EF5"; - -public class CodeStringGenerator -{ - private readonly CodeGenerationTools _code; - private readonly TypeMapper _typeMapper; - private readonly MetadataTools _ef; - - public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef) - { - ArgumentNotNull(code, "code"); - ArgumentNotNull(typeMapper, "typeMapper"); - ArgumentNotNull(ef, "ef"); - - _code = code; - _typeMapper = typeMapper; - _ef = ef; - } - - public string Property(EdmProperty edmProperty) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1} {2} {{ {3}get; {4}set; }}", - Accessibility.ForProperty(edmProperty), - _typeMapper.GetTypeName(edmProperty.TypeUsage), - _code.Escape(edmProperty), - _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), - _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); - } - - public string NavigationProperty(NavigationProperty navigationProperty) - { - var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType()); - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1} {2} {{ {3}get; {4}set; }}", - AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)), - navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, - _code.Escape(navigationProperty), - _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)), - _code.SpaceAfter(Accessibility.ForSetter(navigationProperty))); - } - - public string AccessibilityAndVirtual(string accessibility) - { - return accessibility + (accessibility != "private" ? " virtual" : ""); - } - - public string EntityClassOpening(EntityType entity) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1}partial class {2}{3}", - Accessibility.ForType(entity), - _code.SpaceAfter(_code.AbstractOption(entity)), - _code.Escape(entity), - _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType))); - } - - public string EnumOpening(SimpleType enumType) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} enum {1} : {2}", - Accessibility.ForType(enumType), - _code.Escape(enumType), - _code.Escape(_typeMapper.UnderlyingClrType(enumType))); - } - - public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter) - { - var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); - foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) - { - var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; - var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")"; - var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + parameter.RawClrTypeName + "))"; - writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit); - } - } - - public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace) - { - var parameters = _typeMapper.GetParameters(edmFunction); - - return string.Format( - CultureInfo.InvariantCulture, - "{0} IQueryable<{1}> {2}{3}", - AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), - _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), - _code.Escape(edmFunction), - string.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray())); - } - - public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace) - { - var parameters = _typeMapper.GetParameters(edmFunction); - - return string.Format( - CultureInfo.InvariantCulture, - "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});", - _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), - edmFunction.NamespaceName, - edmFunction.Name, - string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()), - _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))); - } - - public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) - { - var parameters = _typeMapper.GetParameters(edmFunction); - var returnType = _typeMapper.GetReturnType(edmFunction); - - var paramList = String.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray()); - if (includeMergeOption) - { - paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption"; - } - - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1} {2}({3})", - AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), - returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", - _code.Escape(edmFunction), - paramList); - } - - public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) - { - var parameters = _typeMapper.GetParameters(edmFunction); - var returnType = _typeMapper.GetReturnType(edmFunction); - - var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())); - if (includeMergeOption) - { - callParams = ", mergeOption" + callParams; - } - - return string.Format( - CultureInfo.InvariantCulture, - "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});", - returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", - edmFunction.Name, - callParams); - } - - public string DbSet(EntitySet entitySet) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} DbSet<{1}> {2} {{ get; set; }}", - Accessibility.ForReadOnlyProperty(entitySet), - _typeMapper.GetTypeName(entitySet.ElementType), - _code.Escape(entitySet)); - } - - public string UsingDirectives(bool inHeader, bool includeCollections = true) - { - return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion()) - ? string.Format( - CultureInfo.InvariantCulture, - "{0}using System;{1}" + - "{2}", - inHeader ? Environment.NewLine : "", - includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "", - inHeader ? "" : Environment.NewLine) - : ""; - } -} - -public class TypeMapper -{ - private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; - - private readonly System.Collections.IList _errors; - private readonly CodeGenerationTools _code; - private readonly MetadataTools _ef; - - public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors) - { - ArgumentNotNull(code, "code"); - ArgumentNotNull(ef, "ef"); - ArgumentNotNull(errors, "errors"); - - _code = code; - _ef = ef; - _errors = errors; - } - - public string GetTypeName(TypeUsage typeUsage) - { - return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); - } - - public string GetTypeName(EdmType edmType) - { - return GetTypeName(edmType, isNullable: null, modelNamespace: null); - } - - public string GetTypeName(TypeUsage typeUsage, string modelNamespace) - { - return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); - } - - public string GetTypeName(EdmType edmType, string modelNamespace) - { - return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); - } - - public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) - { - if (edmType == null) - { - return null; - } - - var collectionType = edmType as CollectionType; - if (collectionType != null) - { - return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); - } - - var typeName = _code.Escape(edmType.MetadataProperties - .Where(p => p.Name == ExternalTypeNameAttributeName) - .Select(p => (string)p.Value) - .FirstOrDefault()) - ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ? - _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) : - _code.Escape(edmType)); - - if (edmType is StructuralType) - { - return typeName; - } - - if (edmType is SimpleType) - { - var clrType = UnderlyingClrType(edmType); - if (!IsEnumType(edmType)) - { - typeName = _code.Escape(clrType); - } - - return clrType.IsValueType && isNullable == true ? - String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : - typeName; - } - - throw new ArgumentException("edmType"); - } - - public Type UnderlyingClrType(EdmType edmType) - { - ArgumentNotNull(edmType, "edmType"); - - var primitiveType = edmType as PrimitiveType; - if (primitiveType != null) - { - return primitiveType.ClrEquivalentType; - } - - if (IsEnumType(edmType)) - { - return GetEnumUnderlyingType(edmType).ClrEquivalentType; - } - - return typeof(object); - } - - public object GetEnumMemberValue(MetadataItem enumMember) - { - ArgumentNotNull(enumMember, "enumMember"); - - var valueProperty = enumMember.GetType().GetProperty("Value"); - return valueProperty == null ? null : valueProperty.GetValue(enumMember, null); - } - - public string GetEnumMemberName(MetadataItem enumMember) - { - ArgumentNotNull(enumMember, "enumMember"); - - var nameProperty = enumMember.GetType().GetProperty("Name"); - return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null); - } - - public System.Collections.IEnumerable GetEnumMembers(EdmType enumType) - { - ArgumentNotNull(enumType, "enumType"); - - var membersProperty = enumType.GetType().GetProperty("Members"); - return membersProperty != null - ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null) - : Enumerable.Empty(); - } - - public bool EnumIsFlags(EdmType enumType) - { - ArgumentNotNull(enumType, "enumType"); - - var isFlagsProperty = enumType.GetType().GetProperty("IsFlags"); - return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null); - } - - public bool IsEnumType(GlobalItem edmType) - { - ArgumentNotNull(edmType, "edmType"); - - return edmType.GetType().Name == "EnumType"; - } - - public PrimitiveType GetEnumUnderlyingType(EdmType enumType) - { - ArgumentNotNull(enumType, "enumType"); - - return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null); - } - - public string CreateLiteral(object value) - { - if (value == null || value.GetType() != typeof(TimeSpan)) - { - return _code.CreateLiteral(value); - } - - return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks); - } - - public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) - { - ArgumentNotNull(types, "types"); - ArgumentNotNull(sourceFile, "sourceFile"); - - var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); - if (types.Any(item => !hash.Add(item))) - { - _errors.Add( - new CompilerError(sourceFile, -1, -1, "6023", - String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CaseInsensitiveTypeConflict")))); - return false; - } - return true; - } - - public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection) - { - return GetItemsToGenerate(itemCollection) - .Where(e => IsEnumType(e)); - } - - public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType - { - return itemCollection - .OfType() - .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) - .OrderBy(i => i.Name); - } - - public IEnumerable GetAllGlobalItems(IEnumerable itemCollection) - { - return itemCollection - .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i)) - .Select(g => GetGlobalItemName(g)); - } - - public string GetGlobalItemName(GlobalItem item) - { - if (item is EdmType) - { - return ((EdmType)item).Name; - } - else - { - return ((EntityContainer)item).Name; - } - } - - public IEnumerable GetSimpleProperties(EntityType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); - } - - public IEnumerable GetSimpleProperties(ComplexType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); - } - - public IEnumerable GetComplexProperties(EntityType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); - } - - public IEnumerable GetComplexProperties(ComplexType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); - } - - public IEnumerable GetPropertiesWithDefaultValues(EntityType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); - } - - public IEnumerable GetPropertiesWithDefaultValues(ComplexType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); - } - - public IEnumerable GetNavigationProperties(EntityType type) - { - return type.NavigationProperties.Where(np => np.DeclaringType == type); - } - - public IEnumerable GetCollectionNavigationProperties(EntityType type) - { - return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many); - } - - public FunctionParameter GetReturnParameter(EdmFunction edmFunction) - { - ArgumentNotNull(edmFunction, "edmFunction"); - - var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters"); - return returnParamsProperty == null - ? edmFunction.ReturnParameter - : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault(); - } - - public bool IsComposable(EdmFunction edmFunction) - { - ArgumentNotNull(edmFunction, "edmFunction"); - - var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute"); - return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null); - } - - public IEnumerable GetParameters(EdmFunction edmFunction) - { - return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); - } - - public TypeUsage GetReturnType(EdmFunction edmFunction) - { - var returnParam = GetReturnParameter(edmFunction); - return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage); - } - - public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption) - { - var returnType = GetReturnType(edmFunction); - return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType; - } -} - -public class EdmMetadataLoader -{ - private readonly IDynamicHost _host; - private readonly System.Collections.IList _errors; - - public EdmMetadataLoader(IDynamicHost host, System.Collections.IList errors) - { - ArgumentNotNull(host, "host"); - ArgumentNotNull(errors, "errors"); - - _host = host; - _errors = errors; - } - - public IEnumerable CreateEdmItemCollection(string sourcePath) - { - ArgumentNotNull(sourcePath, "sourcePath"); - - if (!ValidateInputPath(sourcePath)) - { - return new EdmItemCollection(); - } - - var schemaElement = LoadRootElement(_host.ResolvePath(sourcePath)); - if (schemaElement != null) - { - using (var reader = schemaElement.CreateReader()) - { - IList errors; - var itemCollection = MetadataItemCollectionFactory.CreateEdmItemCollection(new[] { reader }, out errors); - - ProcessErrors(errors, sourcePath); - - return itemCollection; - } - } - return new EdmItemCollection(); - } - - public string GetModelNamespace(string sourcePath) - { - ArgumentNotNull(sourcePath, "sourcePath"); - - if (!ValidateInputPath(sourcePath)) - { - return string.Empty; - } - - var model = LoadRootElement(_host.ResolvePath(sourcePath)); - if (model == null) - { - return string.Empty; - } - - var attribute = model.Attribute("Namespace"); - return attribute != null ? attribute.Value : ""; - } - - private bool ValidateInputPath(string sourcePath) - { - if (sourcePath == "$" + "edmxInputFile" + "$") - { - _errors.Add( - new CompilerError(_host.TemplateFile ?? sourcePath, 0, 0, string.Empty, - GetResourceString("Template_ReplaceVsItemTemplateToken"))); - return false; - } - - return true; - } - - public XElement LoadRootElement(string sourcePath) - { - ArgumentNotNull(sourcePath, "sourcePath"); - - var root = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); - return root.Elements() - .Where(e => e.Name.LocalName == "Runtime") - .Elements() - .Where(e => e.Name.LocalName == "ConceptualModels") - .Elements() - .Where(e => e.Name.LocalName == "Schema") - .FirstOrDefault() - ?? root; - } - - private void ProcessErrors(IEnumerable errors, string sourceFilePath) - { - foreach (var error in errors) - { - _errors.Add( - new CompilerError( - error.SchemaLocation ?? sourceFilePath, - error.Line, - error.Column, - error.ErrorCode.ToString(CultureInfo.InvariantCulture), - error.Message) - { - IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning - }); - } - } - - public bool IsLazyLoadingEnabled(EntityContainer container) - { - string lazyLoadingAttributeValue; - var lazyLoadingAttributeName = MetadataConstants.EDM_ANNOTATION_09_02 + ":LazyLoadingEnabled"; - bool isLazyLoading; - return !MetadataTools.TryGetStringMetadataPropertySetting(container, lazyLoadingAttributeName, out lazyLoadingAttributeValue) - || !bool.TryParse(lazyLoadingAttributeValue, out isLazyLoading) - || isLazyLoading; - } -} - -public static void ArgumentNotNull(T arg, string name) where T : class -{ - if (arg == null) - { - throw new ArgumentNullException(name); - } -} - -private static readonly Lazy ResourceManager = - new Lazy( - () => new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(MetadataItemCollectionFactory).Assembly), isThreadSafe: true); - -public static string GetResourceString(string resourceName) -{ - ArgumentNotNull(resourceName, "resourceName"); - - return ResourceManager.Value.GetString(resourceName, null); -} - +<#@ template language="C#" debug="false" hostspecific="true"#> +<#@ include file="EF.Utility.CS.ttinclude"#><#@ + output extension=".cs"#><# + +const string inputFile = @"..\Schemas\MonsterModel.csdl"; +var textTransform = DynamicTextTransformation.Create(this); +var code = new CodeGenerationTools(this); +var ef = new MetadataTools(this); +var typeMapper = new TypeMapper(code, ef, textTransform.Errors); +var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors); +var itemCollection = loader.CreateEdmItemCollection(inputFile); +var modelNamespace = loader.GetModelNamespace(inputFile); +var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); + +var container = itemCollection.OfType().FirstOrDefault(); +if (container == null) +{ + return string.Empty; +} +#> +//------------------------------------------------------------------------------ +// +// <#=GetResourceString("Template_GeneratedCodeCommentLine1")#> +// +// <#=GetResourceString("Template_GeneratedCodeCommentLine2")#> +// <#=GetResourceString("Template_GeneratedCodeCommentLine3")#> +// +//------------------------------------------------------------------------------ + +<# + +var codeNamespace = code.VsNamespaceSuggestion(); +if (!String.IsNullOrEmpty(codeNamespace)) +{ +#> +namespace <#=code.EscapeNamespace(codeNamespace)#> +{ +<# + PushIndent(" "); +} + +#> +using System; +using System.Data.Entity; +using System.Data.Entity.Infrastructure; +<# +if (container.FunctionImports.Any()) +{ +#> +using System.Data.Entity.Core.Objects; +using System.Data.Entity.Core.Objects.DataClasses; +using System.Linq; +<# +} +#> + +<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext +{ + public <#=code.Escape(container)#>() + : base("name=<#=container.Name#>") + { +<# +if (!loader.IsLazyLoadingEnabled(container)) +{ +#> + this.Configuration.LazyLoadingEnabled = false; +<# +} +#> + } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + throw new UnintentionalCodeFirstException(); + } + +<# + foreach (var entitySet in container.BaseEntitySets.OfType()) + { +#> + <#=codeStringGenerator.DbSet(entitySet)#> +<# + } + + foreach (var edmFunction in container.FunctionImports) + { + WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false); + } +#> +} +<# + +if (!String.IsNullOrEmpty(codeNamespace)) +{ + PopIndent(); +#> +} +<# +} +#> +<#+ + +private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) +{ + if (typeMapper.IsComposable(edmFunction)) + { +#> + + [EdmFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")] + <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#> + { +<#+ + codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter); +#> + <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#> + } +<#+ + } + else + { +#> + + <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#> + { +<#+ + codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter); +#> + <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#> + } +<#+ + if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption)) + { + WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true); + } + } +} + +public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit) +{ +#> + var <#=name#> = <#=isNotNull#> ? + <#=notNullInit#> : + <#=nullInit#>; + +<#+ +} + +public const string TemplateId = "CSharp_DbContext_Context_EF5"; + +public class CodeStringGenerator +{ + private readonly CodeGenerationTools _code; + private readonly TypeMapper _typeMapper; + private readonly MetadataTools _ef; + + public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef) + { + ArgumentNotNull(code, "code"); + ArgumentNotNull(typeMapper, "typeMapper"); + ArgumentNotNull(ef, "ef"); + + _code = code; + _typeMapper = typeMapper; + _ef = ef; + } + + public string Property(EdmProperty edmProperty) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2} {{ {3}get; {4}set; }}", + Accessibility.ForProperty(edmProperty), + _typeMapper.GetTypeName(edmProperty.TypeUsage), + _code.Escape(edmProperty), + _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), + _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); + } + + public string NavigationProperty(NavigationProperty navigationProperty) + { + var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType()); + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2} {{ {3}get; {4}set; }}", + AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)), + navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, + _code.Escape(navigationProperty), + _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)), + _code.SpaceAfter(Accessibility.ForSetter(navigationProperty))); + } + + public string AccessibilityAndVirtual(string accessibility) + { + return accessibility + (accessibility != "private" ? " virtual" : ""); + } + + public string EntityClassOpening(EntityType entity) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1}partial class {2}{3}", + Accessibility.ForType(entity), + _code.SpaceAfter(_code.AbstractOption(entity)), + _code.Escape(entity), + _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType))); + } + + public string EnumOpening(SimpleType enumType) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} enum {1} : {2}", + Accessibility.ForType(enumType), + _code.Escape(enumType), + _code.Escape(_typeMapper.UnderlyingClrType(enumType))); + } + + public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter) + { + var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); + foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) + { + var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; + var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")"; + var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + parameter.RawClrTypeName + "))"; + writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit); + } + } + + public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace) + { + var parameters = _typeMapper.GetParameters(edmFunction); + + return string.Format( + CultureInfo.InvariantCulture, + "{0} IQueryable<{1}> {2}{3}", + AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), + _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), + _code.Escape(edmFunction), + string.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray())); + } + + public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace) + { + var parameters = _typeMapper.GetParameters(edmFunction); + + return string.Format( + CultureInfo.InvariantCulture, + "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});", + _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), + edmFunction.NamespaceName, + edmFunction.Name, + string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()), + _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))); + } + + public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) + { + var parameters = _typeMapper.GetParameters(edmFunction); + var returnType = _typeMapper.GetReturnType(edmFunction); + + var paramList = String.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray()); + if (includeMergeOption) + { + paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption"; + } + + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2}({3})", + AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), + returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", + _code.Escape(edmFunction), + paramList); + } + + public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) + { + var parameters = _typeMapper.GetParameters(edmFunction); + var returnType = _typeMapper.GetReturnType(edmFunction); + + var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())); + if (includeMergeOption) + { + callParams = ", mergeOption" + callParams; + } + + return string.Format( + CultureInfo.InvariantCulture, + "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});", + returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", + edmFunction.Name, + callParams); + } + + public string DbSet(EntitySet entitySet) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} DbSet<{1}> {2} {{ get; set; }}", + Accessibility.ForReadOnlyProperty(entitySet), + _typeMapper.GetTypeName(entitySet.ElementType), + _code.Escape(entitySet)); + } + + public string UsingDirectives(bool inHeader, bool includeCollections = true) + { + return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion()) + ? string.Format( + CultureInfo.InvariantCulture, + "{0}using System;{1}" + + "{2}", + inHeader ? Environment.NewLine : "", + includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "", + inHeader ? "" : Environment.NewLine) + : ""; + } +} + +public class TypeMapper +{ + private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; + + private readonly System.Collections.IList _errors; + private readonly CodeGenerationTools _code; + private readonly MetadataTools _ef; + + public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors) + { + ArgumentNotNull(code, "code"); + ArgumentNotNull(ef, "ef"); + ArgumentNotNull(errors, "errors"); + + _code = code; + _ef = ef; + _errors = errors; + } + + public string GetTypeName(TypeUsage typeUsage) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); + } + + public string GetTypeName(EdmType edmType) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: null); + } + + public string GetTypeName(TypeUsage typeUsage, string modelNamespace) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); + } + + public string GetTypeName(EdmType edmType, string modelNamespace) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); + } + + public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) + { + if (edmType == null) + { + return null; + } + + var collectionType = edmType as CollectionType; + if (collectionType != null) + { + return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); + } + + var typeName = _code.Escape(edmType.MetadataProperties + .Where(p => p.Name == ExternalTypeNameAttributeName) + .Select(p => (string)p.Value) + .FirstOrDefault()) + ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ? + _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) : + _code.Escape(edmType)); + + if (edmType is StructuralType) + { + return typeName; + } + + if (edmType is SimpleType) + { + var clrType = UnderlyingClrType(edmType); + if (!IsEnumType(edmType)) + { + typeName = _code.Escape(clrType); + } + + return clrType.IsValueType && isNullable == true ? + String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : + typeName; + } + + throw new ArgumentException("edmType"); + } + + public Type UnderlyingClrType(EdmType edmType) + { + ArgumentNotNull(edmType, "edmType"); + + var primitiveType = edmType as PrimitiveType; + if (primitiveType != null) + { + return primitiveType.ClrEquivalentType; + } + + if (IsEnumType(edmType)) + { + return GetEnumUnderlyingType(edmType).ClrEquivalentType; + } + + return typeof(object); + } + + public object GetEnumMemberValue(MetadataItem enumMember) + { + ArgumentNotNull(enumMember, "enumMember"); + + var valueProperty = enumMember.GetType().GetProperty("Value"); + return valueProperty == null ? null : valueProperty.GetValue(enumMember, null); + } + + public string GetEnumMemberName(MetadataItem enumMember) + { + ArgumentNotNull(enumMember, "enumMember"); + + var nameProperty = enumMember.GetType().GetProperty("Name"); + return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null); + } + + public System.Collections.IEnumerable GetEnumMembers(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + var membersProperty = enumType.GetType().GetProperty("Members"); + return membersProperty != null + ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null) + : Enumerable.Empty(); + } + + public bool EnumIsFlags(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + var isFlagsProperty = enumType.GetType().GetProperty("IsFlags"); + return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null); + } + + public bool IsEnumType(GlobalItem edmType) + { + ArgumentNotNull(edmType, "edmType"); + + return edmType.GetType().Name == "EnumType"; + } + + public PrimitiveType GetEnumUnderlyingType(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null); + } + + public string CreateLiteral(object value) + { + if (value == null || value.GetType() != typeof(TimeSpan)) + { + return _code.CreateLiteral(value); + } + + return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks); + } + + public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) + { + ArgumentNotNull(types, "types"); + ArgumentNotNull(sourceFile, "sourceFile"); + + var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); + if (types.Any(item => !hash.Add(item))) + { + _errors.Add( + new CompilerError(sourceFile, -1, -1, "6023", + String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CaseInsensitiveTypeConflict")))); + return false; + } + return true; + } + + public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection) + { + return GetItemsToGenerate(itemCollection) + .Where(e => IsEnumType(e)); + } + + public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType + { + return itemCollection + .OfType() + .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) + .OrderBy(i => i.Name); + } + + public IEnumerable GetAllGlobalItems(IEnumerable itemCollection) + { + return itemCollection + .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i)) + .Select(g => GetGlobalItemName(g)); + } + + public string GetGlobalItemName(GlobalItem item) + { + if (item is EdmType) + { + return ((EdmType)item).Name; + } + else + { + return ((EntityContainer)item).Name; + } + } + + public IEnumerable GetSimpleProperties(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); + } + + public IEnumerable GetSimpleProperties(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); + } + + public IEnumerable GetComplexProperties(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); + } + + public IEnumerable GetComplexProperties(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); + } + + public IEnumerable GetPropertiesWithDefaultValues(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); + } + + public IEnumerable GetPropertiesWithDefaultValues(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); + } + + public IEnumerable GetNavigationProperties(EntityType type) + { + return type.NavigationProperties.Where(np => np.DeclaringType == type); + } + + public IEnumerable GetCollectionNavigationProperties(EntityType type) + { + return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many); + } + + public FunctionParameter GetReturnParameter(EdmFunction edmFunction) + { + ArgumentNotNull(edmFunction, "edmFunction"); + + var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters"); + return returnParamsProperty == null + ? edmFunction.ReturnParameter + : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault(); + } + + public bool IsComposable(EdmFunction edmFunction) + { + ArgumentNotNull(edmFunction, "edmFunction"); + + var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute"); + return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null); + } + + public IEnumerable GetParameters(EdmFunction edmFunction) + { + return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); + } + + public TypeUsage GetReturnType(EdmFunction edmFunction) + { + var returnParam = GetReturnParameter(edmFunction); + return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage); + } + + public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption) + { + var returnType = GetReturnType(edmFunction); + return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType; + } +} + +public class EdmMetadataLoader +{ + private readonly IDynamicHost _host; + private readonly System.Collections.IList _errors; + + public EdmMetadataLoader(IDynamicHost host, System.Collections.IList errors) + { + ArgumentNotNull(host, "host"); + ArgumentNotNull(errors, "errors"); + + _host = host; + _errors = errors; + } + + public IEnumerable CreateEdmItemCollection(string sourcePath) + { + ArgumentNotNull(sourcePath, "sourcePath"); + + if (!ValidateInputPath(sourcePath)) + { + return new EdmItemCollection(); + } + + var schemaElement = LoadRootElement(_host.ResolvePath(sourcePath)); + if (schemaElement != null) + { + using (var reader = schemaElement.CreateReader()) + { + IList errors; + var itemCollection = MetadataItemCollectionFactory.CreateEdmItemCollection(new[] { reader }, out errors); + + ProcessErrors(errors, sourcePath); + + return itemCollection; + } + } + return new EdmItemCollection(); + } + + public string GetModelNamespace(string sourcePath) + { + ArgumentNotNull(sourcePath, "sourcePath"); + + if (!ValidateInputPath(sourcePath)) + { + return string.Empty; + } + + var model = LoadRootElement(_host.ResolvePath(sourcePath)); + if (model == null) + { + return string.Empty; + } + + var attribute = model.Attribute("Namespace"); + return attribute != null ? attribute.Value : ""; + } + + private bool ValidateInputPath(string sourcePath) + { + if (sourcePath == "$" + "edmxInputFile" + "$") + { + _errors.Add( + new CompilerError(_host.TemplateFile ?? sourcePath, 0, 0, string.Empty, + GetResourceString("Template_ReplaceVsItemTemplateToken"))); + return false; + } + + return true; + } + + public XElement LoadRootElement(string sourcePath) + { + ArgumentNotNull(sourcePath, "sourcePath"); + + var root = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); + return root.Elements() + .Where(e => e.Name.LocalName == "Runtime") + .Elements() + .Where(e => e.Name.LocalName == "ConceptualModels") + .Elements() + .Where(e => e.Name.LocalName == "Schema") + .FirstOrDefault() + ?? root; + } + + private void ProcessErrors(IEnumerable errors, string sourceFilePath) + { + foreach (var error in errors) + { + _errors.Add( + new CompilerError( + error.SchemaLocation ?? sourceFilePath, + error.Line, + error.Column, + error.ErrorCode.ToString(CultureInfo.InvariantCulture), + error.Message) + { + IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning + }); + } + } + + public bool IsLazyLoadingEnabled(EntityContainer container) + { + string lazyLoadingAttributeValue; + var lazyLoadingAttributeName = MetadataConstants.EDM_ANNOTATION_09_02 + ":LazyLoadingEnabled"; + bool isLazyLoading; + return !MetadataTools.TryGetStringMetadataPropertySetting(container, lazyLoadingAttributeName, out lazyLoadingAttributeValue) + || !bool.TryParse(lazyLoadingAttributeValue, out isLazyLoading) + || isLazyLoading; + } +} + +public static void ArgumentNotNull(T arg, string name) where T : class +{ + if (arg == null) + { + throw new ArgumentNullException(name); + } +} + +private static readonly Lazy ResourceManager = + new Lazy( + () => new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(MetadataItemCollectionFactory).Assembly), isThreadSafe: true); + +public static string GetResourceString(string resourceName) +{ + ArgumentNotNull(resourceName, "resourceName"); + + return ResourceManager.Value.GetString(resourceName, null); +} + #> \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.cs index 90e37bda..fb52571e 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.cs @@ -1,9 +1,9 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.tt b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.tt similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.tt rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.tt index acbcd6c9..97129ce6 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.tt +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/CsMonsterModel.tt @@ -1,845 +1,845 @@ -<#@ template language="C#" debug="false" hostspecific="true"#> -<#@ include file="EF.Utility.CS.ttinclude"#><#@ - output extension=".cs"#><# - -const string inputFile = @"..\Schemas\MonsterModel.csdl"; -var textTransform = DynamicTextTransformation.Create(this); -var code = new CodeGenerationTools(this); -var ef = new MetadataTools(this); -var typeMapper = new TypeMapper(code, ef, textTransform.Errors); -var fileManager = EntityFrameworkTemplateFileManager.Create(this); -var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile); -var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); - -if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile)) -{ - return string.Empty; -} - -WriteHeader(codeStringGenerator, fileManager); - -foreach (var entity in typeMapper.GetItemsToGenerate(itemCollection)) -{ - fileManager.StartNewFile(entity.Name + ".cs"); - BeginNamespace(code); -#> -<#=codeStringGenerator.UsingDirectives(inHeader: false)#> -<#=codeStringGenerator.EntityClassOpening(entity)#> -{ -<# - var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity); - var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity); - var complexProperties = typeMapper.GetComplexProperties(entity); - - if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any()) - { -#> - public <#=code.Escape(entity)#>() - { -<# - foreach (var edmProperty in propertiesWithDefaultValues) - { -#> - this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>; -<# - } - - foreach (var navigationProperty in collectionNavigationProperties) - { -#> - this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>(); -<# - } - - foreach (var complexProperty in complexProperties) - { -#> - this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>(); -<# - } -#> - } - -<# - } - - var simpleProperties = typeMapper.GetSimpleProperties(entity); - if (simpleProperties.Any()) - { - foreach (var edmProperty in simpleProperties) - { -#> - <#=codeStringGenerator.Property(edmProperty)#> -<# - } - } - - if (complexProperties.Any()) - { -#> - -<# - foreach(var complexProperty in complexProperties) - { -#> - <#=codeStringGenerator.Property(complexProperty)#> -<# - } - } - - var navigationProperties = typeMapper.GetNavigationProperties(entity); - if (navigationProperties.Any()) - { -#> - -<# - foreach (var navigationProperty in navigationProperties) - { -#> - <#=codeStringGenerator.NavigationProperty(navigationProperty)#> -<# - } - } -#> -} -<# - EndNamespace(code); -} - -foreach (var complex in typeMapper.GetItemsToGenerate(itemCollection)) -{ - fileManager.StartNewFile(complex.Name + ".cs"); - BeginNamespace(code); -#> -<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#> -<#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#> -{ -<# - var complexProperties = typeMapper.GetComplexProperties(complex); - var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex); - - if (propertiesWithDefaultValues.Any() || complexProperties.Any()) - { -#> - public <#=code.Escape(complex)#>() - { -<# - foreach (var edmProperty in propertiesWithDefaultValues) - { -#> - this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>; -<# - } - - foreach (var complexProperty in complexProperties) - { -#> - this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>(); -<# - } -#> - } - -<# - } - - var simpleProperties = typeMapper.GetSimpleProperties(complex); - if (simpleProperties.Any()) - { - foreach(var edmProperty in simpleProperties) - { -#> - <#=codeStringGenerator.Property(edmProperty)#> -<# - } - } - - if (complexProperties.Any()) - { -#> - -<# - foreach(var edmProperty in complexProperties) - { -#> - <#=codeStringGenerator.Property(edmProperty)#> -<# - } - } -#> -} -<# - EndNamespace(code); -} - -foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection)) -{ - fileManager.StartNewFile(enumType.Name + ".cs"); - BeginNamespace(code); -#> -<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#> -<# - if (typeMapper.EnumIsFlags(enumType)) - { -#> -[Flags] -<# - } -#> -<#=codeStringGenerator.EnumOpening(enumType)#> -{ -<# - var foundOne = false; - - foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType)) - { - foundOne = true; -#> - <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>, -<# - } - - if (foundOne) - { - this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1); - } -#> -} -<# - EndNamespace(code); -} - -fileManager.Process(); - -#> -<#+ - -public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager) -{ - fileManager.StartHeader(); -#> -//------------------------------------------------------------------------------ -// -// <#=GetResourceString("Template_GeneratedCodeCommentLine1")#> -// -// <#=GetResourceString("Template_GeneratedCodeCommentLine2")#> -// <#=GetResourceString("Template_GeneratedCodeCommentLine3")#> -// -//------------------------------------------------------------------------------ -<#=codeStringGenerator.UsingDirectives(inHeader: true)#> -<#+ - fileManager.EndBlock(); -} - -public void BeginNamespace(CodeGenerationTools code) -{ - var codeNamespace = code.VsNamespaceSuggestion(); - if (!String.IsNullOrEmpty(codeNamespace)) - { -#> -namespace <#=code.EscapeNamespace(codeNamespace)#> -{ -<#+ - PushIndent(" "); - } -} - -public void EndNamespace(CodeGenerationTools code) -{ - if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion())) - { - PopIndent(); -#> -} -<#+ - } -} - -public const string TemplateId = "CSharp_DbContext_Types_EF5"; - -public class CodeStringGenerator -{ - private readonly CodeGenerationTools _code; - private readonly TypeMapper _typeMapper; - private readonly MetadataTools _ef; - - public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef) - { - ArgumentNotNull(code, "code"); - ArgumentNotNull(typeMapper, "typeMapper"); - ArgumentNotNull(ef, "ef"); - - _code = code; - _typeMapper = typeMapper; - _ef = ef; - } - - public string Property(EdmProperty edmProperty) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1} {2} {{ {3}get; {4}set; }}", - Accessibility.ForProperty(edmProperty), - _typeMapper.GetTypeName(edmProperty.TypeUsage), - _code.Escape(edmProperty), - _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), - _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); - } - - public string NavigationProperty(NavigationProperty navigationProperty) - { - var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType()); - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1} {2} {{ {3}get; {4}set; }}", - AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)), - navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, - _code.Escape(navigationProperty), - _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)), - _code.SpaceAfter(Accessibility.ForSetter(navigationProperty))); - } - - public string AccessibilityAndVirtual(string accessibility) - { - return accessibility + (accessibility != "private" ? " virtual" : ""); - } - - public string EntityClassOpening(EntityType entity) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1}partial class {2}{3}", - Accessibility.ForType(entity), - _code.SpaceAfter(_code.AbstractOption(entity)), - _code.Escape(entity), - _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType))); - } - - public string EnumOpening(SimpleType enumType) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} enum {1} : {2}", - Accessibility.ForType(enumType), - _code.Escape(enumType), - _code.Escape(_typeMapper.UnderlyingClrType(enumType))); - } - - public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter) - { - var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); - foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) - { - var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; - var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")"; - var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + parameter.RawClrTypeName + "))"; - writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit); - } - } - - public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace) - { - var parameters = _typeMapper.GetParameters(edmFunction); - - return string.Format( - CultureInfo.InvariantCulture, - "{0} IQueryable<{1}> {2}{3}", - AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), - _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), - _code.Escape(edmFunction), - string.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray())); - } - - public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace) - { - var parameters = _typeMapper.GetParameters(edmFunction); - - return string.Format( - CultureInfo.InvariantCulture, - "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});", - _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), - edmFunction.NamespaceName, - edmFunction.Name, - string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()), - _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))); - } - - public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) - { - var parameters = _typeMapper.GetParameters(edmFunction); - var returnType = _typeMapper.GetReturnType(edmFunction); - - var paramList = String.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray()); - if (includeMergeOption) - { - paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption"; - } - - return string.Format( - CultureInfo.InvariantCulture, - "{0} {1} {2}({3})", - AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), - returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", - _code.Escape(edmFunction), - paramList); - } - - public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) - { - var parameters = _typeMapper.GetParameters(edmFunction); - var returnType = _typeMapper.GetReturnType(edmFunction); - - var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())); - if (includeMergeOption) - { - callParams = ", mergeOption" + callParams; - } - - return string.Format( - CultureInfo.InvariantCulture, - "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});", - returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", - edmFunction.Name, - callParams); - } - - public string DbSet(EntitySet entitySet) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0} DbSet<{1}> {2} {{ get; set; }}", - Accessibility.ForReadOnlyProperty(entitySet), - _typeMapper.GetTypeName(entitySet.ElementType), - _code.Escape(entitySet)); - } - - public string UsingDirectives(bool inHeader, bool includeCollections = true) - { - return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion()) - ? string.Format( - CultureInfo.InvariantCulture, - "{0}using System;{1}" + - "{2}", - inHeader ? Environment.NewLine : "", - includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "", - inHeader ? "" : Environment.NewLine) - : ""; - } -} - -public class TypeMapper -{ - private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; - - private readonly System.Collections.IList _errors; - private readonly CodeGenerationTools _code; - private readonly MetadataTools _ef; - - public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors) - { - ArgumentNotNull(code, "code"); - ArgumentNotNull(ef, "ef"); - ArgumentNotNull(errors, "errors"); - - _code = code; - _ef = ef; - _errors = errors; - } - - public string GetTypeName(TypeUsage typeUsage) - { - return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); - } - - public string GetTypeName(EdmType edmType) - { - return GetTypeName(edmType, isNullable: null, modelNamespace: null); - } - - public string GetTypeName(TypeUsage typeUsage, string modelNamespace) - { - return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); - } - - public string GetTypeName(EdmType edmType, string modelNamespace) - { - return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); - } - - public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) - { - if (edmType == null) - { - return null; - } - - var collectionType = edmType as CollectionType; - if (collectionType != null) - { - return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); - } - - var typeName = _code.Escape(edmType.MetadataProperties - .Where(p => p.Name == ExternalTypeNameAttributeName) - .Select(p => (string)p.Value) - .FirstOrDefault()) - ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ? - _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) : - _code.Escape(edmType)); - - if (edmType is StructuralType) - { - return typeName; - } - - if (edmType is SimpleType) - { - var clrType = UnderlyingClrType(edmType); - if (!IsEnumType(edmType)) - { - typeName = _code.Escape(clrType); - } - - return clrType.IsValueType && isNullable == true ? - String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : - typeName; - } - - throw new ArgumentException("edmType"); - } - - public Type UnderlyingClrType(EdmType edmType) - { - ArgumentNotNull(edmType, "edmType"); - - var primitiveType = edmType as PrimitiveType; - if (primitiveType != null) - { - return primitiveType.ClrEquivalentType; - } - - if (IsEnumType(edmType)) - { - return GetEnumUnderlyingType(edmType).ClrEquivalentType; - } - - return typeof(object); - } - - public object GetEnumMemberValue(MetadataItem enumMember) - { - ArgumentNotNull(enumMember, "enumMember"); - - var valueProperty = enumMember.GetType().GetProperty("Value"); - return valueProperty == null ? null : valueProperty.GetValue(enumMember, null); - } - - public string GetEnumMemberName(MetadataItem enumMember) - { - ArgumentNotNull(enumMember, "enumMember"); - - var nameProperty = enumMember.GetType().GetProperty("Name"); - return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null); - } - - public System.Collections.IEnumerable GetEnumMembers(EdmType enumType) - { - ArgumentNotNull(enumType, "enumType"); - - var membersProperty = enumType.GetType().GetProperty("Members"); - return membersProperty != null - ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null) - : Enumerable.Empty(); - } - - public bool EnumIsFlags(EdmType enumType) - { - ArgumentNotNull(enumType, "enumType"); - - var isFlagsProperty = enumType.GetType().GetProperty("IsFlags"); - return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null); - } - - public bool IsEnumType(GlobalItem edmType) - { - ArgumentNotNull(edmType, "edmType"); - - return edmType.GetType().Name == "EnumType"; - } - - public PrimitiveType GetEnumUnderlyingType(EdmType enumType) - { - ArgumentNotNull(enumType, "enumType"); - - return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null); - } - - public string CreateLiteral(object value) - { - if (value == null || value.GetType() != typeof(TimeSpan)) - { - return _code.CreateLiteral(value); - } - - return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks); - } - - public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) - { - ArgumentNotNull(types, "types"); - ArgumentNotNull(sourceFile, "sourceFile"); - - var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); - if (types.Any(item => !hash.Add(item))) - { - _errors.Add( - new CompilerError(sourceFile, -1, -1, "6023", - String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CaseInsensitiveTypeConflict")))); - return false; - } - return true; - } - - public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection) - { - return GetItemsToGenerate(itemCollection) - .Where(e => IsEnumType(e)); - } - - public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType - { - return itemCollection - .OfType() - .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) - .OrderBy(i => i.Name); - } - - public IEnumerable GetAllGlobalItems(IEnumerable itemCollection) - { - return itemCollection - .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i)) - .Select(g => GetGlobalItemName(g)); - } - - public string GetGlobalItemName(GlobalItem item) - { - if (item is EdmType) - { - return ((EdmType)item).Name; - } - else - { - return ((EntityContainer)item).Name; - } - } - - public IEnumerable GetSimpleProperties(EntityType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); - } - - public IEnumerable GetSimpleProperties(ComplexType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); - } - - public IEnumerable GetComplexProperties(EntityType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); - } - - public IEnumerable GetComplexProperties(ComplexType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); - } - - public IEnumerable GetPropertiesWithDefaultValues(EntityType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); - } - - public IEnumerable GetPropertiesWithDefaultValues(ComplexType type) - { - return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); - } - - public IEnumerable GetNavigationProperties(EntityType type) - { - return type.NavigationProperties.Where(np => np.DeclaringType == type); - } - - public IEnumerable GetCollectionNavigationProperties(EntityType type) - { - return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many); - } - - public FunctionParameter GetReturnParameter(EdmFunction edmFunction) - { - ArgumentNotNull(edmFunction, "edmFunction"); - - var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters"); - return returnParamsProperty == null - ? edmFunction.ReturnParameter - : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault(); - } - - public bool IsComposable(EdmFunction edmFunction) - { - ArgumentNotNull(edmFunction, "edmFunction"); - - var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute"); - return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null); - } - - public IEnumerable GetParameters(EdmFunction edmFunction) - { - return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); - } - - public TypeUsage GetReturnType(EdmFunction edmFunction) - { - var returnParam = GetReturnParameter(edmFunction); - return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage); - } - - public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption) - { - var returnType = GetReturnType(edmFunction); - return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType; - } -} - -public class EdmMetadataLoader -{ - private readonly IDynamicHost _host; - private readonly System.Collections.IList _errors; - - public EdmMetadataLoader(IDynamicHost host, System.Collections.IList errors) - { - ArgumentNotNull(host, "host"); - ArgumentNotNull(errors, "errors"); - - _host = host; - _errors = errors; - } - - public IEnumerable CreateEdmItemCollection(string sourcePath) - { - ArgumentNotNull(sourcePath, "sourcePath"); - - if (!ValidateInputPath(sourcePath)) - { - return new EdmItemCollection(); - } - - var schemaElement = LoadRootElement(_host.ResolvePath(sourcePath)); - if (schemaElement != null) - { - using (var reader = schemaElement.CreateReader()) - { - IList errors; - var itemCollection = MetadataItemCollectionFactory.CreateEdmItemCollection(new[] { reader }, out errors); - - ProcessErrors(errors, sourcePath); - - return itemCollection; - } - } - return new EdmItemCollection(); - } - - public string GetModelNamespace(string sourcePath) - { - ArgumentNotNull(sourcePath, "sourcePath"); - - if (!ValidateInputPath(sourcePath)) - { - return string.Empty; - } - - var model = LoadRootElement(_host.ResolvePath(sourcePath)); - if (model == null) - { - return string.Empty; - } - - var attribute = model.Attribute("Namespace"); - return attribute != null ? attribute.Value : ""; - } - - private bool ValidateInputPath(string sourcePath) - { - if (sourcePath == "$" + "edmxInputFile" + "$") - { - _errors.Add( - new CompilerError(_host.TemplateFile ?? sourcePath, 0, 0, string.Empty, - GetResourceString("Template_ReplaceVsItemTemplateToken"))); - return false; - } - - return true; - } - - public XElement LoadRootElement(string sourcePath) - { - ArgumentNotNull(sourcePath, "sourcePath"); - - var root = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); - return root.Elements() - .Where(e => e.Name.LocalName == "Runtime") - .Elements() - .Where(e => e.Name.LocalName == "ConceptualModels") - .Elements() - .Where(e => e.Name.LocalName == "Schema") - .FirstOrDefault() - ?? root; - } - - private void ProcessErrors(IEnumerable errors, string sourceFilePath) - { - foreach (var error in errors) - { - _errors.Add( - new CompilerError( - error.SchemaLocation ?? sourceFilePath, - error.Line, - error.Column, - error.ErrorCode.ToString(CultureInfo.InvariantCulture), - error.Message) - { - IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning - }); - } - } - - public bool IsLazyLoadingEnabled(EntityContainer container) - { - string lazyLoadingAttributeValue; - var lazyLoadingAttributeName = MetadataConstants.EDM_ANNOTATION_09_02 + ":LazyLoadingEnabled"; - bool isLazyLoading; - return !MetadataTools.TryGetStringMetadataPropertySetting(container, lazyLoadingAttributeName, out lazyLoadingAttributeValue) - || !bool.TryParse(lazyLoadingAttributeValue, out isLazyLoading) - || isLazyLoading; - } -} - -public static void ArgumentNotNull(T arg, string name) where T : class -{ - if (arg == null) - { - throw new ArgumentNullException(name); - } -} - -private static readonly Lazy ResourceManager = - new Lazy( - () => new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(MetadataItemCollectionFactory).Assembly), isThreadSafe: true); - -public static string GetResourceString(string resourceName) -{ - ArgumentNotNull(resourceName, "resourceName"); - - return ResourceManager.Value.GetString(resourceName, null); -} - +<#@ template language="C#" debug="false" hostspecific="true"#> +<#@ include file="EF.Utility.CS.ttinclude"#><#@ + output extension=".cs"#><# + +const string inputFile = @"..\Schemas\MonsterModel.csdl"; +var textTransform = DynamicTextTransformation.Create(this); +var code = new CodeGenerationTools(this); +var ef = new MetadataTools(this); +var typeMapper = new TypeMapper(code, ef, textTransform.Errors); +var fileManager = EntityFrameworkTemplateFileManager.Create(this); +var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile); +var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); + +if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile)) +{ + return string.Empty; +} + +WriteHeader(codeStringGenerator, fileManager); + +foreach (var entity in typeMapper.GetItemsToGenerate(itemCollection)) +{ + fileManager.StartNewFile(entity.Name + ".cs"); + BeginNamespace(code); +#> +<#=codeStringGenerator.UsingDirectives(inHeader: false)#> +<#=codeStringGenerator.EntityClassOpening(entity)#> +{ +<# + var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity); + var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity); + var complexProperties = typeMapper.GetComplexProperties(entity); + + if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any()) + { +#> + public <#=code.Escape(entity)#>() + { +<# + foreach (var edmProperty in propertiesWithDefaultValues) + { +#> + this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>; +<# + } + + foreach (var navigationProperty in collectionNavigationProperties) + { +#> + this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>(); +<# + } + + foreach (var complexProperty in complexProperties) + { +#> + this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>(); +<# + } +#> + } + +<# + } + + var simpleProperties = typeMapper.GetSimpleProperties(entity); + if (simpleProperties.Any()) + { + foreach (var edmProperty in simpleProperties) + { +#> + <#=codeStringGenerator.Property(edmProperty)#> +<# + } + } + + if (complexProperties.Any()) + { +#> + +<# + foreach(var complexProperty in complexProperties) + { +#> + <#=codeStringGenerator.Property(complexProperty)#> +<# + } + } + + var navigationProperties = typeMapper.GetNavigationProperties(entity); + if (navigationProperties.Any()) + { +#> + +<# + foreach (var navigationProperty in navigationProperties) + { +#> + <#=codeStringGenerator.NavigationProperty(navigationProperty)#> +<# + } + } +#> +} +<# + EndNamespace(code); +} + +foreach (var complex in typeMapper.GetItemsToGenerate(itemCollection)) +{ + fileManager.StartNewFile(complex.Name + ".cs"); + BeginNamespace(code); +#> +<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#> +<#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#> +{ +<# + var complexProperties = typeMapper.GetComplexProperties(complex); + var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex); + + if (propertiesWithDefaultValues.Any() || complexProperties.Any()) + { +#> + public <#=code.Escape(complex)#>() + { +<# + foreach (var edmProperty in propertiesWithDefaultValues) + { +#> + this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>; +<# + } + + foreach (var complexProperty in complexProperties) + { +#> + this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>(); +<# + } +#> + } + +<# + } + + var simpleProperties = typeMapper.GetSimpleProperties(complex); + if (simpleProperties.Any()) + { + foreach(var edmProperty in simpleProperties) + { +#> + <#=codeStringGenerator.Property(edmProperty)#> +<# + } + } + + if (complexProperties.Any()) + { +#> + +<# + foreach(var edmProperty in complexProperties) + { +#> + <#=codeStringGenerator.Property(edmProperty)#> +<# + } + } +#> +} +<# + EndNamespace(code); +} + +foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection)) +{ + fileManager.StartNewFile(enumType.Name + ".cs"); + BeginNamespace(code); +#> +<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#> +<# + if (typeMapper.EnumIsFlags(enumType)) + { +#> +[Flags] +<# + } +#> +<#=codeStringGenerator.EnumOpening(enumType)#> +{ +<# + var foundOne = false; + + foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType)) + { + foundOne = true; +#> + <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>, +<# + } + + if (foundOne) + { + this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1); + } +#> +} +<# + EndNamespace(code); +} + +fileManager.Process(); + +#> +<#+ + +public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager) +{ + fileManager.StartHeader(); +#> +//------------------------------------------------------------------------------ +// +// <#=GetResourceString("Template_GeneratedCodeCommentLine1")#> +// +// <#=GetResourceString("Template_GeneratedCodeCommentLine2")#> +// <#=GetResourceString("Template_GeneratedCodeCommentLine3")#> +// +//------------------------------------------------------------------------------ +<#=codeStringGenerator.UsingDirectives(inHeader: true)#> +<#+ + fileManager.EndBlock(); +} + +public void BeginNamespace(CodeGenerationTools code) +{ + var codeNamespace = code.VsNamespaceSuggestion(); + if (!String.IsNullOrEmpty(codeNamespace)) + { +#> +namespace <#=code.EscapeNamespace(codeNamespace)#> +{ +<#+ + PushIndent(" "); + } +} + +public void EndNamespace(CodeGenerationTools code) +{ + if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion())) + { + PopIndent(); +#> +} +<#+ + } +} + +public const string TemplateId = "CSharp_DbContext_Types_EF5"; + +public class CodeStringGenerator +{ + private readonly CodeGenerationTools _code; + private readonly TypeMapper _typeMapper; + private readonly MetadataTools _ef; + + public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef) + { + ArgumentNotNull(code, "code"); + ArgumentNotNull(typeMapper, "typeMapper"); + ArgumentNotNull(ef, "ef"); + + _code = code; + _typeMapper = typeMapper; + _ef = ef; + } + + public string Property(EdmProperty edmProperty) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2} {{ {3}get; {4}set; }}", + Accessibility.ForProperty(edmProperty), + _typeMapper.GetTypeName(edmProperty.TypeUsage), + _code.Escape(edmProperty), + _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), + _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); + } + + public string NavigationProperty(NavigationProperty navigationProperty) + { + var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType()); + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2} {{ {3}get; {4}set; }}", + AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)), + navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, + _code.Escape(navigationProperty), + _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)), + _code.SpaceAfter(Accessibility.ForSetter(navigationProperty))); + } + + public string AccessibilityAndVirtual(string accessibility) + { + return accessibility + (accessibility != "private" ? " virtual" : ""); + } + + public string EntityClassOpening(EntityType entity) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1}partial class {2}{3}", + Accessibility.ForType(entity), + _code.SpaceAfter(_code.AbstractOption(entity)), + _code.Escape(entity), + _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType))); + } + + public string EnumOpening(SimpleType enumType) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} enum {1} : {2}", + Accessibility.ForType(enumType), + _code.Escape(enumType), + _code.Escape(_typeMapper.UnderlyingClrType(enumType))); + } + + public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter) + { + var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); + foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) + { + var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; + var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")"; + var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + parameter.RawClrTypeName + "))"; + writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit); + } + } + + public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace) + { + var parameters = _typeMapper.GetParameters(edmFunction); + + return string.Format( + CultureInfo.InvariantCulture, + "{0} IQueryable<{1}> {2}{3}", + AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), + _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), + _code.Escape(edmFunction), + string.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray())); + } + + public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace) + { + var parameters = _typeMapper.GetParameters(edmFunction); + + return string.Format( + CultureInfo.InvariantCulture, + "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});", + _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), + edmFunction.NamespaceName, + edmFunction.Name, + string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()), + _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))); + } + + public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) + { + var parameters = _typeMapper.GetParameters(edmFunction); + var returnType = _typeMapper.GetReturnType(edmFunction); + + var paramList = String.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray()); + if (includeMergeOption) + { + paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption"; + } + + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2}({3})", + AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), + returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", + _code.Escape(edmFunction), + paramList); + } + + public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) + { + var parameters = _typeMapper.GetParameters(edmFunction); + var returnType = _typeMapper.GetReturnType(edmFunction); + + var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())); + if (includeMergeOption) + { + callParams = ", mergeOption" + callParams; + } + + return string.Format( + CultureInfo.InvariantCulture, + "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});", + returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", + edmFunction.Name, + callParams); + } + + public string DbSet(EntitySet entitySet) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} DbSet<{1}> {2} {{ get; set; }}", + Accessibility.ForReadOnlyProperty(entitySet), + _typeMapper.GetTypeName(entitySet.ElementType), + _code.Escape(entitySet)); + } + + public string UsingDirectives(bool inHeader, bool includeCollections = true) + { + return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion()) + ? string.Format( + CultureInfo.InvariantCulture, + "{0}using System;{1}" + + "{2}", + inHeader ? Environment.NewLine : "", + includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "", + inHeader ? "" : Environment.NewLine) + : ""; + } +} + +public class TypeMapper +{ + private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; + + private readonly System.Collections.IList _errors; + private readonly CodeGenerationTools _code; + private readonly MetadataTools _ef; + + public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors) + { + ArgumentNotNull(code, "code"); + ArgumentNotNull(ef, "ef"); + ArgumentNotNull(errors, "errors"); + + _code = code; + _ef = ef; + _errors = errors; + } + + public string GetTypeName(TypeUsage typeUsage) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); + } + + public string GetTypeName(EdmType edmType) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: null); + } + + public string GetTypeName(TypeUsage typeUsage, string modelNamespace) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); + } + + public string GetTypeName(EdmType edmType, string modelNamespace) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); + } + + public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) + { + if (edmType == null) + { + return null; + } + + var collectionType = edmType as CollectionType; + if (collectionType != null) + { + return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); + } + + var typeName = _code.Escape(edmType.MetadataProperties + .Where(p => p.Name == ExternalTypeNameAttributeName) + .Select(p => (string)p.Value) + .FirstOrDefault()) + ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ? + _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) : + _code.Escape(edmType)); + + if (edmType is StructuralType) + { + return typeName; + } + + if (edmType is SimpleType) + { + var clrType = UnderlyingClrType(edmType); + if (!IsEnumType(edmType)) + { + typeName = _code.Escape(clrType); + } + + return clrType.IsValueType && isNullable == true ? + String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : + typeName; + } + + throw new ArgumentException("edmType"); + } + + public Type UnderlyingClrType(EdmType edmType) + { + ArgumentNotNull(edmType, "edmType"); + + var primitiveType = edmType as PrimitiveType; + if (primitiveType != null) + { + return primitiveType.ClrEquivalentType; + } + + if (IsEnumType(edmType)) + { + return GetEnumUnderlyingType(edmType).ClrEquivalentType; + } + + return typeof(object); + } + + public object GetEnumMemberValue(MetadataItem enumMember) + { + ArgumentNotNull(enumMember, "enumMember"); + + var valueProperty = enumMember.GetType().GetProperty("Value"); + return valueProperty == null ? null : valueProperty.GetValue(enumMember, null); + } + + public string GetEnumMemberName(MetadataItem enumMember) + { + ArgumentNotNull(enumMember, "enumMember"); + + var nameProperty = enumMember.GetType().GetProperty("Name"); + return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null); + } + + public System.Collections.IEnumerable GetEnumMembers(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + var membersProperty = enumType.GetType().GetProperty("Members"); + return membersProperty != null + ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null) + : Enumerable.Empty(); + } + + public bool EnumIsFlags(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + var isFlagsProperty = enumType.GetType().GetProperty("IsFlags"); + return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null); + } + + public bool IsEnumType(GlobalItem edmType) + { + ArgumentNotNull(edmType, "edmType"); + + return edmType.GetType().Name == "EnumType"; + } + + public PrimitiveType GetEnumUnderlyingType(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null); + } + + public string CreateLiteral(object value) + { + if (value == null || value.GetType() != typeof(TimeSpan)) + { + return _code.CreateLiteral(value); + } + + return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks); + } + + public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) + { + ArgumentNotNull(types, "types"); + ArgumentNotNull(sourceFile, "sourceFile"); + + var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); + if (types.Any(item => !hash.Add(item))) + { + _errors.Add( + new CompilerError(sourceFile, -1, -1, "6023", + String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CaseInsensitiveTypeConflict")))); + return false; + } + return true; + } + + public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection) + { + return GetItemsToGenerate(itemCollection) + .Where(e => IsEnumType(e)); + } + + public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType + { + return itemCollection + .OfType() + .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) + .OrderBy(i => i.Name); + } + + public IEnumerable GetAllGlobalItems(IEnumerable itemCollection) + { + return itemCollection + .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i)) + .Select(g => GetGlobalItemName(g)); + } + + public string GetGlobalItemName(GlobalItem item) + { + if (item is EdmType) + { + return ((EdmType)item).Name; + } + else + { + return ((EntityContainer)item).Name; + } + } + + public IEnumerable GetSimpleProperties(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); + } + + public IEnumerable GetSimpleProperties(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); + } + + public IEnumerable GetComplexProperties(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); + } + + public IEnumerable GetComplexProperties(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); + } + + public IEnumerable GetPropertiesWithDefaultValues(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); + } + + public IEnumerable GetPropertiesWithDefaultValues(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); + } + + public IEnumerable GetNavigationProperties(EntityType type) + { + return type.NavigationProperties.Where(np => np.DeclaringType == type); + } + + public IEnumerable GetCollectionNavigationProperties(EntityType type) + { + return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many); + } + + public FunctionParameter GetReturnParameter(EdmFunction edmFunction) + { + ArgumentNotNull(edmFunction, "edmFunction"); + + var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters"); + return returnParamsProperty == null + ? edmFunction.ReturnParameter + : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault(); + } + + public bool IsComposable(EdmFunction edmFunction) + { + ArgumentNotNull(edmFunction, "edmFunction"); + + var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute"); + return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null); + } + + public IEnumerable GetParameters(EdmFunction edmFunction) + { + return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); + } + + public TypeUsage GetReturnType(EdmFunction edmFunction) + { + var returnParam = GetReturnParameter(edmFunction); + return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage); + } + + public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption) + { + var returnType = GetReturnType(edmFunction); + return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType; + } +} + +public class EdmMetadataLoader +{ + private readonly IDynamicHost _host; + private readonly System.Collections.IList _errors; + + public EdmMetadataLoader(IDynamicHost host, System.Collections.IList errors) + { + ArgumentNotNull(host, "host"); + ArgumentNotNull(errors, "errors"); + + _host = host; + _errors = errors; + } + + public IEnumerable CreateEdmItemCollection(string sourcePath) + { + ArgumentNotNull(sourcePath, "sourcePath"); + + if (!ValidateInputPath(sourcePath)) + { + return new EdmItemCollection(); + } + + var schemaElement = LoadRootElement(_host.ResolvePath(sourcePath)); + if (schemaElement != null) + { + using (var reader = schemaElement.CreateReader()) + { + IList errors; + var itemCollection = MetadataItemCollectionFactory.CreateEdmItemCollection(new[] { reader }, out errors); + + ProcessErrors(errors, sourcePath); + + return itemCollection; + } + } + return new EdmItemCollection(); + } + + public string GetModelNamespace(string sourcePath) + { + ArgumentNotNull(sourcePath, "sourcePath"); + + if (!ValidateInputPath(sourcePath)) + { + return string.Empty; + } + + var model = LoadRootElement(_host.ResolvePath(sourcePath)); + if (model == null) + { + return string.Empty; + } + + var attribute = model.Attribute("Namespace"); + return attribute != null ? attribute.Value : ""; + } + + private bool ValidateInputPath(string sourcePath) + { + if (sourcePath == "$" + "edmxInputFile" + "$") + { + _errors.Add( + new CompilerError(_host.TemplateFile ?? sourcePath, 0, 0, string.Empty, + GetResourceString("Template_ReplaceVsItemTemplateToken"))); + return false; + } + + return true; + } + + public XElement LoadRootElement(string sourcePath) + { + ArgumentNotNull(sourcePath, "sourcePath"); + + var root = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); + return root.Elements() + .Where(e => e.Name.LocalName == "Runtime") + .Elements() + .Where(e => e.Name.LocalName == "ConceptualModels") + .Elements() + .Where(e => e.Name.LocalName == "Schema") + .FirstOrDefault() + ?? root; + } + + private void ProcessErrors(IEnumerable errors, string sourceFilePath) + { + foreach (var error in errors) + { + _errors.Add( + new CompilerError( + error.SchemaLocation ?? sourceFilePath, + error.Line, + error.Column, + error.ErrorCode.ToString(CultureInfo.InvariantCulture), + error.Message) + { + IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning + }); + } + } + + public bool IsLazyLoadingEnabled(EntityContainer container) + { + string lazyLoadingAttributeValue; + var lazyLoadingAttributeName = MetadataConstants.EDM_ANNOTATION_09_02 + ":LazyLoadingEnabled"; + bool isLazyLoading; + return !MetadataTools.TryGetStringMetadataPropertySetting(container, lazyLoadingAttributeName, out lazyLoadingAttributeValue) + || !bool.TryParse(lazyLoadingAttributeValue, out isLazyLoading) + || isLazyLoading; + } +} + +public static void ArgumentNotNull(T arg, string name) where T : class +{ + if (arg == null) + { + throw new ArgumentNullException(name); + } +} + +private static readonly Lazy ResourceManager = + new Lazy( + () => new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(MetadataItemCollectionFactory).Assembly), isThreadSafe: true); + +public static string GetResourceString(string resourceName) +{ + ArgumentNotNull(resourceName, "resourceName"); + + return ResourceManager.Value.GetString(resourceName, null); +} + #> \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/CustomerInfoMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/CustomerInfoMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/CustomerInfoMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/CustomerInfoMm.cs index 9f94070e..3f7b760d 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/CustomerInfoMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/CustomerInfoMm.cs @@ -1,20 +1,20 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class CustomerInfoMm - { - public int CustomerInfoId { get; set; } - public string Information { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class CustomerInfoMm + { + public int CustomerInfoId { get; set; } + public string Information { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/DimensionsMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/DimensionsMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/DimensionsMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/DimensionsMm.cs index cd710df3..00e1a1da 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/DimensionsMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/DimensionsMm.cs @@ -1,20 +1,20 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - - public partial class DimensionsMm - { - public decimal Width { get; set; } - public decimal Height { get; set; } - public decimal Depth { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + + public partial class DimensionsMm + { + public decimal Width { get; set; } + public decimal Height { get; set; } + public decimal Depth { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/DiscontinuedProductMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/DiscontinuedProductMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/DiscontinuedProductMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/DiscontinuedProductMm.cs index b5398599..38b568bb 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/DiscontinuedProductMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/DiscontinuedProductMm.cs @@ -1,22 +1,22 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class DiscontinuedProductMm : ProductMm - { - public System.DateTime Discontinued { get; set; } - public Nullable ReplacementProductId { get; set; } - - public virtual ProductMm ReplacedBy { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class DiscontinuedProductMm : ProductMm + { + public System.DateTime Discontinued { get; set; } + public Nullable ReplacementProductId { get; set; } + + public virtual ProductMm ReplacedBy { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/DriverMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/DriverMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/DriverMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/DriverMm.cs index 76118f44..d851debd 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/DriverMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/DriverMm.cs @@ -1,22 +1,22 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class DriverMm - { - public string Name { get; set; } - public System.DateTime BirthDate { get; set; } - - public virtual LicenseMm License { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class DriverMm + { + public string Name { get; set; } + public System.DateTime BirthDate { get; set; } + + public virtual LicenseMm License { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/EF.Utility.CS.ttinclude b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/EF.Utility.CS.ttinclude similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/EF.Utility.CS.ttinclude rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/EF.Utility.CS.ttinclude index 3f40d2a6..ac68740d 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/EF.Utility.CS.ttinclude +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/EF.Utility.CS.ttinclude @@ -1,2549 +1,2549 @@ -<#@ assembly name="System.Core" #> -<#@ assembly name="System.Data" #> -<#@ assembly name="System.Data.Entity" #> -<#@ assembly name="System.Data.Entity.Design" #> -<#@ assembly name="System.Xml" #> -<#@ assembly name="System.Xml.Linq"#> -<#@ assembly name="EnvDTE"#> -<#@ import namespace="System" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.IO" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ import namespace="System.Data.Objects" #> -<#@ import namespace="System.Data.Objects.DataClasses" #> -<#@ import namespace="System.Xml" #> -<#@ import namespace="System.Xml.Linq" #> -<#@ import namespace="System.Globalization" #> -<#@ import namespace="System.Reflection" #> -<#@ import namespace="System.Data.Metadata.Edm" #> -<#@ import namespace="System.Data.Mapping" #> -<#@ import namespace="System.Data.Entity.Design" #> -<#@ import namespace="System.CodeDom" #> -<#@ import namespace="System.CodeDom.Compiler" #> -<#@ import namespace="Microsoft.CSharp"#> -<#@ import namespace="System.Text"#> -<#+ -// Copyright (c) Microsoft Corporation. All rights reserved. - -public static Dictionary TemplateMetadata = new Dictionary(); - -/// -/// Responsible for helping to create source code that is -/// correctly formated and functional -/// -public class CodeGenerationTools -{ - private readonly DynamicTextTransformation _textTransformation; - private readonly CSharpCodeProvider _code; - private readonly MetadataTools _ef; - - /// - /// Initializes a new CodeGenerationTools object with the TextTransformation (T4 generated class) - /// that is currently running - /// - public CodeGenerationTools(object textTransformation) - { - if (textTransformation == null) - { - throw new ArgumentNullException("textTransformation"); - } - - _textTransformation = DynamicTextTransformation.Create(textTransformation); - _code = new CSharpCodeProvider(); - _ef = new MetadataTools(_textTransformation); - FullyQualifySystemTypes = false; - CamelCaseFields = true; - } - - /// - /// When true, all types that are not being generated - /// are fully qualified to keep them from conflicting with - /// types that are being generated. Useful when you have - /// something like a type being generated named System. - /// - /// Default is false. - /// - public bool FullyQualifySystemTypes { get; set; } - - /// - /// When true, the field names are Camel Cased, - /// otherwise they will preserve the case they - /// start with. - /// - /// Default is true. - /// - public bool CamelCaseFields { get; set; } - - /// - /// Returns the NamespaceName suggested by VS if running inside VS. Otherwise, returns - /// null. - /// - public string VsNamespaceSuggestion() - { - string suggestion = _textTransformation.Host.ResolveParameterValue("directiveId", "namespaceDirectiveProcessor", "namespaceHint"); - if (String.IsNullOrEmpty(suggestion)) - { - return null; - } - - return suggestion; - } - - /// - /// Returns a string that is safe for use as an identifier in C#. - /// Keywords are escaped. - /// - public string Escape(string name) - { - if (name == null) - { - return null; - } - - return _code.CreateEscapedIdentifier(name); - } - - /// - /// Returns the name of the TypeUsage's EdmType that is safe for - /// use as an identifier. - /// - public string Escape(TypeUsage typeUsage) - { - if (typeUsage == null) - { - return null; - } - - if (typeUsage.EdmType is ComplexType || - typeUsage.EdmType is EntityType) - { - return Escape(typeUsage.EdmType.Name); - } - else if (typeUsage.EdmType is SimpleType) - { - Type clrType = _ef.UnderlyingClrType(typeUsage.EdmType); - string typeName = typeUsage.EdmType is EnumType ? Escape(typeUsage.EdmType.Name) : Escape(clrType); - if (clrType.IsValueType && _ef.IsNullable(typeUsage)) - { - return String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName); - } - - return typeName; - } - else if (typeUsage.EdmType is CollectionType) - { - return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", Escape(((CollectionType)typeUsage.EdmType).TypeUsage)); - } - - throw new ArgumentException("typeUsage"); - } - - /// - /// Returns the name of the EdmMember that is safe for - /// use as an identifier. - /// - public string Escape(EdmMember member) - { - if (member == null) - { - return null; - } - - return Escape(member.Name); - } - - /// - /// Returns the name of the EdmType that is safe for - /// use as an identifier. - /// - public string Escape(EdmType type) - { - if (type == null) - { - return null; - } - - return Escape(type.Name); - } - - /// - /// Returns the name of the EdmFunction that is safe for - /// use as an identifier. - /// - public string Escape(EdmFunction function) - { - if (function == null) - { - return null; - } - - return Escape(function.Name); - } - - /// - /// Returns the name of the EnumMember that is safe for - /// use as an identifier. - /// - public string Escape(EnumMember member) - { - if (member == null) - { - return null; - } - - return Escape(member.Name); - } - - /// - /// Returns the name of the EntityContainer that is safe for - /// use as an identifier. - /// - public string Escape(EntityContainer container) - { - if (container == null) - { - return null; - } - - return Escape(container.Name); - } - - /// - /// Returns the name of the EntitySet that is safe for - /// use as an identifier. - /// - public string Escape(EntitySet set) - { - if (set == null) - { - return null; - } - - return Escape(set.Name); - } - - /// - /// Returns the name of the StructuralType that is safe for - /// use as an identifier. - /// - public string Escape(StructuralType type) - { - if (type == null) - { - return null; - } - - return Escape(type.Name); - } - - /// - /// Returns the NamespaceName with each segment safe to - /// use as an identifier. - /// - public string EscapeNamespace(string namespaceName) - { - if (String.IsNullOrEmpty(namespaceName)) - { - return namespaceName; - } - - string[] parts = namespaceName.Split('.'); - namespaceName = String.Empty; - foreach (string part in parts) - { - if (namespaceName != String.Empty) - { - namespaceName += "."; - } - - namespaceName += Escape(part); - } - - return namespaceName; - } - - /// - /// Returns the name of the EdmMember formatted for - /// use as a field identifier. - /// - /// This method changes behavior based on the CamelCaseFields - /// setting. - /// - public string FieldName(EdmMember member) - { - if (member == null) - { - return null; - } - - return FieldName(member.Name); - } - - /// - /// Returns the name of the EntitySet formatted for - /// use as a field identifier. - /// - /// This method changes behavior based on the CamelCaseFields - /// setting. - /// - public string FieldName(EntitySet set) - { - if (set == null) - { - return null; - } - - return FieldName(set.Name); - - } - - private string FieldName(string name) - { - if (CamelCaseFields) - { - return "_" + CamelCase(name); - } - else - { - return "_" + name; - } - } - - /// - /// Returns the name of the Type object formatted for - /// use in source code. - /// - /// This method changes behavior based on the FullyQualifySystemTypes - /// setting. - /// - public string Escape(Type clrType) - { - return Escape(clrType, FullyQualifySystemTypes); - } - - /// - /// Returns the name of the Type object formatted for - /// use in source code. - /// - public string Escape(Type clrType, bool fullyQualifySystemTypes) - { - if(clrType == null) - { - return null; - } - - string typeName; - if (fullyQualifySystemTypes) - { - typeName = "global::" + clrType.FullName; - } - else - { - typeName = _code.GetTypeOutput(new CodeTypeReference(clrType)); - } - return typeName; - } - - /// - /// Returns the abstract option if the entity is Abstract, otherwise returns String.Empty - /// - public string AbstractOption(EntityType entity) - { - if (entity.Abstract) - { - return "abstract"; - } - return String.Empty; - } - - /// - /// Returns the passed in identifier with the first letter changed to lowercase - /// - public string CamelCase(string identifier) - { - if (String.IsNullOrEmpty(identifier)) - { - return identifier; - } - - if (identifier.Length == 1) - { - return identifier[0].ToString(CultureInfo.InvariantCulture).ToLowerInvariant(); - } - - return identifier[0].ToString(CultureInfo.InvariantCulture).ToLowerInvariant() + identifier.Substring(1); - } - - /// - /// If the value parameter is null or empty an empty string is returned, - /// otherwise it retuns value with a single space concatenated on the end. - /// - public string SpaceAfter(string value) - { - return StringAfter(value, " "); - } - - /// - /// If the value parameter is null or empty an empty string is returned, - /// otherwise it retuns value with a single space concatenated on the end. - /// - public string SpaceBefore(string value) - { - return StringBefore(" ", value); - } - - /// - /// If the value parameter is null or empty an empty string is returned, - /// otherwise it retuns value with append concatenated on the end. - /// - public string StringAfter(string value, string append) - { - if (String.IsNullOrEmpty(value)) - { - return String.Empty; - } - - return value + append; - } - - /// - /// If the value parameter is null or empty an empty string is returned, - /// otherwise it retuns value with prepend concatenated on the front. - /// - public string StringBefore(string prepend, string value) - { - if (String.IsNullOrEmpty(value)) - { - return String.Empty; - } - - return prepend + value; - } - - /// - /// Returns false and shows an error if the supplied type names aren't case-insensitively unique, - /// otherwise returns true. - /// - public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) - { - return VerifyCaseInsensitiveUniqueness(types, t => string.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CaseInsensitiveTypeConflict"), t), sourceFile); - } - - /// - /// Returns false and shows an error if the supplied strings aren't case-insensitively unique, - /// otherwise returns true. - /// - private bool VerifyCaseInsensitiveUniqueness(IEnumerable items, Func formatMessage, string sourceFile) - { - HashSet hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); - foreach (string item in items) - { - if (!hash.Add(item)) - { - _textTransformation.Errors.Add(new System.CodeDom.Compiler.CompilerError(sourceFile, -1, -1, "6023", formatMessage(item))); - return false; - } - } - return true; - } - - /// - /// Returns the names of the items in the supplied collection that correspond to O-Space types. - /// - public IEnumerable GetAllGlobalItems(EdmItemCollection itemCollection) - { - return itemCollection.GetItems().Where(i => i is EntityType || i is ComplexType || i is EnumType || i is EntityContainer).Select(g => GetGlobalItemName(g)); - } - - /// - /// Returns the name of the supplied GlobalItem. - /// - public string GetGlobalItemName(GlobalItem item) - { - if (item is EdmType) - { - return ((EdmType)item).Name; - } - else - { - return ((EntityContainer)item).Name; - } - } - - /// - /// Retuns as full of a name as possible, if a namespace is provided - /// the namespace and name are combined with a period, otherwise just - /// the name is returned. - /// - public string CreateFullName(string namespaceName, string name) - { - if (String.IsNullOrEmpty(namespaceName)) - { - return name; - } - - return namespaceName + "." + name; - } - - /// - /// Retuns a literal representing the supplied value. - /// - public string CreateLiteral(object value) - { - if (value == null) - { - return string.Empty; - } - - Type type = value.GetType(); - if (type.IsEnum) - { - return type.FullName + "." + value.ToString(); - } - if (type == typeof(Guid)) - { - return string.Format(CultureInfo.InvariantCulture, "new Guid(\"{0}\")", - ((Guid)value).ToString("D", CultureInfo.InvariantCulture)); - } - else if (type == typeof(DateTime)) - { - return string.Format(CultureInfo.InvariantCulture, "new DateTime({0}, DateTimeKind.Unspecified)", - ((DateTime)value).Ticks); - } - else if (type == typeof(byte[])) - { - var arrayInit = string.Join(", ", ((byte[])value).Select(b => b.ToString(CultureInfo.InvariantCulture)).ToArray()); - return string.Format(CultureInfo.InvariantCulture, "new Byte[] {{{0}}}", arrayInit); - } - else if (type == typeof(DateTimeOffset)) - { - var dto = (DateTimeOffset)value; - return string.Format(CultureInfo.InvariantCulture, "new DateTimeOffset({0}, new TimeSpan({1}))", - dto.Ticks, dto.Offset.Ticks); - } - else if (type == typeof(TimeSpan)) - { - return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", - ((TimeSpan)value).Ticks); - } - - var expression = new CodePrimitiveExpression(value); - var writer = new StringWriter(); - CSharpCodeProvider code = new CSharpCodeProvider(); - code.GenerateCodeFromExpression(expression, writer, new CodeGeneratorOptions()); - return writer.ToString(); - } - - /// - /// Returns a resource string from the System.Data.Entity.Design assembly. - /// - public static string GetResourceString(string resourceName, CultureInfo culture = null) - { - if(_resourceManager == null) - { - _resourceManager = new System.Resources.ResourceManager("System.Data.Entity.Design", - typeof(System.Data.Entity.Design.MetadataItemCollectionFactory).Assembly); - } - - return _resourceManager.GetString(resourceName, culture); - } - static System.Resources.ResourceManager _resourceManager; - - private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; - - /// - /// Gets the entity, complex, or enum types for which code should be generated from the given item collection. - /// Any types for which an ExternalTypeName annotation has been applied in the conceptual model - /// metadata (CSDL) are filtered out of the returned list. - /// - /// The type of item to return. - /// The item collection to look in. - /// The items to generate. - public IEnumerable GetItemsToGenerate(ItemCollection itemCollection) where T: GlobalItem - { - return itemCollection.GetItems().Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)); - } - - /// - /// Returns the escaped type name to use for the given usage of a c-space type in o-space. This might be - /// an external type name if the ExternalTypeName annotation has been specified in the - /// conceptual model metadata (CSDL). - /// - /// The c-space type usage to get a name for. - /// The type name to use. - public string GetTypeName(TypeUsage typeUsage) - { - return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); - } - - /// - /// Returns the escaped type name to use for the given c-space type in o-space. This might be - /// an external type name if the ExternalTypeName annotation has been specified in the - /// conceptual model metadata (CSDL). - /// - /// The c-space type to get a name for. - /// The type name to use. - public string GetTypeName(EdmType edmType) - { - return GetTypeName(edmType, isNullable: null, modelNamespace: null); - } - - /// - /// Returns the escaped type name to use for the given usage of an c-space type in o-space. This might be - /// an external type name if the ExternalTypeName annotation has been specified in the - /// conceptual model metadata (CSDL). - /// - /// The c-space type usage to get a name for. - /// If not null and the type's namespace does not match this namespace, then a - /// fully qualified name will be returned. - /// The type name to use. - public string GetTypeName(TypeUsage typeUsage, string modelNamespace) - { - return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); - } - - /// - /// Returns the escaped type name to use for the given c-space type in o-space. This might be - /// an external type name if the ExternalTypeName annotation has been specified in the - /// conceptual model metadata (CSDL). - /// - /// The c-space type to get a name for. - /// If not null and the type's namespace does not match this namespace, then a - /// fully qualified name will be returned. - /// The type name to use. - public string GetTypeName(EdmType edmType, string modelNamespace) - { - return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); - } - - /// - /// Returns the escaped type name to use for the given c-space type in o-space. This might be - /// an external type name if the ExternalTypeName annotation has been specified in the - /// conceptual model metadata (CSDL). - /// - /// The c-space type to get a name for. - /// Set this to true for nullable usage of this type. - /// If not null and the type's namespace does not match this namespace, then a - /// fully qualified name will be returned. - /// The type name to use. - private string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) - { - if (edmType == null) - { - return null; - } - - var collectionType = edmType as CollectionType; - if (collectionType != null) - { - return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); - } - - // Try to get an external type name, and if that is null, then try to get escape the name from metadata, - // possibly namespace-qualifying it. - var typeName = Escape(edmType.MetadataProperties - .Where(p => p.Name == ExternalTypeNameAttributeName) - .Select(p => (string)p.Value) - .FirstOrDefault()) - ?? - (modelNamespace != null && edmType.NamespaceName != modelNamespace ? - CreateFullName(EscapeNamespace(edmType.NamespaceName), Escape(edmType)) : - Escape(edmType)); - - if (edmType is StructuralType) - { - return typeName; - } - - if (edmType is SimpleType) - { - var clrType = _ef.UnderlyingClrType(edmType); - if (!(edmType is EnumType)) - { - typeName = Escape(clrType); - } - - return clrType.IsValueType && isNullable == true ? - String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : - typeName; - } - - throw new ArgumentException("typeUsage"); - } -} - -/// -/// Responsible for making the Entity Framework Metadata more -/// accessible for code generation. -/// -public class MetadataTools -{ - private readonly DynamicTextTransformation _textTransformation; - - /// - /// Initializes an MetadataTools Instance with the - /// TextTransformation (T4 generated class) that is currently running - /// - public MetadataTools(object textTransformation) - { - if (textTransformation == null) - { - throw new ArgumentNullException("textTransformation"); - } - - _textTransformation = DynamicTextTransformation.Create(textTransformation); - } - - /// - /// This method returns the underlying CLR type of the o-space type corresponding to the supplied - /// Note that for an enum type this means that the type backing the enum will be returned, not the enum type itself. - /// - public Type ClrType(TypeUsage typeUsage) - { - return UnderlyingClrType(typeUsage.EdmType); - } - - /// - /// This method returns the underlying CLR type given the c-space type. - /// Note that for an enum type this means that the type backing the enum will be returned, not the enum type itself. - /// - public Type UnderlyingClrType(EdmType edmType) - { - var primitiveType = edmType as PrimitiveType; - if (primitiveType != null) - { - return primitiveType.ClrEquivalentType; - } - - var enumType = edmType as EnumType; - if (enumType != null) - { - return enumType.UnderlyingType.ClrEquivalentType; - } - - return typeof(object); - } - - /// - /// True if the EdmProperty is a key of its DeclaringType, False otherwise. - /// - public bool IsKey(EdmProperty property) - { - if (property != null && property.DeclaringType.BuiltInTypeKind == BuiltInTypeKind.EntityType) - { - return ((EntityType)property.DeclaringType).KeyMembers.Contains(property); - } - - return false; - } - - /// - /// True if the EdmProperty TypeUsage is Nullable, False otherwise. - /// - public bool IsNullable(EdmProperty property) - { - return property != null && IsNullable(property.TypeUsage); - } - - /// - /// True if the TypeUsage is Nullable, False otherwise. - /// - public bool IsNullable(TypeUsage typeUsage) - { - Facet nullableFacet = null; - if (typeUsage != null && - typeUsage.Facets.TryGetValue("Nullable", true, out nullableFacet)) - { - return (bool)nullableFacet.Value; - } - - return false; - } - - /// - /// If the passed in TypeUsage represents a collection this method returns final element - /// type of the collection, otherwise it returns the value passed in. - /// - public TypeUsage GetElementType(TypeUsage typeUsage) - { - if (typeUsage == null) - { - return null; - } - - if (typeUsage.EdmType is CollectionType) - { - return GetElementType(((CollectionType)typeUsage.EdmType).TypeUsage); - } - else - { - return typeUsage; - } - } - - /// - /// Returns the NavigationProperty that is the other end of the same association set if it is - /// available, otherwise it returns null. - /// - public NavigationProperty Inverse(NavigationProperty navProperty) - { - if(navProperty == null) - { - return null; - } - - EntityType toEntity = navProperty.ToEndMember.GetEntityType(); - return toEntity.NavigationProperties - .SingleOrDefault(n => Object.ReferenceEquals(n.RelationshipType, navProperty.RelationshipType) && !Object.ReferenceEquals(n, navProperty)); - } - - /// - /// Given a property on the dependent end of a referential constraint, returns the corresponding property on the principal end. - /// Requires: The association has a referential constraint, and the specified dependentProperty is one of the properties on the dependent end. - /// - public EdmProperty GetCorrespondingPrincipalProperty(NavigationProperty navProperty, EdmProperty dependentProperty) - { - if (navProperty == null) - { - throw new ArgumentNullException("navProperty"); - } - - if (dependentProperty == null) - { - throw new ArgumentNullException("dependentProperty"); - } - - ReadOnlyMetadataCollection fromProperties = GetPrincipalProperties(navProperty); - ReadOnlyMetadataCollection toProperties = GetDependentProperties(navProperty); - return fromProperties[toProperties.IndexOf(dependentProperty)]; - } - - /// - /// Given a property on the principal end of a referential constraint, returns the corresponding property on the dependent end. - /// Requires: The association has a referential constraint, and the specified principalProperty is one of the properties on the principal end. - /// - public EdmProperty GetCorrespondingDependentProperty(NavigationProperty navProperty, EdmProperty principalProperty) - { - if (navProperty == null) - { - throw new ArgumentNullException("navProperty"); - } - - if (principalProperty == null) - { - throw new ArgumentNullException("principalProperty"); - } - - ReadOnlyMetadataCollection fromProperties = GetPrincipalProperties(navProperty); - ReadOnlyMetadataCollection toProperties = GetDependentProperties(navProperty); - return toProperties[fromProperties.IndexOf(principalProperty)]; - } - - /// - /// Gets the collection of properties that are on the principal end of a referential constraint for the specified navigation property. - /// Requires: The association has a referential constraint. - /// - public ReadOnlyMetadataCollection GetPrincipalProperties(NavigationProperty navProperty) - { - if (navProperty == null) - { - throw new ArgumentNullException("navProperty"); - } - - return ((AssociationType)navProperty.RelationshipType).ReferentialConstraints[0].FromProperties; - } - - /// - /// Gets the collection of properties that are on the dependent end of a referential constraint for the specified navigation property. - /// Requires: The association has a referential constraint. - /// - public ReadOnlyMetadataCollection GetDependentProperties(NavigationProperty navProperty) - { - if (navProperty == null) - { - throw new ArgumentNullException("navProperty"); - } - - return ((AssociationType)navProperty.RelationshipType).ReferentialConstraints[0].ToProperties; - } - - /// - /// True if this entity type requires the HandleCascadeDelete method defined and the method has - /// not been defined on any base type - /// - public bool NeedsHandleCascadeDeleteMethod(ItemCollection itemCollection, EntityType entity) - { - bool needsMethod = ContainsCascadeDeleteAssociation(itemCollection, entity); - // Check to make sure no base types have already declared this method - EntityType baseType = entity.BaseType as EntityType; - while(needsMethod && baseType != null) - { - needsMethod = !ContainsCascadeDeleteAssociation(itemCollection, baseType); - baseType = baseType.BaseType as EntityType; - } - return needsMethod; - } - - /// - /// True if this entity type participates in any relationships where the other end has an OnDelete - /// cascade delete defined, or if it is the dependent in any identifying relationships - /// - private bool ContainsCascadeDeleteAssociation(ItemCollection itemCollection, EntityType entity) - { - return itemCollection.GetItems().Where(a => - ((RefType)a.AssociationEndMembers[0].TypeUsage.EdmType).ElementType == entity && IsCascadeDeletePrincipal(a.AssociationEndMembers[1]) || - ((RefType)a.AssociationEndMembers[1].TypeUsage.EdmType).ElementType == entity && IsCascadeDeletePrincipal(a.AssociationEndMembers[0])).Any(); - } - - /// - /// True if the source end of the specified navigation property is the principal in an identifying relationship. - /// or if the source end has cascade delete defined. - /// - public bool IsCascadeDeletePrincipal(NavigationProperty navProperty) - { - if (navProperty == null) - { - throw new ArgumentNullException("navProperty"); - } - - return IsCascadeDeletePrincipal((AssociationEndMember)navProperty.FromEndMember); - } - - /// - /// True if the specified association end is the principal in an identifying relationship. - /// or if the association end has cascade delete defined. - /// - public bool IsCascadeDeletePrincipal(AssociationEndMember associationEnd) - { - if (associationEnd == null) - { - throw new ArgumentNullException("associationEnd"); - } - - return associationEnd.DeleteBehavior == OperationAction.Cascade || IsPrincipalEndOfIdentifyingRelationship(associationEnd); - } - - /// - /// True if the specified association end is the principal end in an identifying relationship. - /// In order to be an identifying relationship, the association must have a referential constraint where all of the dependent properties are part of the dependent type's primary key. - /// - public bool IsPrincipalEndOfIdentifyingRelationship(AssociationEndMember associationEnd) - { - if (associationEnd == null) - { - throw new ArgumentNullException("associationEnd"); - } - - ReferentialConstraint refConstraint = ((AssociationType)associationEnd.DeclaringType).ReferentialConstraints.Where(rc => rc.FromRole == associationEnd).SingleOrDefault(); - if (refConstraint != null) - { - EntityType entity = refConstraint.ToRole.GetEntityType(); - return !refConstraint.ToProperties.Where(tp => !entity.KeyMembers.Contains(tp)).Any(); - } - return false; - } - - /// - /// True if the specified association type is an identifying relationship. - /// In order to be an identifying relationship, the association must have a referential constraint where all of the dependent properties are part of the dependent type's primary key. - /// - public bool IsIdentifyingRelationship(AssociationType association) - { - if (association == null) - { - throw new ArgumentNullException("association"); - } - - return IsPrincipalEndOfIdentifyingRelationship(association.AssociationEndMembers[0]) || IsPrincipalEndOfIdentifyingRelationship(association.AssociationEndMembers[1]); - } - - /// - /// requires: firstType is not null - /// effects: if secondType is among the base types of the firstType, return true, - /// otherwise returns false. - /// when firstType is same as the secondType, return false. - /// - public bool IsSubtypeOf(EdmType firstType, EdmType secondType) - { - if (secondType == null) - { - return false; - } - - // walk up firstType hierarchy list - for (EdmType t = firstType.BaseType; t != null; t = t.BaseType) - { - if (t == secondType) - return true; - } - return false; - } - - /// - /// Returns the subtype of the EntityType in the current itemCollection - /// - public IEnumerable GetSubtypesOf(EntityType type, ItemCollection itemCollection, bool includeAbstractTypes) - { - if (type != null) - { - IEnumerable typesInCollection = itemCollection.GetItems(); - foreach (EntityType typeInCollection in typesInCollection) - { - if (type.Equals(typeInCollection) == false && this.IsSubtypeOf(typeInCollection, type)) - { - if ( includeAbstractTypes || !typeInCollection.Abstract) - { - yield return typeInCollection; - } - } - } - } - } - - public static bool TryGetStringMetadataPropertySetting(MetadataItem item, string propertyName, out string value) - { - value = null; - MetadataProperty property = item.MetadataProperties.FirstOrDefault(p => p.Name == propertyName); - if (property != null) - { - value = (string)property.Value; - } - return value != null; - } -} - -/// -/// Responsible for loading an EdmItemCollection from a .edmx file or .csdl files -/// -public class MetadataLoader -{ - private readonly DynamicTextTransformation _textTransformation; - - /// - /// Initializes an MetadataLoader Instance with the - /// TextTransformation (T4 generated class) that is currently running - /// - public MetadataLoader(object textTransformation) - { - if (textTransformation == null) - { - throw new ArgumentNullException("textTransformation"); - } - - _textTransformation = DynamicTextTransformation.Create(textTransformation); - } - - /// - /// Load the metadata for Edm, Store, and Mapping collections and register them - /// with a new MetadataWorkspace, returns false if any of the parts can't be - /// created, some of the ItemCollections may be registered and usable even if false is - /// returned - /// - public bool TryLoadAllMetadata(string inputFile, out MetadataWorkspace metadataWorkspace) - { - metadataWorkspace = new MetadataWorkspace(); - - EdmItemCollection edmItemCollection = CreateEdmItemCollection(inputFile); - metadataWorkspace.RegisterItemCollection(edmItemCollection); - - StoreItemCollection storeItemCollection = null; - if (TryCreateStoreItemCollection(inputFile, out storeItemCollection)) - { - StorageMappingItemCollection storageMappingItemCollection = null; - if (TryCreateStorageMappingItemCollection(inputFile, edmItemCollection, storeItemCollection, out storageMappingItemCollection)) - { - metadataWorkspace.RegisterItemCollection(storeItemCollection); - metadataWorkspace.RegisterItemCollection(storageMappingItemCollection); - return true; - } - } - - return false; - } - - /// - /// Create an EdmItemCollection loaded with the metadata provided - /// - public EdmItemCollection CreateEdmItemCollection(string sourcePath, params string[] referenceSchemas) - { - EdmItemCollection edmItemCollection; - if(TryCreateEdmItemCollection(sourcePath, referenceSchemas, out edmItemCollection)) - { - return edmItemCollection; - } - - return new EdmItemCollection(); - } - - /// - /// Attempts to create a EdmItemCollection from the specified metadata file - /// - public bool TryCreateEdmItemCollection(string sourcePath, out EdmItemCollection edmItemCollection) - { - return TryCreateEdmItemCollection(sourcePath, null, out edmItemCollection); - } - - /// - /// Attempts to create a EdmItemCollection from the specified metadata file - /// - public bool TryCreateEdmItemCollection(string sourcePath, string[] referenceSchemas, out EdmItemCollection edmItemCollection) - { - edmItemCollection = null; - - if (!ValidateInputPath(sourcePath, _textTransformation)) - { - return false; - } - - if (referenceSchemas == null) - { - referenceSchemas = new string[0]; - } - - ItemCollection itemCollection = null; - sourcePath = _textTransformation.Host.ResolvePath(sourcePath); - EdmItemCollectionBuilder collectionBuilder = new EdmItemCollectionBuilder(_textTransformation, referenceSchemas.Select(s => _textTransformation.Host.ResolvePath(s)).Where(s => s != sourcePath)); - if (collectionBuilder.TryCreateItemCollection(sourcePath, out itemCollection)) - { - edmItemCollection = (EdmItemCollection)itemCollection; - } - - return edmItemCollection != null; - } - - /// - /// Attempts to create a StoreItemCollection from the specified metadata file - /// - public bool TryCreateStoreItemCollection(string sourcePath, out StoreItemCollection storeItemCollection) - { - storeItemCollection = null; - - if (!ValidateInputPath(sourcePath, _textTransformation)) - { - return false; - } - - ItemCollection itemCollection = null; - StoreItemCollectionBuilder collectionBuilder = new StoreItemCollectionBuilder(_textTransformation); - if (collectionBuilder.TryCreateItemCollection(_textTransformation.Host.ResolvePath(sourcePath), out itemCollection)) - { - storeItemCollection = (StoreItemCollection)itemCollection; - } - return storeItemCollection != null; - } - - /// - /// Attempts to create a StorageMappingItemCollection from the specified metadata file, EdmItemCollection, and StoreItemCollection - /// - public bool TryCreateStorageMappingItemCollection(string sourcePath, EdmItemCollection edmItemCollection, StoreItemCollection storeItemCollection, out StorageMappingItemCollection storageMappingItemCollection) - { - storageMappingItemCollection = null; - - if (!ValidateInputPath(sourcePath, _textTransformation)) - { - return false; - } - - if (edmItemCollection == null) - { - throw new ArgumentNullException("edmItemCollection"); - } - - if (storeItemCollection == null) - { - throw new ArgumentNullException("storeItemCollection"); - } - - ItemCollection itemCollection = null; - StorageMappingItemCollectionBuilder collectionBuilder = new StorageMappingItemCollectionBuilder(_textTransformation, edmItemCollection, storeItemCollection); - if (collectionBuilder.TryCreateItemCollection(_textTransformation.Host.ResolvePath(sourcePath), out itemCollection)) - { - storageMappingItemCollection = (StorageMappingItemCollection)itemCollection; - } - return storageMappingItemCollection != null; - } - - /// - /// Gets the Model Namespace from the provided schema file. - /// - public string GetModelNamespace(string sourcePath) - { - if (!ValidateInputPath(sourcePath, _textTransformation)) - { - return String.Empty; - } - - EdmItemCollectionBuilder builder = new EdmItemCollectionBuilder(_textTransformation); - XElement model; - if(builder.TryLoadRootElement(_textTransformation.Host.ResolvePath(sourcePath), out model)) - { - XAttribute attribute = model.Attribute("Namespace"); - if (attribute != null) - { - return attribute.Value; - } - } - - return String.Empty; - } - - /// - /// Returns true if the specified file path is valid - /// - private static bool ValidateInputPath(string sourcePath, DynamicTextTransformation textTransformation) - { - if (String.IsNullOrEmpty(sourcePath)) - { - throw new ArgumentException("sourcePath"); - } - - if(sourcePath == "$edmxInputFile$") - { - textTransformation.Errors.Add(new CompilerError(textTransformation.Host.TemplateFile ?? CodeGenerationTools.GetResourceString("Template_CurrentlyRunningTemplate"), -1, -1, string.Empty, - CodeGenerationTools.GetResourceString("Template_ReplaceVsItemTemplateToken"))); - return false; - } - - return true; - } - - /// - /// Base class for ItemCollectionBuilder classes that - /// loads the specific types of metadata - /// - private abstract class ItemCollectionBuilder - { - private readonly DynamicTextTransformation _textTransformation; - private readonly string _fileExtension; - private readonly string _edmxSectionName; - private readonly string _rootElementName; - - /// - /// FileExtension for individual (non-edmx) metadata file for this - /// specific ItemCollection type - /// - public string FileExtension - { - get { return _fileExtension; } - } - - /// - /// The name of the XmlElement in the .edmx element - /// to find this ItemCollection's metadata - /// - public string EdmxSectionName - { - get { return _edmxSectionName; } - } - - /// - /// The name of the root element of this ItemCollection's metadata - /// - public string RootElementName - { - get { return _rootElementName; } - } - - /// - /// Method to build the appropriate ItemCollection - /// - protected abstract ItemCollection CreateItemCollection(IEnumerable readers, out IList errors); - - /// - /// Ctor to setup the ItemCollectionBuilder members - /// - protected ItemCollectionBuilder(DynamicTextTransformation textTransformation, string fileExtension, string edmxSectionName, string rootElementName) - { - _textTransformation = textTransformation; - _fileExtension = fileExtension; - _edmxSectionName = edmxSectionName; - _rootElementName = rootElementName; - } - - /// - /// Selects a namespace from the supplied constants. - /// - protected abstract string GetNamespace(SchemaConstants constants); - - /// - /// Try to create an ItemCollection loaded with the metadata provided - /// - public bool TryCreateItemCollection(string sourcePath, out ItemCollection itemCollection) - { - itemCollection = null; - - if (!ValidateInputPath(sourcePath, _textTransformation)) - { - return false; - } - - XElement schemaElement = null; - if (TryLoadRootElement(sourcePath, out schemaElement)) - { - List readers = new List(); - try - { - readers.Add(schemaElement.CreateReader()); - IList errors = null; - - ItemCollection tempItemCollection = CreateItemCollection(readers, out errors); - if (ProcessErrors(errors, sourcePath)) - { - return false; - } - - itemCollection = tempItemCollection; - return true; - } - finally - { - foreach (XmlReader reader in readers) - { - ((IDisposable)reader).Dispose(); - } - } - } - - return false; - } - - /// - /// Tries to load the root element from the metadata file provided - /// - public bool TryLoadRootElement(string sourcePath, out XElement schemaElement) - { - schemaElement = null; - string extension = Path.GetExtension(sourcePath); - if (extension.Equals(".edmx", StringComparison.InvariantCultureIgnoreCase)) - { - return TryLoadRootElementFromEdmx(sourcePath, out schemaElement); - } - else if(extension.Equals(FileExtension, StringComparison.InvariantCultureIgnoreCase)) - { - // load from single metadata file (.csdl, .ssdl, or .msl) - schemaElement = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); - return true; - } - - return false; - } - - /// - /// Tries to load the root element from the provided edmxDocument - /// - private bool TryLoadRootElementFromEdmx(XElement edmxDocument, SchemaConstants schemaConstants, string sectionName, string rootElementName, out XElement rootElement) - { - rootElement = null; - - XNamespace edmxNs = schemaConstants.EdmxNamespace; - XNamespace sectionNs = GetNamespace(schemaConstants); - - XElement runtime = edmxDocument.Element(edmxNs + "Runtime"); - if (runtime == null) - { - return false; - } - - XElement section = runtime.Element(edmxNs + sectionName); - if (section == null) - { - return false; - } - - string templateVersion; - - if (!TemplateMetadata.TryGetValue(MetadataConstants.TT_TEMPLATE_VERSION, out templateVersion)) - { - templateVersion = MetadataConstants.DEFAULT_TEMPLATE_VERSION; - } - - if (schemaConstants.MinimumTemplateVersion > new Version(templateVersion)) - { - _textTransformation.Errors.Add(new CompilerError( - _textTransformation.Host.TemplateFile ?? CodeGenerationTools.GetResourceString("Template_CurrentlyRunningTemplate"), -1, -1, string.Empty, - CodeGenerationTools.GetResourceString("Template_UnsupportedSchema")) - {IsWarning = true}); - } - - rootElement = section.Element(sectionNs + rootElementName); - return rootElement != null; - } - - /// - /// Tries to load the root element from the provided .edmx metadata file - /// - private bool TryLoadRootElementFromEdmx(string edmxPath, out XElement rootElement) - { - rootElement = null; - - XElement element = XElement.Load(edmxPath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); - - return TryLoadRootElementFromEdmx(element, MetadataConstants.V3_SCHEMA_CONSTANTS, EdmxSectionName, RootElementName, out rootElement) - || TryLoadRootElementFromEdmx(element, MetadataConstants.V2_SCHEMA_CONSTANTS, EdmxSectionName, RootElementName, out rootElement) - || TryLoadRootElementFromEdmx(element, MetadataConstants.V1_SCHEMA_CONSTANTS, EdmxSectionName, RootElementName, out rootElement); - } - - /// - /// Takes an Enumerable of EdmSchemaErrors, and adds them - /// to the errors collection of the template class - /// - private bool ProcessErrors(IEnumerable errors, string sourceFilePath) - { - bool foundErrors = false; - foreach (EdmSchemaError error in errors) - { - CompilerError newError = new CompilerError(error.SchemaLocation, error.Line, error.Column, - error.ErrorCode.ToString(CultureInfo.InvariantCulture), - error.Message); - newError.IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning; - foundErrors |= error.Severity == EdmSchemaErrorSeverity.Error; - if (error.SchemaLocation == null) - { - newError.FileName = sourceFilePath; - } - _textTransformation.Errors.Add(newError); - } - - return foundErrors; - } - } - - /// - /// Builder class for creating a StorageMappingItemCollection - /// - private class StorageMappingItemCollectionBuilder : ItemCollectionBuilder - { - private readonly EdmItemCollection _edmItemCollection; - private readonly StoreItemCollection _storeItemCollection; - - public StorageMappingItemCollectionBuilder(DynamicTextTransformation textTransformation, EdmItemCollection edmItemCollection, StoreItemCollection storeItemCollection) - : base(textTransformation, MetadataConstants.MSL_EXTENSION, MetadataConstants.MSL_EDMX_SECTION_NAME, MetadataConstants.MSL_ROOT_ELEMENT_NAME) - { - _edmItemCollection = edmItemCollection; - _storeItemCollection = storeItemCollection; - } - - protected override ItemCollection CreateItemCollection(IEnumerable readers, out IList errors) - { - return MetadataItemCollectionFactory.CreateStorageMappingItemCollection(_edmItemCollection, _storeItemCollection, readers, out errors); - } - - /// - /// Selects a namespace from the supplied constants. - /// - protected override string GetNamespace(SchemaConstants constants) - { - return constants.MslNamespace; - } - } - - /// - /// Builder class for creating a StoreItemCollection - /// - private class StoreItemCollectionBuilder : ItemCollectionBuilder - { - public StoreItemCollectionBuilder(DynamicTextTransformation textTransformation) - : base(textTransformation, MetadataConstants.SSDL_EXTENSION, MetadataConstants.SSDL_EDMX_SECTION_NAME, MetadataConstants.SSDL_ROOT_ELEMENT_NAME) - { - } - - protected override ItemCollection CreateItemCollection(IEnumerable readers, out IList errors) - { - return MetadataItemCollectionFactory.CreateStoreItemCollection(readers, out errors); - } - - /// - /// Selects a namespace from the supplied constants. - /// - protected override string GetNamespace(SchemaConstants constants) - { - return constants.SsdlNamespace; - } - } - - /// - /// Builder class for creating a EdmItemCollection - /// - private class EdmItemCollectionBuilder : ItemCollectionBuilder - { - private List _referenceSchemas = new List(); - - public EdmItemCollectionBuilder(DynamicTextTransformation textTransformation) - : base(textTransformation, MetadataConstants.CSDL_EXTENSION, MetadataConstants.CSDL_EDMX_SECTION_NAME, MetadataConstants.CSDL_ROOT_ELEMENT_NAME) - { - } - - public EdmItemCollectionBuilder(DynamicTextTransformation textTransformation, IEnumerable referenceSchemas) - : this(textTransformation) - { - _referenceSchemas.AddRange(referenceSchemas); - } - - protected override ItemCollection CreateItemCollection(IEnumerable readers, out IList errors) - { - List ownedReaders = new List(); - List allReaders = new List(); - try - { - allReaders.AddRange(readers); - foreach (string path in _referenceSchemas.Distinct()) - { - XElement reference; - if(TryLoadRootElement(path, out reference)) - { - XmlReader reader = reference.CreateReader(); - allReaders.Add(reader); - ownedReaders.Add(reader); - } - } - - return MetadataItemCollectionFactory.CreateEdmItemCollection(allReaders, out errors); - } - finally - { - foreach (XmlReader reader in ownedReaders) - { - ((IDisposable)reader).Dispose(); - } - } - } - - /// - /// Selects a namespace from the supplied constants. - /// - protected override string GetNamespace(SchemaConstants constants) - { - return constants.CsdlNamespace; - } - } -} - -/// -/// Responsible for encapsulating the retrieval and translation of the CodeGeneration -/// annotations in the EntityFramework Metadata to a form that is useful in code generation. -/// -public static class Accessibility -{ - private const string GETTER_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:GetterAccess"; - private const string SETTER_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:SetterAccess"; - private const string TYPE_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:TypeAccess"; - private const string METHOD_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:MethodAccess"; - private const string ACCESS_PROTECTED = "Protected"; - private const string ACCESS_INTERNAL = "Internal"; - private const string ACCESS_PRIVATE = "Private"; - private static readonly Dictionary AccessibilityRankIdLookup = new Dictionary - { - { "private", 1}, - { "internal", 2}, - { "protected", 3}, - { "public", 4}, - }; - - /// - /// Gets the accessibility that should be applied to a type being generated from the provided GlobalItem. - /// - /// defaults to public if no annotation is found. - /// - public static string ForType(GlobalItem item) - { - if (item == null) - { - return null; - } - - return GetAccessibility(item, TYPE_ACCESS); - } - - /// - /// Gets the accessibility that should be applied at the property level for a property being - /// generated from the provided EdmMember. - /// - /// defaults to public if no annotation is found. - /// - public static string ForProperty(EdmMember member) - { - if (member == null) - { - return null; - } - - string getterAccess, setterAccess, propertyAccess; - CalculatePropertyAccessibility(member, out propertyAccess, out getterAccess, out setterAccess); - return propertyAccess; - } - - /// - /// Gets the accessibility that should be applied at the property level for a Read-Only property being - /// generated from the provided EdmMember. - /// - /// defaults to public if no annotation is found. - /// - public static string ForReadOnlyProperty(EdmMember member) - { - if (member == null) - { - return null; - } - - return GetAccessibility(member, GETTER_ACCESS); - } - - /// - /// Gets the accessibility that should be applied at the property level for a property being - /// generated from the provided EntitySet. - /// - /// defaults to public if no annotation is found. - /// - public static string ForReadOnlyProperty(EntitySet set) - { - if (set == null) - { - return null; - } - - return GetAccessibility(set, GETTER_ACCESS); - } - - /// - /// Gets the accessibility that should be applied at the property level for a Write-Only property being - /// generated from the provided EdmMember. - /// - /// defaults to public if no annotation is found. - /// - public static string ForWriteOnlyProperty(EdmMember member) - { - if (member == null) - { - return null; - } - - return GetAccessibility(member, SETTER_ACCESS); - } - - - /// - /// Gets the accessibility that should be applied at the get level for a property being - /// generated from the provided EdmMember. - /// - /// defaults to empty if no annotation is found or the accessibility is the same as the property level. - /// - public static string ForGetter(EdmMember member) - { - if (member == null) - { - return null; - } - - string getterAccess, setterAccess, propertyAccess; - CalculatePropertyAccessibility(member, out propertyAccess, out getterAccess, out setterAccess); - return getterAccess; - } - - /// - /// Gets the accessibility that should be applied at the set level for a property being - /// generated from the provided EdmMember. - /// - /// defaults to empty if no annotation is found or the accessibility is the same as the property level. - /// - public static string ForSetter(EdmMember member) - { - if (member == null) - { - return null; - } - - string getterAccess, setterAccess, propertyAccess; - CalculatePropertyAccessibility(member, out propertyAccess, out getterAccess, out setterAccess); - return setterAccess; - } - - /// - /// Gets the accessibility that should be applied to a method being generated from the provided EdmFunction. - /// - /// defaults to public if no annotation is found. - /// - public static string ForMethod(EdmFunction function) - { - if (function == null) - { - return null; - } - - return GetAccessibility(function, METHOD_ACCESS); - } - - private static void CalculatePropertyAccessibility(MetadataItem item, - out string propertyAccessibility, - out string getterAccessibility, - out string setterAccessibility) - { - getterAccessibility = GetAccessibility(item, GETTER_ACCESS); - int getterRank = AccessibilityRankIdLookup[getterAccessibility]; - - setterAccessibility = GetAccessibility(item, SETTER_ACCESS); - int setterRank = AccessibilityRankIdLookup[setterAccessibility]; - - int propertyRank = Math.Max(getterRank, setterRank); - if (setterRank == propertyRank) - { - setterAccessibility = String.Empty; - } - - if (getterRank == propertyRank) - { - getterAccessibility = String.Empty; - } - - propertyAccessibility = AccessibilityRankIdLookup.Where(v => v.Value == propertyRank).Select(v => v.Key).Single(); - } - - private static string GetAccessibility(MetadataItem item, string name) - { - string accessibility; - if (MetadataTools.TryGetStringMetadataPropertySetting(item, name, out accessibility)) - { - return TranslateUserAccessibilityToCSharpAccessibility(accessibility); - } - - return "public"; - } - - private static string TranslateUserAccessibilityToCSharpAccessibility(string userAccessibility) - { - if (userAccessibility == ACCESS_PROTECTED) - { - return "protected"; - } - else if (userAccessibility == ACCESS_INTERNAL) - { - return "internal"; - } - else if (userAccessibility == ACCESS_PRIVATE) - { - return "private"; - } - else - { - // default to public - return "public"; - } - } -} - -/// -/// Responsible for creating source code regions in code when the loop inside -/// actually produces something. -/// -public class CodeRegion -{ - private const int STANDARD_INDENT_LENGTH = 4; - - private readonly DynamicTextTransformation _textTransformation; - private int _beforeRegionLength; - private int _emptyRegionLength; - private int _regionIndentLevel = -1; - - /// - /// Initializes an CodeRegion instance with the - /// TextTransformation (T4 generated class) that is currently running - /// - public CodeRegion(object textTransformation) - { - if (textTransformation == null) - { - throw new ArgumentNullException("textTransformation"); - } - - _textTransformation = DynamicTextTransformation.Create(textTransformation); - } - - /// - /// Initializes an CodeRegion instance with the - /// TextTransformation (T4 generated class) that is currently running, - /// and the indent level to start the first region at. - /// - public CodeRegion(object textTransformation, int firstIndentLevel) - : this(textTransformation) - { - if (firstIndentLevel < 0) - { - throw new ArgumentException("firstIndentLevel"); - } - - _regionIndentLevel = firstIndentLevel - 1; - } - - /// - /// Starts the begining of a region - /// - public void Begin(string regionName) - { - if (regionName == null) - { - throw new ArgumentNullException("regionName"); - } - - Begin(regionName, 1); - } - - /// - /// Start the begining of a region, indented - /// the numbers of levels specified - /// - public void Begin(string regionName, int levelsToIncreaseIndent) - { - if (regionName == null) - { - throw new ArgumentNullException("regionName"); - } - - _beforeRegionLength = _textTransformation.GenerationEnvironment.Length; - _regionIndentLevel += levelsToIncreaseIndent; - _textTransformation.Write(GetIndent(_regionIndentLevel)); - _textTransformation.WriteLine("#region " + regionName); - _emptyRegionLength = _textTransformation.GenerationEnvironment.Length; - } - - /// - /// Ends a region, or totaly removes it if nothing - /// was generted since the begining of the region. - /// - public void End() - { - End(1); - } - - /// - /// Ends a region, or totaly removes it if nothing - /// was generted since the begining of the region, also outdents - /// the number of levels specified. - /// - public void End(int levelsToDecrease) - { - int indentLevel = _regionIndentLevel; - _regionIndentLevel -= levelsToDecrease; - - if (_emptyRegionLength == _textTransformation.GenerationEnvironment.Length) - _textTransformation.GenerationEnvironment.Length = _beforeRegionLength; - else - { - _textTransformation.WriteLine(String.Empty); - _textTransformation.Write(GetIndent(indentLevel)); - _textTransformation.WriteLine("#endregion"); - _textTransformation.WriteLine(String.Empty); - } - } - - /// - /// Gets the current indent level that the next end region statement will be written - /// at - /// - public int CurrentIndentLevel { get { return _regionIndentLevel; } } - - /// - /// Get a string of spaces equivelent to the number of indents - /// desired. - /// - public static string GetIndent(int indentLevel) - { - if (indentLevel < 0) - { - throw new ArgumentException("indentLevel"); - } - - return String.Empty.PadLeft(indentLevel * STANDARD_INDENT_LENGTH); - } -} - - -/// -/// Responsible for collecting together the actual method parameters -/// and the parameters that need to be sent to the Execute method. -/// -public class FunctionImportParameter -{ - public FunctionParameter Source { get; set; } - public string RawFunctionParameterName { get; set; } - public string FunctionParameterName { get; set; } - public string FunctionParameterType { get; set; } - public string LocalVariableName { get; set; } - public string RawClrTypeName { get; set; } - public string ExecuteParameterName { get; set; } - public string EsqlParameterName { get; set; } - public bool NeedsLocalVariable { get; set; } - public bool IsNullableOfT { get; set; } - - - /// - /// Creates a set of FunctionImportParameter objects from the parameters passed in. - /// - public static IEnumerable Create(IEnumerable parameters, CodeGenerationTools code, MetadataTools ef) - { - if (parameters == null) - { - throw new ArgumentNullException("parameters"); - } - - if (code == null) - { - throw new ArgumentNullException("code"); - } - - if (ef == null) - { - throw new ArgumentNullException("ef"); - } - - UniqueIdentifierService unique = new UniqueIdentifierService(); - List importParameters = new List(); - foreach (FunctionParameter parameter in parameters) - { - FunctionImportParameter importParameter = new FunctionImportParameter(); - importParameter.Source = parameter; - importParameter.RawFunctionParameterName = unique.AdjustIdentifier(code.CamelCase(parameter.Name)); - importParameter.FunctionParameterName = code.Escape(importParameter.RawFunctionParameterName); - if (parameter.Mode == ParameterMode.In) - { - TypeUsage typeUsage = parameter.TypeUsage; - importParameter.NeedsLocalVariable = true; - importParameter.FunctionParameterType = code.GetTypeName(typeUsage); - importParameter.EsqlParameterName = parameter.Name; - Type clrType = ef.UnderlyingClrType(parameter.TypeUsage.EdmType); - importParameter.RawClrTypeName = typeUsage.EdmType is EnumType ? code.GetTypeName(typeUsage.EdmType) : code.Escape(clrType); - importParameter.IsNullableOfT = clrType.IsValueType; - } - else - { - importParameter.NeedsLocalVariable = false; - importParameter.FunctionParameterType = "ObjectParameter"; - importParameter.ExecuteParameterName = importParameter.FunctionParameterName; - } - importParameters.Add(importParameter); - } - - // we save the local parameter uniquification for a second pass to make the visible parameters - // as pretty and sensible as possible - for (int i = 0; i < importParameters.Count; i++) - { - FunctionImportParameter importParameter = importParameters[i]; - if (importParameter.NeedsLocalVariable) - { - importParameter.LocalVariableName = unique.AdjustIdentifier(importParameter.RawFunctionParameterName + "Parameter"); - importParameter.ExecuteParameterName = importParameter.LocalVariableName; - } - } - - return importParameters; - } - - // - // Class to create unique variables within the same scope - // - private sealed class UniqueIdentifierService - { - private readonly HashSet _knownIdentifiers; - - public UniqueIdentifierService() - { - _knownIdentifiers = new HashSet(StringComparer.Ordinal); - } - - /// - /// Given an identifier, makes it unique within the scope by adding - /// a suffix (1, 2, 3, ...), and returns the adjusted identifier. - /// - public string AdjustIdentifier(string identifier) - { - // find a unique name by adding suffix as necessary - int numberOfConflicts = 0; - string adjustedIdentifier = identifier; - - while (!_knownIdentifiers.Add(adjustedIdentifier)) - { - ++numberOfConflicts; - adjustedIdentifier = identifier + numberOfConflicts.ToString(CultureInfo.InvariantCulture); - } - - return adjustedIdentifier; - } - } -} - -/// -/// Responsible for marking the various sections of the generation, -/// so they can be split up into separate files -/// -public class EntityFrameworkTemplateFileManager -{ - /// - /// Creates the VsEntityFrameworkTemplateFileManager if VS is detected, otherwise - /// creates the file system version. - /// - public static EntityFrameworkTemplateFileManager Create(object textTransformation) - { - DynamicTextTransformation transformation = DynamicTextTransformation.Create(textTransformation); - IDynamicHost host = transformation.Host; - -#if !PREPROCESSED_TEMPLATE - var hostServiceProvider = host.AsIServiceProvider(); - - if (hostServiceProvider != null) - { - EnvDTE.DTE dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE)); - - if (dte != null) - { - return new VsEntityFrameworkTemplateFileManager(transformation); - } - } -#endif - return new EntityFrameworkTemplateFileManager(transformation); - } - - private sealed class Block - { - public String Name; - public int Start, Length; - } - - private readonly List files = new List(); - private readonly Block footer = new Block(); - private readonly Block header = new Block(); - private readonly DynamicTextTransformation _textTransformation; - - // reference to the GenerationEnvironment StringBuilder on the - // TextTransformation object - private readonly StringBuilder _generationEnvironment; - - private Block currentBlock; - - /// - /// Initializes an EntityFrameworkTemplateFileManager Instance with the - /// TextTransformation (T4 generated class) that is currently running - /// - private EntityFrameworkTemplateFileManager(object textTransformation) - { - if (textTransformation == null) - { - throw new ArgumentNullException("textTransformation"); - } - - _textTransformation = DynamicTextTransformation.Create(textTransformation); - _generationEnvironment = _textTransformation.GenerationEnvironment; - } - - /// - /// Marks the end of the last file if there was one, and starts a new - /// and marks this point in generation as a new file. - /// - public void StartNewFile(string name) - { - if (name == null) - { - throw new ArgumentNullException("name"); - } - - CurrentBlock = new Block { Name = name }; - } - - public void StartFooter() - { - CurrentBlock = footer; - } - - public void StartHeader() - { - CurrentBlock = header; - } - - public void EndBlock() - { - if (CurrentBlock == null) - { - return; - } - - CurrentBlock.Length = _generationEnvironment.Length - CurrentBlock.Start; - - if (CurrentBlock != header && CurrentBlock != footer) - { - files.Add(CurrentBlock); - } - - currentBlock = null; - } - - /// - /// Produce the template output files. - /// - public virtual IEnumerable Process(bool split = true) - { - var generatedFileNames = new List(); - - if (split) - { - EndBlock(); - - var headerText = _generationEnvironment.ToString(header.Start, header.Length); - var footerText = _generationEnvironment.ToString(footer.Start, footer.Length); - var outputPath = Path.GetDirectoryName(_textTransformation.Host.TemplateFile); - - files.Reverse(); - - foreach (var block in files) - { - var fileName = Path.Combine(outputPath, block.Name); - var content = headerText + _generationEnvironment.ToString(block.Start, block.Length) + footerText; - - generatedFileNames.Add(fileName); - CreateFile(fileName, content); - _generationEnvironment.Remove(block.Start, block.Length); - } - } - - return generatedFileNames; - } - - protected virtual void CreateFile(string fileName, string content) - { - if (IsFileContentDifferent(fileName, content)) - { - File.WriteAllText(fileName, content); - } - } - - protected bool IsFileContentDifferent(String fileName, string newContent) - { - return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent); - } - - private Block CurrentBlock - { - get { return currentBlock; } - set - { - if (CurrentBlock != null) - { - EndBlock(); - } - - if (value != null) - { - value.Start = _generationEnvironment.Length; - } - - currentBlock = value; - } - } - -#if !PREPROCESSED_TEMPLATE - private sealed class VsEntityFrameworkTemplateFileManager : EntityFrameworkTemplateFileManager - { - private EnvDTE.ProjectItem templateProjectItem; - private EnvDTE.DTE dte; - private Action checkOutAction; - private Action> projectSyncAction; - - /// - /// Creates an instance of the VsEntityFrameworkTemplateFileManager class with the IDynamicHost instance - /// - public VsEntityFrameworkTemplateFileManager(object textTemplating) - : base(textTemplating) - { - var hostServiceProvider = _textTransformation.Host.AsIServiceProvider(); - if (hostServiceProvider == null) - { - throw new ArgumentNullException("Could not obtain hostServiceProvider"); - } - - dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE)); - if (dte == null) - { - throw new ArgumentNullException("Could not obtain DTE from host"); - } - - templateProjectItem = dte.Solution.FindProjectItem(_textTransformation.Host.TemplateFile); - - checkOutAction = fileName => dte.SourceControl.CheckOutItem(fileName); - projectSyncAction = keepFileNames => ProjectSync(templateProjectItem, keepFileNames); - } - - public override IEnumerable Process(bool split) - { - if (templateProjectItem.ProjectItems == null) - { - return new List(); - } - - var generatedFileNames = base.Process(split); - - projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null)); - - return generatedFileNames; - } - - protected override void CreateFile(string fileName, string content) - { - if (IsFileContentDifferent(fileName, content)) - { - CheckoutFileIfRequired(fileName); - File.WriteAllText(fileName, content); - } - } - - private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable keepFileNames) - { - var keepFileNameSet = new HashSet(keepFileNames); - var projectFiles = new Dictionary(); - var originalOutput = Path.GetFileNameWithoutExtension(templateProjectItem.FileNames[0]); - - foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) - { - projectFiles.Add(projectItem.FileNames[0], projectItem); - } - - // Remove unused items from the project - foreach (var pair in projectFiles) - { - if (!keepFileNames.Contains(pair.Key) - && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalOutput + ".")) - { - pair.Value.Delete(); - } - } - - // Add missing files to the project - foreach (string fileName in keepFileNameSet) - { - if (!projectFiles.ContainsKey(fileName)) - { - templateProjectItem.ProjectItems.AddFromFile(fileName); - } - } - } - - private void CheckoutFileIfRequired(string fileName) - { - if (dte.SourceControl == null - || !dte.SourceControl.IsItemUnderSCC(fileName) - || dte.SourceControl.IsItemCheckedOut(fileName)) - { - return; - } - - // run on worker thread to prevent T4 calling back into VS - checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null)); - } - } -#endif -} - -/// -/// Responsible creating an instance that can be passed -/// to helper classes that need to access the TextTransformation -/// members. It accesses member by name and signature rather than -/// by type. This is necessary when the -/// template is being used in Preprocessed mode -/// and there is no common known type that can be -/// passed instead -/// -public class DynamicTextTransformation -{ - private object _instance; - IDynamicHost _dynamicHost; - - private readonly MethodInfo _write; - private readonly MethodInfo _writeLine; - private readonly PropertyInfo _generationEnvironment; - private readonly PropertyInfo _errors; - private readonly PropertyInfo _host; - - /// - /// Creates an instance of the DynamicTextTransformation class around the passed in - /// TextTransformation shapped instance passed in, or if the passed in instance - /// already is a DynamicTextTransformation, it casts it and sends it back. - /// - public static DynamicTextTransformation Create(object instance) - { - if (instance == null) - { - throw new ArgumentNullException("instance"); - } - - DynamicTextTransformation textTransformation = instance as DynamicTextTransformation; - if (textTransformation != null) - { - return textTransformation; - } - - return new DynamicTextTransformation(instance); - } - - private DynamicTextTransformation(object instance) - { - _instance = instance; - Type type = _instance.GetType(); - _write = type.GetMethod("Write", new Type[] { typeof(string) }); - _writeLine = type.GetMethod("WriteLine", new Type[] { typeof(string) }); - _generationEnvironment = type.GetProperty("GenerationEnvironment", BindingFlags.Instance | BindingFlags.NonPublic); - _host = type.GetProperty("Host"); - _errors = type.GetProperty("Errors"); - } - - /// - /// Gets the value of the wrapped TextTranformation instance's GenerationEnvironment property - /// - public StringBuilder GenerationEnvironment { get { return (StringBuilder)_generationEnvironment.GetValue(_instance, null); } } - - /// - /// Gets the value of the wrapped TextTranformation instance's Errors property - /// - public System.CodeDom.Compiler.CompilerErrorCollection Errors { get { return (System.CodeDom.Compiler.CompilerErrorCollection)_errors.GetValue(_instance, null); } } - - /// - /// Calls the wrapped TextTranformation instance's Write method. - /// - public void Write(string text) - { - _write.Invoke(_instance, new object[] { text }); - } - - /// - /// Calls the wrapped TextTranformation instance's WriteLine method. - /// - public void WriteLine(string text) - { - _writeLine.Invoke(_instance, new object[] { text }); - } - - /// - /// Gets the value of the wrapped TextTranformation instance's Host property - /// if available (shows up when hostspecific is set to true in the template directive) and returns - /// the appropriate implementation of IDynamicHost - /// - public IDynamicHost Host - { - get - { - if (_dynamicHost == null) - { - if(_host == null) - { - _dynamicHost = new NullHost(); - } - else - { - _dynamicHost = new DynamicHost(_host.GetValue(_instance, null)); - } - } - return _dynamicHost; - } - } -} - - -/// -/// Reponsible for abstracting the use of Host between times -/// when it is available and not -/// -public interface IDynamicHost -{ - /// - /// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue - /// - string ResolveParameterValue(string id, string name, string otherName); - - /// - /// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath - /// - string ResolvePath(string path); - - /// - /// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile - /// - string TemplateFile { get; } - - /// - /// Returns the Host instance cast as an IServiceProvider - /// - IServiceProvider AsIServiceProvider(); -} - -/// -/// Reponsible for implementing the IDynamicHost as a dynamic -/// shape wrapper over the Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost interface -/// rather than type dependent wrapper. We don't use the -/// interface type so that the code can be run in preprocessed mode -/// on a .net framework only installed machine. -/// -public class DynamicHost : IDynamicHost -{ - private readonly object _instance; - private readonly MethodInfo _resolveParameterValue; - private readonly MethodInfo _resolvePath; - private readonly PropertyInfo _templateFile; - - /// - /// Creates an instance of the DynamicHost class around the passed in - /// Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost shapped instance passed in. - /// - public DynamicHost(object instance) - { - _instance = instance; - Type type = _instance.GetType(); - _resolveParameterValue = type.GetMethod("ResolveParameterValue", new Type[] { typeof(string), typeof(string), typeof(string) }); - _resolvePath = type.GetMethod("ResolvePath", new Type[] { typeof(string) }); - _templateFile = type.GetProperty("TemplateFile"); - - } - - /// - /// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue - /// - public string ResolveParameterValue(string id, string name, string otherName) - { - return (string)_resolveParameterValue.Invoke(_instance, new object[] { id, name, otherName }); - } - - /// - /// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath - /// - public string ResolvePath(string path) - { - return (string)_resolvePath.Invoke(_instance, new object[] { path }); - } - - /// - /// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile - /// - public string TemplateFile - { - get - { - return (string)_templateFile.GetValue(_instance, null); - } - } - - /// - /// Returns the Host instance cast as an IServiceProvider - /// - public IServiceProvider AsIServiceProvider() - { - return _instance as IServiceProvider; - } -} - -/// -/// Reponsible for implementing the IDynamicHost when the -/// Host property is not available on the TextTemplating type. The Host -/// property only exists when the hostspecific attribute of the template -/// directive is set to true. -/// -public class NullHost : IDynamicHost -{ - /// - /// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue - /// that simply retuns null. - /// - public string ResolveParameterValue(string id, string name, string otherName) - { - return null; - } - - /// - /// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath - /// that simply retuns the path passed in. - /// - public string ResolvePath(string path) - { - return path; - } - - /// - /// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile - /// that returns null. - /// - public string TemplateFile - { - get - { - return null; - } - } - - /// - /// Returns null. - /// - public IServiceProvider AsIServiceProvider() - { - return null; - } -} - -/// -/// Responsible for encapsulating the constants defined in Metadata -/// -public static class MetadataConstants -{ - public const string CSDL_EXTENSION = ".csdl"; - - public const string CSDL_EDMX_SECTION_NAME = "ConceptualModels"; - public const string CSDL_ROOT_ELEMENT_NAME = "Schema"; - public const string EDM_ANNOTATION_09_02 = "http://schemas.microsoft.com/ado/2009/02/edm/annotation"; - - public const string SSDL_EXTENSION = ".ssdl"; - - public const string SSDL_EDMX_SECTION_NAME = "StorageModels"; - public const string SSDL_ROOT_ELEMENT_NAME = "Schema"; - - public const string MSL_EXTENSION = ".msl"; - - public const string MSL_EDMX_SECTION_NAME = "Mappings"; - public const string MSL_ROOT_ELEMENT_NAME = "Mapping"; - - public const string TT_TEMPLATE_NAME = "TemplateName"; - public const string TT_TEMPLATE_VERSION = "TemplateVersion"; - public const string TT_MINIMUM_ENTITY_FRAMEWORK_VERSION = "MinimumEntityFrameworkVersion"; - - public const string DEFAULT_TEMPLATE_VERSION = "4.0"; - - public static readonly SchemaConstants V1_SCHEMA_CONSTANTS = new SchemaConstants( - "http://schemas.microsoft.com/ado/2007/06/edmx", - "http://schemas.microsoft.com/ado/2006/04/edm", - "http://schemas.microsoft.com/ado/2006/04/edm/ssdl", - "urn:schemas-microsoft-com:windows:storage:mapping:CS", - new Version("3.5")); - - public static readonly SchemaConstants V2_SCHEMA_CONSTANTS = new SchemaConstants( - "http://schemas.microsoft.com/ado/2008/10/edmx", - "http://schemas.microsoft.com/ado/2008/09/edm", - "http://schemas.microsoft.com/ado/2009/02/edm/ssdl", - "http://schemas.microsoft.com/ado/2008/09/mapping/cs", - new Version("4.0")); - - public static readonly SchemaConstants V3_SCHEMA_CONSTANTS = new SchemaConstants( - "http://schemas.microsoft.com/ado/2009/11/edmx", - "http://schemas.microsoft.com/ado/2009/11/edm", - "http://schemas.microsoft.com/ado/2009/11/edm/ssdl", - "http://schemas.microsoft.com/ado/2009/11/mapping/cs", - new Version("5.0")); -} - -public struct SchemaConstants -{ - public SchemaConstants(string edmxNamespace, string csdlNamespace, string ssdlNamespace, string mslNamespace, Version minimumTemplateVersion) : this() - { - EdmxNamespace = edmxNamespace; - CsdlNamespace = csdlNamespace; - SsdlNamespace = ssdlNamespace; - MslNamespace = mslNamespace; - MinimumTemplateVersion = minimumTemplateVersion; - } - - public string EdmxNamespace { get; private set; } - public string CsdlNamespace { get; private set; } - public string SsdlNamespace { get; private set; } - public string MslNamespace { get; private set; } - public Version MinimumTemplateVersion { get; private set; } -} +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Data.Entity.Design" #> +<#@ assembly name="System.Xml" #> +<#@ assembly name="System.Xml.Linq"#> +<#@ assembly name="EnvDTE"#> +<#@ import namespace="System" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.IO" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Data.Objects" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Xml" #> +<#@ import namespace="System.Xml.Linq" #> +<#@ import namespace="System.Globalization" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="System.Data.Metadata.Edm" #> +<#@ import namespace="System.Data.Mapping" #> +<#@ import namespace="System.Data.Entity.Design" #> +<#@ import namespace="System.CodeDom" #> +<#@ import namespace="System.CodeDom.Compiler" #> +<#@ import namespace="Microsoft.CSharp"#> +<#@ import namespace="System.Text"#> +<#+ +// Copyright (c) Microsoft Corporation. All rights reserved. + +public static Dictionary TemplateMetadata = new Dictionary(); + +/// +/// Responsible for helping to create source code that is +/// correctly formated and functional +/// +public class CodeGenerationTools +{ + private readonly DynamicTextTransformation _textTransformation; + private readonly CSharpCodeProvider _code; + private readonly MetadataTools _ef; + + /// + /// Initializes a new CodeGenerationTools object with the TextTransformation (T4 generated class) + /// that is currently running + /// + public CodeGenerationTools(object textTransformation) + { + if (textTransformation == null) + { + throw new ArgumentNullException("textTransformation"); + } + + _textTransformation = DynamicTextTransformation.Create(textTransformation); + _code = new CSharpCodeProvider(); + _ef = new MetadataTools(_textTransformation); + FullyQualifySystemTypes = false; + CamelCaseFields = true; + } + + /// + /// When true, all types that are not being generated + /// are fully qualified to keep them from conflicting with + /// types that are being generated. Useful when you have + /// something like a type being generated named System. + /// + /// Default is false. + /// + public bool FullyQualifySystemTypes { get; set; } + + /// + /// When true, the field names are Camel Cased, + /// otherwise they will preserve the case they + /// start with. + /// + /// Default is true. + /// + public bool CamelCaseFields { get; set; } + + /// + /// Returns the NamespaceName suggested by VS if running inside VS. Otherwise, returns + /// null. + /// + public string VsNamespaceSuggestion() + { + string suggestion = _textTransformation.Host.ResolveParameterValue("directiveId", "namespaceDirectiveProcessor", "namespaceHint"); + if (String.IsNullOrEmpty(suggestion)) + { + return null; + } + + return suggestion; + } + + /// + /// Returns a string that is safe for use as an identifier in C#. + /// Keywords are escaped. + /// + public string Escape(string name) + { + if (name == null) + { + return null; + } + + return _code.CreateEscapedIdentifier(name); + } + + /// + /// Returns the name of the TypeUsage's EdmType that is safe for + /// use as an identifier. + /// + public string Escape(TypeUsage typeUsage) + { + if (typeUsage == null) + { + return null; + } + + if (typeUsage.EdmType is ComplexType || + typeUsage.EdmType is EntityType) + { + return Escape(typeUsage.EdmType.Name); + } + else if (typeUsage.EdmType is SimpleType) + { + Type clrType = _ef.UnderlyingClrType(typeUsage.EdmType); + string typeName = typeUsage.EdmType is EnumType ? Escape(typeUsage.EdmType.Name) : Escape(clrType); + if (clrType.IsValueType && _ef.IsNullable(typeUsage)) + { + return String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName); + } + + return typeName; + } + else if (typeUsage.EdmType is CollectionType) + { + return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", Escape(((CollectionType)typeUsage.EdmType).TypeUsage)); + } + + throw new ArgumentException("typeUsage"); + } + + /// + /// Returns the name of the EdmMember that is safe for + /// use as an identifier. + /// + public string Escape(EdmMember member) + { + if (member == null) + { + return null; + } + + return Escape(member.Name); + } + + /// + /// Returns the name of the EdmType that is safe for + /// use as an identifier. + /// + public string Escape(EdmType type) + { + if (type == null) + { + return null; + } + + return Escape(type.Name); + } + + /// + /// Returns the name of the EdmFunction that is safe for + /// use as an identifier. + /// + public string Escape(EdmFunction function) + { + if (function == null) + { + return null; + } + + return Escape(function.Name); + } + + /// + /// Returns the name of the EnumMember that is safe for + /// use as an identifier. + /// + public string Escape(EnumMember member) + { + if (member == null) + { + return null; + } + + return Escape(member.Name); + } + + /// + /// Returns the name of the EntityContainer that is safe for + /// use as an identifier. + /// + public string Escape(EntityContainer container) + { + if (container == null) + { + return null; + } + + return Escape(container.Name); + } + + /// + /// Returns the name of the EntitySet that is safe for + /// use as an identifier. + /// + public string Escape(EntitySet set) + { + if (set == null) + { + return null; + } + + return Escape(set.Name); + } + + /// + /// Returns the name of the StructuralType that is safe for + /// use as an identifier. + /// + public string Escape(StructuralType type) + { + if (type == null) + { + return null; + } + + return Escape(type.Name); + } + + /// + /// Returns the NamespaceName with each segment safe to + /// use as an identifier. + /// + public string EscapeNamespace(string namespaceName) + { + if (String.IsNullOrEmpty(namespaceName)) + { + return namespaceName; + } + + string[] parts = namespaceName.Split('.'); + namespaceName = String.Empty; + foreach (string part in parts) + { + if (namespaceName != String.Empty) + { + namespaceName += "."; + } + + namespaceName += Escape(part); + } + + return namespaceName; + } + + /// + /// Returns the name of the EdmMember formatted for + /// use as a field identifier. + /// + /// This method changes behavior based on the CamelCaseFields + /// setting. + /// + public string FieldName(EdmMember member) + { + if (member == null) + { + return null; + } + + return FieldName(member.Name); + } + + /// + /// Returns the name of the EntitySet formatted for + /// use as a field identifier. + /// + /// This method changes behavior based on the CamelCaseFields + /// setting. + /// + public string FieldName(EntitySet set) + { + if (set == null) + { + return null; + } + + return FieldName(set.Name); + + } + + private string FieldName(string name) + { + if (CamelCaseFields) + { + return "_" + CamelCase(name); + } + else + { + return "_" + name; + } + } + + /// + /// Returns the name of the Type object formatted for + /// use in source code. + /// + /// This method changes behavior based on the FullyQualifySystemTypes + /// setting. + /// + public string Escape(Type clrType) + { + return Escape(clrType, FullyQualifySystemTypes); + } + + /// + /// Returns the name of the Type object formatted for + /// use in source code. + /// + public string Escape(Type clrType, bool fullyQualifySystemTypes) + { + if(clrType == null) + { + return null; + } + + string typeName; + if (fullyQualifySystemTypes) + { + typeName = "global::" + clrType.FullName; + } + else + { + typeName = _code.GetTypeOutput(new CodeTypeReference(clrType)); + } + return typeName; + } + + /// + /// Returns the abstract option if the entity is Abstract, otherwise returns String.Empty + /// + public string AbstractOption(EntityType entity) + { + if (entity.Abstract) + { + return "abstract"; + } + return String.Empty; + } + + /// + /// Returns the passed in identifier with the first letter changed to lowercase + /// + public string CamelCase(string identifier) + { + if (String.IsNullOrEmpty(identifier)) + { + return identifier; + } + + if (identifier.Length == 1) + { + return identifier[0].ToString(CultureInfo.InvariantCulture).ToLowerInvariant(); + } + + return identifier[0].ToString(CultureInfo.InvariantCulture).ToLowerInvariant() + identifier.Substring(1); + } + + /// + /// If the value parameter is null or empty an empty string is returned, + /// otherwise it retuns value with a single space concatenated on the end. + /// + public string SpaceAfter(string value) + { + return StringAfter(value, " "); + } + + /// + /// If the value parameter is null or empty an empty string is returned, + /// otherwise it retuns value with a single space concatenated on the end. + /// + public string SpaceBefore(string value) + { + return StringBefore(" ", value); + } + + /// + /// If the value parameter is null or empty an empty string is returned, + /// otherwise it retuns value with append concatenated on the end. + /// + public string StringAfter(string value, string append) + { + if (String.IsNullOrEmpty(value)) + { + return String.Empty; + } + + return value + append; + } + + /// + /// If the value parameter is null or empty an empty string is returned, + /// otherwise it retuns value with prepend concatenated on the front. + /// + public string StringBefore(string prepend, string value) + { + if (String.IsNullOrEmpty(value)) + { + return String.Empty; + } + + return prepend + value; + } + + /// + /// Returns false and shows an error if the supplied type names aren't case-insensitively unique, + /// otherwise returns true. + /// + public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) + { + return VerifyCaseInsensitiveUniqueness(types, t => string.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CaseInsensitiveTypeConflict"), t), sourceFile); + } + + /// + /// Returns false and shows an error if the supplied strings aren't case-insensitively unique, + /// otherwise returns true. + /// + private bool VerifyCaseInsensitiveUniqueness(IEnumerable items, Func formatMessage, string sourceFile) + { + HashSet hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); + foreach (string item in items) + { + if (!hash.Add(item)) + { + _textTransformation.Errors.Add(new System.CodeDom.Compiler.CompilerError(sourceFile, -1, -1, "6023", formatMessage(item))); + return false; + } + } + return true; + } + + /// + /// Returns the names of the items in the supplied collection that correspond to O-Space types. + /// + public IEnumerable GetAllGlobalItems(EdmItemCollection itemCollection) + { + return itemCollection.GetItems().Where(i => i is EntityType || i is ComplexType || i is EnumType || i is EntityContainer).Select(g => GetGlobalItemName(g)); + } + + /// + /// Returns the name of the supplied GlobalItem. + /// + public string GetGlobalItemName(GlobalItem item) + { + if (item is EdmType) + { + return ((EdmType)item).Name; + } + else + { + return ((EntityContainer)item).Name; + } + } + + /// + /// Retuns as full of a name as possible, if a namespace is provided + /// the namespace and name are combined with a period, otherwise just + /// the name is returned. + /// + public string CreateFullName(string namespaceName, string name) + { + if (String.IsNullOrEmpty(namespaceName)) + { + return name; + } + + return namespaceName + "." + name; + } + + /// + /// Retuns a literal representing the supplied value. + /// + public string CreateLiteral(object value) + { + if (value == null) + { + return string.Empty; + } + + Type type = value.GetType(); + if (type.IsEnum) + { + return type.FullName + "." + value.ToString(); + } + if (type == typeof(Guid)) + { + return string.Format(CultureInfo.InvariantCulture, "new Guid(\"{0}\")", + ((Guid)value).ToString("D", CultureInfo.InvariantCulture)); + } + else if (type == typeof(DateTime)) + { + return string.Format(CultureInfo.InvariantCulture, "new DateTime({0}, DateTimeKind.Unspecified)", + ((DateTime)value).Ticks); + } + else if (type == typeof(byte[])) + { + var arrayInit = string.Join(", ", ((byte[])value).Select(b => b.ToString(CultureInfo.InvariantCulture)).ToArray()); + return string.Format(CultureInfo.InvariantCulture, "new Byte[] {{{0}}}", arrayInit); + } + else if (type == typeof(DateTimeOffset)) + { + var dto = (DateTimeOffset)value; + return string.Format(CultureInfo.InvariantCulture, "new DateTimeOffset({0}, new TimeSpan({1}))", + dto.Ticks, dto.Offset.Ticks); + } + else if (type == typeof(TimeSpan)) + { + return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", + ((TimeSpan)value).Ticks); + } + + var expression = new CodePrimitiveExpression(value); + var writer = new StringWriter(); + CSharpCodeProvider code = new CSharpCodeProvider(); + code.GenerateCodeFromExpression(expression, writer, new CodeGeneratorOptions()); + return writer.ToString(); + } + + /// + /// Returns a resource string from the System.Data.Entity.Design assembly. + /// + public static string GetResourceString(string resourceName, CultureInfo culture = null) + { + if(_resourceManager == null) + { + _resourceManager = new System.Resources.ResourceManager("System.Data.Entity.Design", + typeof(System.Data.Entity.Design.MetadataItemCollectionFactory).Assembly); + } + + return _resourceManager.GetString(resourceName, culture); + } + static System.Resources.ResourceManager _resourceManager; + + private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; + + /// + /// Gets the entity, complex, or enum types for which code should be generated from the given item collection. + /// Any types for which an ExternalTypeName annotation has been applied in the conceptual model + /// metadata (CSDL) are filtered out of the returned list. + /// + /// The type of item to return. + /// The item collection to look in. + /// The items to generate. + public IEnumerable GetItemsToGenerate(ItemCollection itemCollection) where T: GlobalItem + { + return itemCollection.GetItems().Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)); + } + + /// + /// Returns the escaped type name to use for the given usage of a c-space type in o-space. This might be + /// an external type name if the ExternalTypeName annotation has been specified in the + /// conceptual model metadata (CSDL). + /// + /// The c-space type usage to get a name for. + /// The type name to use. + public string GetTypeName(TypeUsage typeUsage) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); + } + + /// + /// Returns the escaped type name to use for the given c-space type in o-space. This might be + /// an external type name if the ExternalTypeName annotation has been specified in the + /// conceptual model metadata (CSDL). + /// + /// The c-space type to get a name for. + /// The type name to use. + public string GetTypeName(EdmType edmType) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: null); + } + + /// + /// Returns the escaped type name to use for the given usage of an c-space type in o-space. This might be + /// an external type name if the ExternalTypeName annotation has been specified in the + /// conceptual model metadata (CSDL). + /// + /// The c-space type usage to get a name for. + /// If not null and the type's namespace does not match this namespace, then a + /// fully qualified name will be returned. + /// The type name to use. + public string GetTypeName(TypeUsage typeUsage, string modelNamespace) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); + } + + /// + /// Returns the escaped type name to use for the given c-space type in o-space. This might be + /// an external type name if the ExternalTypeName annotation has been specified in the + /// conceptual model metadata (CSDL). + /// + /// The c-space type to get a name for. + /// If not null and the type's namespace does not match this namespace, then a + /// fully qualified name will be returned. + /// The type name to use. + public string GetTypeName(EdmType edmType, string modelNamespace) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); + } + + /// + /// Returns the escaped type name to use for the given c-space type in o-space. This might be + /// an external type name if the ExternalTypeName annotation has been specified in the + /// conceptual model metadata (CSDL). + /// + /// The c-space type to get a name for. + /// Set this to true for nullable usage of this type. + /// If not null and the type's namespace does not match this namespace, then a + /// fully qualified name will be returned. + /// The type name to use. + private string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) + { + if (edmType == null) + { + return null; + } + + var collectionType = edmType as CollectionType; + if (collectionType != null) + { + return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); + } + + // Try to get an external type name, and if that is null, then try to get escape the name from metadata, + // possibly namespace-qualifying it. + var typeName = Escape(edmType.MetadataProperties + .Where(p => p.Name == ExternalTypeNameAttributeName) + .Select(p => (string)p.Value) + .FirstOrDefault()) + ?? + (modelNamespace != null && edmType.NamespaceName != modelNamespace ? + CreateFullName(EscapeNamespace(edmType.NamespaceName), Escape(edmType)) : + Escape(edmType)); + + if (edmType is StructuralType) + { + return typeName; + } + + if (edmType is SimpleType) + { + var clrType = _ef.UnderlyingClrType(edmType); + if (!(edmType is EnumType)) + { + typeName = Escape(clrType); + } + + return clrType.IsValueType && isNullable == true ? + String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : + typeName; + } + + throw new ArgumentException("typeUsage"); + } +} + +/// +/// Responsible for making the Entity Framework Metadata more +/// accessible for code generation. +/// +public class MetadataTools +{ + private readonly DynamicTextTransformation _textTransformation; + + /// + /// Initializes an MetadataTools Instance with the + /// TextTransformation (T4 generated class) that is currently running + /// + public MetadataTools(object textTransformation) + { + if (textTransformation == null) + { + throw new ArgumentNullException("textTransformation"); + } + + _textTransformation = DynamicTextTransformation.Create(textTransformation); + } + + /// + /// This method returns the underlying CLR type of the o-space type corresponding to the supplied + /// Note that for an enum type this means that the type backing the enum will be returned, not the enum type itself. + /// + public Type ClrType(TypeUsage typeUsage) + { + return UnderlyingClrType(typeUsage.EdmType); + } + + /// + /// This method returns the underlying CLR type given the c-space type. + /// Note that for an enum type this means that the type backing the enum will be returned, not the enum type itself. + /// + public Type UnderlyingClrType(EdmType edmType) + { + var primitiveType = edmType as PrimitiveType; + if (primitiveType != null) + { + return primitiveType.ClrEquivalentType; + } + + var enumType = edmType as EnumType; + if (enumType != null) + { + return enumType.UnderlyingType.ClrEquivalentType; + } + + return typeof(object); + } + + /// + /// True if the EdmProperty is a key of its DeclaringType, False otherwise. + /// + public bool IsKey(EdmProperty property) + { + if (property != null && property.DeclaringType.BuiltInTypeKind == BuiltInTypeKind.EntityType) + { + return ((EntityType)property.DeclaringType).KeyMembers.Contains(property); + } + + return false; + } + + /// + /// True if the EdmProperty TypeUsage is Nullable, False otherwise. + /// + public bool IsNullable(EdmProperty property) + { + return property != null && IsNullable(property.TypeUsage); + } + + /// + /// True if the TypeUsage is Nullable, False otherwise. + /// + public bool IsNullable(TypeUsage typeUsage) + { + Facet nullableFacet = null; + if (typeUsage != null && + typeUsage.Facets.TryGetValue("Nullable", true, out nullableFacet)) + { + return (bool)nullableFacet.Value; + } + + return false; + } + + /// + /// If the passed in TypeUsage represents a collection this method returns final element + /// type of the collection, otherwise it returns the value passed in. + /// + public TypeUsage GetElementType(TypeUsage typeUsage) + { + if (typeUsage == null) + { + return null; + } + + if (typeUsage.EdmType is CollectionType) + { + return GetElementType(((CollectionType)typeUsage.EdmType).TypeUsage); + } + else + { + return typeUsage; + } + } + + /// + /// Returns the NavigationProperty that is the other end of the same association set if it is + /// available, otherwise it returns null. + /// + public NavigationProperty Inverse(NavigationProperty navProperty) + { + if(navProperty == null) + { + return null; + } + + EntityType toEntity = navProperty.ToEndMember.GetEntityType(); + return toEntity.NavigationProperties + .SingleOrDefault(n => Object.ReferenceEquals(n.RelationshipType, navProperty.RelationshipType) && !Object.ReferenceEquals(n, navProperty)); + } + + /// + /// Given a property on the dependent end of a referential constraint, returns the corresponding property on the principal end. + /// Requires: The association has a referential constraint, and the specified dependentProperty is one of the properties on the dependent end. + /// + public EdmProperty GetCorrespondingPrincipalProperty(NavigationProperty navProperty, EdmProperty dependentProperty) + { + if (navProperty == null) + { + throw new ArgumentNullException("navProperty"); + } + + if (dependentProperty == null) + { + throw new ArgumentNullException("dependentProperty"); + } + + ReadOnlyMetadataCollection fromProperties = GetPrincipalProperties(navProperty); + ReadOnlyMetadataCollection toProperties = GetDependentProperties(navProperty); + return fromProperties[toProperties.IndexOf(dependentProperty)]; + } + + /// + /// Given a property on the principal end of a referential constraint, returns the corresponding property on the dependent end. + /// Requires: The association has a referential constraint, and the specified principalProperty is one of the properties on the principal end. + /// + public EdmProperty GetCorrespondingDependentProperty(NavigationProperty navProperty, EdmProperty principalProperty) + { + if (navProperty == null) + { + throw new ArgumentNullException("navProperty"); + } + + if (principalProperty == null) + { + throw new ArgumentNullException("principalProperty"); + } + + ReadOnlyMetadataCollection fromProperties = GetPrincipalProperties(navProperty); + ReadOnlyMetadataCollection toProperties = GetDependentProperties(navProperty); + return toProperties[fromProperties.IndexOf(principalProperty)]; + } + + /// + /// Gets the collection of properties that are on the principal end of a referential constraint for the specified navigation property. + /// Requires: The association has a referential constraint. + /// + public ReadOnlyMetadataCollection GetPrincipalProperties(NavigationProperty navProperty) + { + if (navProperty == null) + { + throw new ArgumentNullException("navProperty"); + } + + return ((AssociationType)navProperty.RelationshipType).ReferentialConstraints[0].FromProperties; + } + + /// + /// Gets the collection of properties that are on the dependent end of a referential constraint for the specified navigation property. + /// Requires: The association has a referential constraint. + /// + public ReadOnlyMetadataCollection GetDependentProperties(NavigationProperty navProperty) + { + if (navProperty == null) + { + throw new ArgumentNullException("navProperty"); + } + + return ((AssociationType)navProperty.RelationshipType).ReferentialConstraints[0].ToProperties; + } + + /// + /// True if this entity type requires the HandleCascadeDelete method defined and the method has + /// not been defined on any base type + /// + public bool NeedsHandleCascadeDeleteMethod(ItemCollection itemCollection, EntityType entity) + { + bool needsMethod = ContainsCascadeDeleteAssociation(itemCollection, entity); + // Check to make sure no base types have already declared this method + EntityType baseType = entity.BaseType as EntityType; + while(needsMethod && baseType != null) + { + needsMethod = !ContainsCascadeDeleteAssociation(itemCollection, baseType); + baseType = baseType.BaseType as EntityType; + } + return needsMethod; + } + + /// + /// True if this entity type participates in any relationships where the other end has an OnDelete + /// cascade delete defined, or if it is the dependent in any identifying relationships + /// + private bool ContainsCascadeDeleteAssociation(ItemCollection itemCollection, EntityType entity) + { + return itemCollection.GetItems().Where(a => + ((RefType)a.AssociationEndMembers[0].TypeUsage.EdmType).ElementType == entity && IsCascadeDeletePrincipal(a.AssociationEndMembers[1]) || + ((RefType)a.AssociationEndMembers[1].TypeUsage.EdmType).ElementType == entity && IsCascadeDeletePrincipal(a.AssociationEndMembers[0])).Any(); + } + + /// + /// True if the source end of the specified navigation property is the principal in an identifying relationship. + /// or if the source end has cascade delete defined. + /// + public bool IsCascadeDeletePrincipal(NavigationProperty navProperty) + { + if (navProperty == null) + { + throw new ArgumentNullException("navProperty"); + } + + return IsCascadeDeletePrincipal((AssociationEndMember)navProperty.FromEndMember); + } + + /// + /// True if the specified association end is the principal in an identifying relationship. + /// or if the association end has cascade delete defined. + /// + public bool IsCascadeDeletePrincipal(AssociationEndMember associationEnd) + { + if (associationEnd == null) + { + throw new ArgumentNullException("associationEnd"); + } + + return associationEnd.DeleteBehavior == OperationAction.Cascade || IsPrincipalEndOfIdentifyingRelationship(associationEnd); + } + + /// + /// True if the specified association end is the principal end in an identifying relationship. + /// In order to be an identifying relationship, the association must have a referential constraint where all of the dependent properties are part of the dependent type's primary key. + /// + public bool IsPrincipalEndOfIdentifyingRelationship(AssociationEndMember associationEnd) + { + if (associationEnd == null) + { + throw new ArgumentNullException("associationEnd"); + } + + ReferentialConstraint refConstraint = ((AssociationType)associationEnd.DeclaringType).ReferentialConstraints.Where(rc => rc.FromRole == associationEnd).SingleOrDefault(); + if (refConstraint != null) + { + EntityType entity = refConstraint.ToRole.GetEntityType(); + return !refConstraint.ToProperties.Where(tp => !entity.KeyMembers.Contains(tp)).Any(); + } + return false; + } + + /// + /// True if the specified association type is an identifying relationship. + /// In order to be an identifying relationship, the association must have a referential constraint where all of the dependent properties are part of the dependent type's primary key. + /// + public bool IsIdentifyingRelationship(AssociationType association) + { + if (association == null) + { + throw new ArgumentNullException("association"); + } + + return IsPrincipalEndOfIdentifyingRelationship(association.AssociationEndMembers[0]) || IsPrincipalEndOfIdentifyingRelationship(association.AssociationEndMembers[1]); + } + + /// + /// requires: firstType is not null + /// effects: if secondType is among the base types of the firstType, return true, + /// otherwise returns false. + /// when firstType is same as the secondType, return false. + /// + public bool IsSubtypeOf(EdmType firstType, EdmType secondType) + { + if (secondType == null) + { + return false; + } + + // walk up firstType hierarchy list + for (EdmType t = firstType.BaseType; t != null; t = t.BaseType) + { + if (t == secondType) + return true; + } + return false; + } + + /// + /// Returns the subtype of the EntityType in the current itemCollection + /// + public IEnumerable GetSubtypesOf(EntityType type, ItemCollection itemCollection, bool includeAbstractTypes) + { + if (type != null) + { + IEnumerable typesInCollection = itemCollection.GetItems(); + foreach (EntityType typeInCollection in typesInCollection) + { + if (type.Equals(typeInCollection) == false && this.IsSubtypeOf(typeInCollection, type)) + { + if ( includeAbstractTypes || !typeInCollection.Abstract) + { + yield return typeInCollection; + } + } + } + } + } + + public static bool TryGetStringMetadataPropertySetting(MetadataItem item, string propertyName, out string value) + { + value = null; + MetadataProperty property = item.MetadataProperties.FirstOrDefault(p => p.Name == propertyName); + if (property != null) + { + value = (string)property.Value; + } + return value != null; + } +} + +/// +/// Responsible for loading an EdmItemCollection from a .edmx file or .csdl files +/// +public class MetadataLoader +{ + private readonly DynamicTextTransformation _textTransformation; + + /// + /// Initializes an MetadataLoader Instance with the + /// TextTransformation (T4 generated class) that is currently running + /// + public MetadataLoader(object textTransformation) + { + if (textTransformation == null) + { + throw new ArgumentNullException("textTransformation"); + } + + _textTransformation = DynamicTextTransformation.Create(textTransformation); + } + + /// + /// Load the metadata for Edm, Store, and Mapping collections and register them + /// with a new MetadataWorkspace, returns false if any of the parts can't be + /// created, some of the ItemCollections may be registered and usable even if false is + /// returned + /// + public bool TryLoadAllMetadata(string inputFile, out MetadataWorkspace metadataWorkspace) + { + metadataWorkspace = new MetadataWorkspace(); + + EdmItemCollection edmItemCollection = CreateEdmItemCollection(inputFile); + metadataWorkspace.RegisterItemCollection(edmItemCollection); + + StoreItemCollection storeItemCollection = null; + if (TryCreateStoreItemCollection(inputFile, out storeItemCollection)) + { + StorageMappingItemCollection storageMappingItemCollection = null; + if (TryCreateStorageMappingItemCollection(inputFile, edmItemCollection, storeItemCollection, out storageMappingItemCollection)) + { + metadataWorkspace.RegisterItemCollection(storeItemCollection); + metadataWorkspace.RegisterItemCollection(storageMappingItemCollection); + return true; + } + } + + return false; + } + + /// + /// Create an EdmItemCollection loaded with the metadata provided + /// + public EdmItemCollection CreateEdmItemCollection(string sourcePath, params string[] referenceSchemas) + { + EdmItemCollection edmItemCollection; + if(TryCreateEdmItemCollection(sourcePath, referenceSchemas, out edmItemCollection)) + { + return edmItemCollection; + } + + return new EdmItemCollection(); + } + + /// + /// Attempts to create a EdmItemCollection from the specified metadata file + /// + public bool TryCreateEdmItemCollection(string sourcePath, out EdmItemCollection edmItemCollection) + { + return TryCreateEdmItemCollection(sourcePath, null, out edmItemCollection); + } + + /// + /// Attempts to create a EdmItemCollection from the specified metadata file + /// + public bool TryCreateEdmItemCollection(string sourcePath, string[] referenceSchemas, out EdmItemCollection edmItemCollection) + { + edmItemCollection = null; + + if (!ValidateInputPath(sourcePath, _textTransformation)) + { + return false; + } + + if (referenceSchemas == null) + { + referenceSchemas = new string[0]; + } + + ItemCollection itemCollection = null; + sourcePath = _textTransformation.Host.ResolvePath(sourcePath); + EdmItemCollectionBuilder collectionBuilder = new EdmItemCollectionBuilder(_textTransformation, referenceSchemas.Select(s => _textTransformation.Host.ResolvePath(s)).Where(s => s != sourcePath)); + if (collectionBuilder.TryCreateItemCollection(sourcePath, out itemCollection)) + { + edmItemCollection = (EdmItemCollection)itemCollection; + } + + return edmItemCollection != null; + } + + /// + /// Attempts to create a StoreItemCollection from the specified metadata file + /// + public bool TryCreateStoreItemCollection(string sourcePath, out StoreItemCollection storeItemCollection) + { + storeItemCollection = null; + + if (!ValidateInputPath(sourcePath, _textTransformation)) + { + return false; + } + + ItemCollection itemCollection = null; + StoreItemCollectionBuilder collectionBuilder = new StoreItemCollectionBuilder(_textTransformation); + if (collectionBuilder.TryCreateItemCollection(_textTransformation.Host.ResolvePath(sourcePath), out itemCollection)) + { + storeItemCollection = (StoreItemCollection)itemCollection; + } + return storeItemCollection != null; + } + + /// + /// Attempts to create a StorageMappingItemCollection from the specified metadata file, EdmItemCollection, and StoreItemCollection + /// + public bool TryCreateStorageMappingItemCollection(string sourcePath, EdmItemCollection edmItemCollection, StoreItemCollection storeItemCollection, out StorageMappingItemCollection storageMappingItemCollection) + { + storageMappingItemCollection = null; + + if (!ValidateInputPath(sourcePath, _textTransformation)) + { + return false; + } + + if (edmItemCollection == null) + { + throw new ArgumentNullException("edmItemCollection"); + } + + if (storeItemCollection == null) + { + throw new ArgumentNullException("storeItemCollection"); + } + + ItemCollection itemCollection = null; + StorageMappingItemCollectionBuilder collectionBuilder = new StorageMappingItemCollectionBuilder(_textTransformation, edmItemCollection, storeItemCollection); + if (collectionBuilder.TryCreateItemCollection(_textTransformation.Host.ResolvePath(sourcePath), out itemCollection)) + { + storageMappingItemCollection = (StorageMappingItemCollection)itemCollection; + } + return storageMappingItemCollection != null; + } + + /// + /// Gets the Model Namespace from the provided schema file. + /// + public string GetModelNamespace(string sourcePath) + { + if (!ValidateInputPath(sourcePath, _textTransformation)) + { + return String.Empty; + } + + EdmItemCollectionBuilder builder = new EdmItemCollectionBuilder(_textTransformation); + XElement model; + if(builder.TryLoadRootElement(_textTransformation.Host.ResolvePath(sourcePath), out model)) + { + XAttribute attribute = model.Attribute("Namespace"); + if (attribute != null) + { + return attribute.Value; + } + } + + return String.Empty; + } + + /// + /// Returns true if the specified file path is valid + /// + private static bool ValidateInputPath(string sourcePath, DynamicTextTransformation textTransformation) + { + if (String.IsNullOrEmpty(sourcePath)) + { + throw new ArgumentException("sourcePath"); + } + + if(sourcePath == "$edmxInputFile$") + { + textTransformation.Errors.Add(new CompilerError(textTransformation.Host.TemplateFile ?? CodeGenerationTools.GetResourceString("Template_CurrentlyRunningTemplate"), -1, -1, string.Empty, + CodeGenerationTools.GetResourceString("Template_ReplaceVsItemTemplateToken"))); + return false; + } + + return true; + } + + /// + /// Base class for ItemCollectionBuilder classes that + /// loads the specific types of metadata + /// + private abstract class ItemCollectionBuilder + { + private readonly DynamicTextTransformation _textTransformation; + private readonly string _fileExtension; + private readonly string _edmxSectionName; + private readonly string _rootElementName; + + /// + /// FileExtension for individual (non-edmx) metadata file for this + /// specific ItemCollection type + /// + public string FileExtension + { + get { return _fileExtension; } + } + + /// + /// The name of the XmlElement in the .edmx element + /// to find this ItemCollection's metadata + /// + public string EdmxSectionName + { + get { return _edmxSectionName; } + } + + /// + /// The name of the root element of this ItemCollection's metadata + /// + public string RootElementName + { + get { return _rootElementName; } + } + + /// + /// Method to build the appropriate ItemCollection + /// + protected abstract ItemCollection CreateItemCollection(IEnumerable readers, out IList errors); + + /// + /// Ctor to setup the ItemCollectionBuilder members + /// + protected ItemCollectionBuilder(DynamicTextTransformation textTransformation, string fileExtension, string edmxSectionName, string rootElementName) + { + _textTransformation = textTransformation; + _fileExtension = fileExtension; + _edmxSectionName = edmxSectionName; + _rootElementName = rootElementName; + } + + /// + /// Selects a namespace from the supplied constants. + /// + protected abstract string GetNamespace(SchemaConstants constants); + + /// + /// Try to create an ItemCollection loaded with the metadata provided + /// + public bool TryCreateItemCollection(string sourcePath, out ItemCollection itemCollection) + { + itemCollection = null; + + if (!ValidateInputPath(sourcePath, _textTransformation)) + { + return false; + } + + XElement schemaElement = null; + if (TryLoadRootElement(sourcePath, out schemaElement)) + { + List readers = new List(); + try + { + readers.Add(schemaElement.CreateReader()); + IList errors = null; + + ItemCollection tempItemCollection = CreateItemCollection(readers, out errors); + if (ProcessErrors(errors, sourcePath)) + { + return false; + } + + itemCollection = tempItemCollection; + return true; + } + finally + { + foreach (XmlReader reader in readers) + { + ((IDisposable)reader).Dispose(); + } + } + } + + return false; + } + + /// + /// Tries to load the root element from the metadata file provided + /// + public bool TryLoadRootElement(string sourcePath, out XElement schemaElement) + { + schemaElement = null; + string extension = Path.GetExtension(sourcePath); + if (extension.Equals(".edmx", StringComparison.InvariantCultureIgnoreCase)) + { + return TryLoadRootElementFromEdmx(sourcePath, out schemaElement); + } + else if(extension.Equals(FileExtension, StringComparison.InvariantCultureIgnoreCase)) + { + // load from single metadata file (.csdl, .ssdl, or .msl) + schemaElement = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); + return true; + } + + return false; + } + + /// + /// Tries to load the root element from the provided edmxDocument + /// + private bool TryLoadRootElementFromEdmx(XElement edmxDocument, SchemaConstants schemaConstants, string sectionName, string rootElementName, out XElement rootElement) + { + rootElement = null; + + XNamespace edmxNs = schemaConstants.EdmxNamespace; + XNamespace sectionNs = GetNamespace(schemaConstants); + + XElement runtime = edmxDocument.Element(edmxNs + "Runtime"); + if (runtime == null) + { + return false; + } + + XElement section = runtime.Element(edmxNs + sectionName); + if (section == null) + { + return false; + } + + string templateVersion; + + if (!TemplateMetadata.TryGetValue(MetadataConstants.TT_TEMPLATE_VERSION, out templateVersion)) + { + templateVersion = MetadataConstants.DEFAULT_TEMPLATE_VERSION; + } + + if (schemaConstants.MinimumTemplateVersion > new Version(templateVersion)) + { + _textTransformation.Errors.Add(new CompilerError( + _textTransformation.Host.TemplateFile ?? CodeGenerationTools.GetResourceString("Template_CurrentlyRunningTemplate"), -1, -1, string.Empty, + CodeGenerationTools.GetResourceString("Template_UnsupportedSchema")) + {IsWarning = true}); + } + + rootElement = section.Element(sectionNs + rootElementName); + return rootElement != null; + } + + /// + /// Tries to load the root element from the provided .edmx metadata file + /// + private bool TryLoadRootElementFromEdmx(string edmxPath, out XElement rootElement) + { + rootElement = null; + + XElement element = XElement.Load(edmxPath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); + + return TryLoadRootElementFromEdmx(element, MetadataConstants.V3_SCHEMA_CONSTANTS, EdmxSectionName, RootElementName, out rootElement) + || TryLoadRootElementFromEdmx(element, MetadataConstants.V2_SCHEMA_CONSTANTS, EdmxSectionName, RootElementName, out rootElement) + || TryLoadRootElementFromEdmx(element, MetadataConstants.V1_SCHEMA_CONSTANTS, EdmxSectionName, RootElementName, out rootElement); + } + + /// + /// Takes an Enumerable of EdmSchemaErrors, and adds them + /// to the errors collection of the template class + /// + private bool ProcessErrors(IEnumerable errors, string sourceFilePath) + { + bool foundErrors = false; + foreach (EdmSchemaError error in errors) + { + CompilerError newError = new CompilerError(error.SchemaLocation, error.Line, error.Column, + error.ErrorCode.ToString(CultureInfo.InvariantCulture), + error.Message); + newError.IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning; + foundErrors |= error.Severity == EdmSchemaErrorSeverity.Error; + if (error.SchemaLocation == null) + { + newError.FileName = sourceFilePath; + } + _textTransformation.Errors.Add(newError); + } + + return foundErrors; + } + } + + /// + /// Builder class for creating a StorageMappingItemCollection + /// + private class StorageMappingItemCollectionBuilder : ItemCollectionBuilder + { + private readonly EdmItemCollection _edmItemCollection; + private readonly StoreItemCollection _storeItemCollection; + + public StorageMappingItemCollectionBuilder(DynamicTextTransformation textTransformation, EdmItemCollection edmItemCollection, StoreItemCollection storeItemCollection) + : base(textTransformation, MetadataConstants.MSL_EXTENSION, MetadataConstants.MSL_EDMX_SECTION_NAME, MetadataConstants.MSL_ROOT_ELEMENT_NAME) + { + _edmItemCollection = edmItemCollection; + _storeItemCollection = storeItemCollection; + } + + protected override ItemCollection CreateItemCollection(IEnumerable readers, out IList errors) + { + return MetadataItemCollectionFactory.CreateStorageMappingItemCollection(_edmItemCollection, _storeItemCollection, readers, out errors); + } + + /// + /// Selects a namespace from the supplied constants. + /// + protected override string GetNamespace(SchemaConstants constants) + { + return constants.MslNamespace; + } + } + + /// + /// Builder class for creating a StoreItemCollection + /// + private class StoreItemCollectionBuilder : ItemCollectionBuilder + { + public StoreItemCollectionBuilder(DynamicTextTransformation textTransformation) + : base(textTransformation, MetadataConstants.SSDL_EXTENSION, MetadataConstants.SSDL_EDMX_SECTION_NAME, MetadataConstants.SSDL_ROOT_ELEMENT_NAME) + { + } + + protected override ItemCollection CreateItemCollection(IEnumerable readers, out IList errors) + { + return MetadataItemCollectionFactory.CreateStoreItemCollection(readers, out errors); + } + + /// + /// Selects a namespace from the supplied constants. + /// + protected override string GetNamespace(SchemaConstants constants) + { + return constants.SsdlNamespace; + } + } + + /// + /// Builder class for creating a EdmItemCollection + /// + private class EdmItemCollectionBuilder : ItemCollectionBuilder + { + private List _referenceSchemas = new List(); + + public EdmItemCollectionBuilder(DynamicTextTransformation textTransformation) + : base(textTransformation, MetadataConstants.CSDL_EXTENSION, MetadataConstants.CSDL_EDMX_SECTION_NAME, MetadataConstants.CSDL_ROOT_ELEMENT_NAME) + { + } + + public EdmItemCollectionBuilder(DynamicTextTransformation textTransformation, IEnumerable referenceSchemas) + : this(textTransformation) + { + _referenceSchemas.AddRange(referenceSchemas); + } + + protected override ItemCollection CreateItemCollection(IEnumerable readers, out IList errors) + { + List ownedReaders = new List(); + List allReaders = new List(); + try + { + allReaders.AddRange(readers); + foreach (string path in _referenceSchemas.Distinct()) + { + XElement reference; + if(TryLoadRootElement(path, out reference)) + { + XmlReader reader = reference.CreateReader(); + allReaders.Add(reader); + ownedReaders.Add(reader); + } + } + + return MetadataItemCollectionFactory.CreateEdmItemCollection(allReaders, out errors); + } + finally + { + foreach (XmlReader reader in ownedReaders) + { + ((IDisposable)reader).Dispose(); + } + } + } + + /// + /// Selects a namespace from the supplied constants. + /// + protected override string GetNamespace(SchemaConstants constants) + { + return constants.CsdlNamespace; + } + } +} + +/// +/// Responsible for encapsulating the retrieval and translation of the CodeGeneration +/// annotations in the EntityFramework Metadata to a form that is useful in code generation. +/// +public static class Accessibility +{ + private const string GETTER_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:GetterAccess"; + private const string SETTER_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:SetterAccess"; + private const string TYPE_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:TypeAccess"; + private const string METHOD_ACCESS = "http://schemas.microsoft.com/ado/2006/04/codegeneration:MethodAccess"; + private const string ACCESS_PROTECTED = "Protected"; + private const string ACCESS_INTERNAL = "Internal"; + private const string ACCESS_PRIVATE = "Private"; + private static readonly Dictionary AccessibilityRankIdLookup = new Dictionary + { + { "private", 1}, + { "internal", 2}, + { "protected", 3}, + { "public", 4}, + }; + + /// + /// Gets the accessibility that should be applied to a type being generated from the provided GlobalItem. + /// + /// defaults to public if no annotation is found. + /// + public static string ForType(GlobalItem item) + { + if (item == null) + { + return null; + } + + return GetAccessibility(item, TYPE_ACCESS); + } + + /// + /// Gets the accessibility that should be applied at the property level for a property being + /// generated from the provided EdmMember. + /// + /// defaults to public if no annotation is found. + /// + public static string ForProperty(EdmMember member) + { + if (member == null) + { + return null; + } + + string getterAccess, setterAccess, propertyAccess; + CalculatePropertyAccessibility(member, out propertyAccess, out getterAccess, out setterAccess); + return propertyAccess; + } + + /// + /// Gets the accessibility that should be applied at the property level for a Read-Only property being + /// generated from the provided EdmMember. + /// + /// defaults to public if no annotation is found. + /// + public static string ForReadOnlyProperty(EdmMember member) + { + if (member == null) + { + return null; + } + + return GetAccessibility(member, GETTER_ACCESS); + } + + /// + /// Gets the accessibility that should be applied at the property level for a property being + /// generated from the provided EntitySet. + /// + /// defaults to public if no annotation is found. + /// + public static string ForReadOnlyProperty(EntitySet set) + { + if (set == null) + { + return null; + } + + return GetAccessibility(set, GETTER_ACCESS); + } + + /// + /// Gets the accessibility that should be applied at the property level for a Write-Only property being + /// generated from the provided EdmMember. + /// + /// defaults to public if no annotation is found. + /// + public static string ForWriteOnlyProperty(EdmMember member) + { + if (member == null) + { + return null; + } + + return GetAccessibility(member, SETTER_ACCESS); + } + + + /// + /// Gets the accessibility that should be applied at the get level for a property being + /// generated from the provided EdmMember. + /// + /// defaults to empty if no annotation is found or the accessibility is the same as the property level. + /// + public static string ForGetter(EdmMember member) + { + if (member == null) + { + return null; + } + + string getterAccess, setterAccess, propertyAccess; + CalculatePropertyAccessibility(member, out propertyAccess, out getterAccess, out setterAccess); + return getterAccess; + } + + /// + /// Gets the accessibility that should be applied at the set level for a property being + /// generated from the provided EdmMember. + /// + /// defaults to empty if no annotation is found or the accessibility is the same as the property level. + /// + public static string ForSetter(EdmMember member) + { + if (member == null) + { + return null; + } + + string getterAccess, setterAccess, propertyAccess; + CalculatePropertyAccessibility(member, out propertyAccess, out getterAccess, out setterAccess); + return setterAccess; + } + + /// + /// Gets the accessibility that should be applied to a method being generated from the provided EdmFunction. + /// + /// defaults to public if no annotation is found. + /// + public static string ForMethod(EdmFunction function) + { + if (function == null) + { + return null; + } + + return GetAccessibility(function, METHOD_ACCESS); + } + + private static void CalculatePropertyAccessibility(MetadataItem item, + out string propertyAccessibility, + out string getterAccessibility, + out string setterAccessibility) + { + getterAccessibility = GetAccessibility(item, GETTER_ACCESS); + int getterRank = AccessibilityRankIdLookup[getterAccessibility]; + + setterAccessibility = GetAccessibility(item, SETTER_ACCESS); + int setterRank = AccessibilityRankIdLookup[setterAccessibility]; + + int propertyRank = Math.Max(getterRank, setterRank); + if (setterRank == propertyRank) + { + setterAccessibility = String.Empty; + } + + if (getterRank == propertyRank) + { + getterAccessibility = String.Empty; + } + + propertyAccessibility = AccessibilityRankIdLookup.Where(v => v.Value == propertyRank).Select(v => v.Key).Single(); + } + + private static string GetAccessibility(MetadataItem item, string name) + { + string accessibility; + if (MetadataTools.TryGetStringMetadataPropertySetting(item, name, out accessibility)) + { + return TranslateUserAccessibilityToCSharpAccessibility(accessibility); + } + + return "public"; + } + + private static string TranslateUserAccessibilityToCSharpAccessibility(string userAccessibility) + { + if (userAccessibility == ACCESS_PROTECTED) + { + return "protected"; + } + else if (userAccessibility == ACCESS_INTERNAL) + { + return "internal"; + } + else if (userAccessibility == ACCESS_PRIVATE) + { + return "private"; + } + else + { + // default to public + return "public"; + } + } +} + +/// +/// Responsible for creating source code regions in code when the loop inside +/// actually produces something. +/// +public class CodeRegion +{ + private const int STANDARD_INDENT_LENGTH = 4; + + private readonly DynamicTextTransformation _textTransformation; + private int _beforeRegionLength; + private int _emptyRegionLength; + private int _regionIndentLevel = -1; + + /// + /// Initializes an CodeRegion instance with the + /// TextTransformation (T4 generated class) that is currently running + /// + public CodeRegion(object textTransformation) + { + if (textTransformation == null) + { + throw new ArgumentNullException("textTransformation"); + } + + _textTransformation = DynamicTextTransformation.Create(textTransformation); + } + + /// + /// Initializes an CodeRegion instance with the + /// TextTransformation (T4 generated class) that is currently running, + /// and the indent level to start the first region at. + /// + public CodeRegion(object textTransformation, int firstIndentLevel) + : this(textTransformation) + { + if (firstIndentLevel < 0) + { + throw new ArgumentException("firstIndentLevel"); + } + + _regionIndentLevel = firstIndentLevel - 1; + } + + /// + /// Starts the begining of a region + /// + public void Begin(string regionName) + { + if (regionName == null) + { + throw new ArgumentNullException("regionName"); + } + + Begin(regionName, 1); + } + + /// + /// Start the begining of a region, indented + /// the numbers of levels specified + /// + public void Begin(string regionName, int levelsToIncreaseIndent) + { + if (regionName == null) + { + throw new ArgumentNullException("regionName"); + } + + _beforeRegionLength = _textTransformation.GenerationEnvironment.Length; + _regionIndentLevel += levelsToIncreaseIndent; + _textTransformation.Write(GetIndent(_regionIndentLevel)); + _textTransformation.WriteLine("#region " + regionName); + _emptyRegionLength = _textTransformation.GenerationEnvironment.Length; + } + + /// + /// Ends a region, or totaly removes it if nothing + /// was generted since the begining of the region. + /// + public void End() + { + End(1); + } + + /// + /// Ends a region, or totaly removes it if nothing + /// was generted since the begining of the region, also outdents + /// the number of levels specified. + /// + public void End(int levelsToDecrease) + { + int indentLevel = _regionIndentLevel; + _regionIndentLevel -= levelsToDecrease; + + if (_emptyRegionLength == _textTransformation.GenerationEnvironment.Length) + _textTransformation.GenerationEnvironment.Length = _beforeRegionLength; + else + { + _textTransformation.WriteLine(String.Empty); + _textTransformation.Write(GetIndent(indentLevel)); + _textTransformation.WriteLine("#endregion"); + _textTransformation.WriteLine(String.Empty); + } + } + + /// + /// Gets the current indent level that the next end region statement will be written + /// at + /// + public int CurrentIndentLevel { get { return _regionIndentLevel; } } + + /// + /// Get a string of spaces equivelent to the number of indents + /// desired. + /// + public static string GetIndent(int indentLevel) + { + if (indentLevel < 0) + { + throw new ArgumentException("indentLevel"); + } + + return String.Empty.PadLeft(indentLevel * STANDARD_INDENT_LENGTH); + } +} + + +/// +/// Responsible for collecting together the actual method parameters +/// and the parameters that need to be sent to the Execute method. +/// +public class FunctionImportParameter +{ + public FunctionParameter Source { get; set; } + public string RawFunctionParameterName { get; set; } + public string FunctionParameterName { get; set; } + public string FunctionParameterType { get; set; } + public string LocalVariableName { get; set; } + public string RawClrTypeName { get; set; } + public string ExecuteParameterName { get; set; } + public string EsqlParameterName { get; set; } + public bool NeedsLocalVariable { get; set; } + public bool IsNullableOfT { get; set; } + + + /// + /// Creates a set of FunctionImportParameter objects from the parameters passed in. + /// + public static IEnumerable Create(IEnumerable parameters, CodeGenerationTools code, MetadataTools ef) + { + if (parameters == null) + { + throw new ArgumentNullException("parameters"); + } + + if (code == null) + { + throw new ArgumentNullException("code"); + } + + if (ef == null) + { + throw new ArgumentNullException("ef"); + } + + UniqueIdentifierService unique = new UniqueIdentifierService(); + List importParameters = new List(); + foreach (FunctionParameter parameter in parameters) + { + FunctionImportParameter importParameter = new FunctionImportParameter(); + importParameter.Source = parameter; + importParameter.RawFunctionParameterName = unique.AdjustIdentifier(code.CamelCase(parameter.Name)); + importParameter.FunctionParameterName = code.Escape(importParameter.RawFunctionParameterName); + if (parameter.Mode == ParameterMode.In) + { + TypeUsage typeUsage = parameter.TypeUsage; + importParameter.NeedsLocalVariable = true; + importParameter.FunctionParameterType = code.GetTypeName(typeUsage); + importParameter.EsqlParameterName = parameter.Name; + Type clrType = ef.UnderlyingClrType(parameter.TypeUsage.EdmType); + importParameter.RawClrTypeName = typeUsage.EdmType is EnumType ? code.GetTypeName(typeUsage.EdmType) : code.Escape(clrType); + importParameter.IsNullableOfT = clrType.IsValueType; + } + else + { + importParameter.NeedsLocalVariable = false; + importParameter.FunctionParameterType = "ObjectParameter"; + importParameter.ExecuteParameterName = importParameter.FunctionParameterName; + } + importParameters.Add(importParameter); + } + + // we save the local parameter uniquification for a second pass to make the visible parameters + // as pretty and sensible as possible + for (int i = 0; i < importParameters.Count; i++) + { + FunctionImportParameter importParameter = importParameters[i]; + if (importParameter.NeedsLocalVariable) + { + importParameter.LocalVariableName = unique.AdjustIdentifier(importParameter.RawFunctionParameterName + "Parameter"); + importParameter.ExecuteParameterName = importParameter.LocalVariableName; + } + } + + return importParameters; + } + + // + // Class to create unique variables within the same scope + // + private sealed class UniqueIdentifierService + { + private readonly HashSet _knownIdentifiers; + + public UniqueIdentifierService() + { + _knownIdentifiers = new HashSet(StringComparer.Ordinal); + } + + /// + /// Given an identifier, makes it unique within the scope by adding + /// a suffix (1, 2, 3, ...), and returns the adjusted identifier. + /// + public string AdjustIdentifier(string identifier) + { + // find a unique name by adding suffix as necessary + int numberOfConflicts = 0; + string adjustedIdentifier = identifier; + + while (!_knownIdentifiers.Add(adjustedIdentifier)) + { + ++numberOfConflicts; + adjustedIdentifier = identifier + numberOfConflicts.ToString(CultureInfo.InvariantCulture); + } + + return adjustedIdentifier; + } + } +} + +/// +/// Responsible for marking the various sections of the generation, +/// so they can be split up into separate files +/// +public class EntityFrameworkTemplateFileManager +{ + /// + /// Creates the VsEntityFrameworkTemplateFileManager if VS is detected, otherwise + /// creates the file system version. + /// + public static EntityFrameworkTemplateFileManager Create(object textTransformation) + { + DynamicTextTransformation transformation = DynamicTextTransformation.Create(textTransformation); + IDynamicHost host = transformation.Host; + +#if !PREPROCESSED_TEMPLATE + var hostServiceProvider = host.AsIServiceProvider(); + + if (hostServiceProvider != null) + { + EnvDTE.DTE dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE)); + + if (dte != null) + { + return new VsEntityFrameworkTemplateFileManager(transformation); + } + } +#endif + return new EntityFrameworkTemplateFileManager(transformation); + } + + private sealed class Block + { + public String Name; + public int Start, Length; + } + + private readonly List files = new List(); + private readonly Block footer = new Block(); + private readonly Block header = new Block(); + private readonly DynamicTextTransformation _textTransformation; + + // reference to the GenerationEnvironment StringBuilder on the + // TextTransformation object + private readonly StringBuilder _generationEnvironment; + + private Block currentBlock; + + /// + /// Initializes an EntityFrameworkTemplateFileManager Instance with the + /// TextTransformation (T4 generated class) that is currently running + /// + private EntityFrameworkTemplateFileManager(object textTransformation) + { + if (textTransformation == null) + { + throw new ArgumentNullException("textTransformation"); + } + + _textTransformation = DynamicTextTransformation.Create(textTransformation); + _generationEnvironment = _textTransformation.GenerationEnvironment; + } + + /// + /// Marks the end of the last file if there was one, and starts a new + /// and marks this point in generation as a new file. + /// + public void StartNewFile(string name) + { + if (name == null) + { + throw new ArgumentNullException("name"); + } + + CurrentBlock = new Block { Name = name }; + } + + public void StartFooter() + { + CurrentBlock = footer; + } + + public void StartHeader() + { + CurrentBlock = header; + } + + public void EndBlock() + { + if (CurrentBlock == null) + { + return; + } + + CurrentBlock.Length = _generationEnvironment.Length - CurrentBlock.Start; + + if (CurrentBlock != header && CurrentBlock != footer) + { + files.Add(CurrentBlock); + } + + currentBlock = null; + } + + /// + /// Produce the template output files. + /// + public virtual IEnumerable Process(bool split = true) + { + var generatedFileNames = new List(); + + if (split) + { + EndBlock(); + + var headerText = _generationEnvironment.ToString(header.Start, header.Length); + var footerText = _generationEnvironment.ToString(footer.Start, footer.Length); + var outputPath = Path.GetDirectoryName(_textTransformation.Host.TemplateFile); + + files.Reverse(); + + foreach (var block in files) + { + var fileName = Path.Combine(outputPath, block.Name); + var content = headerText + _generationEnvironment.ToString(block.Start, block.Length) + footerText; + + generatedFileNames.Add(fileName); + CreateFile(fileName, content); + _generationEnvironment.Remove(block.Start, block.Length); + } + } + + return generatedFileNames; + } + + protected virtual void CreateFile(string fileName, string content) + { + if (IsFileContentDifferent(fileName, content)) + { + File.WriteAllText(fileName, content); + } + } + + protected bool IsFileContentDifferent(String fileName, string newContent) + { + return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent); + } + + private Block CurrentBlock + { + get { return currentBlock; } + set + { + if (CurrentBlock != null) + { + EndBlock(); + } + + if (value != null) + { + value.Start = _generationEnvironment.Length; + } + + currentBlock = value; + } + } + +#if !PREPROCESSED_TEMPLATE + private sealed class VsEntityFrameworkTemplateFileManager : EntityFrameworkTemplateFileManager + { + private EnvDTE.ProjectItem templateProjectItem; + private EnvDTE.DTE dte; + private Action checkOutAction; + private Action> projectSyncAction; + + /// + /// Creates an instance of the VsEntityFrameworkTemplateFileManager class with the IDynamicHost instance + /// + public VsEntityFrameworkTemplateFileManager(object textTemplating) + : base(textTemplating) + { + var hostServiceProvider = _textTransformation.Host.AsIServiceProvider(); + if (hostServiceProvider == null) + { + throw new ArgumentNullException("Could not obtain hostServiceProvider"); + } + + dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE)); + if (dte == null) + { + throw new ArgumentNullException("Could not obtain DTE from host"); + } + + templateProjectItem = dte.Solution.FindProjectItem(_textTransformation.Host.TemplateFile); + + checkOutAction = fileName => dte.SourceControl.CheckOutItem(fileName); + projectSyncAction = keepFileNames => ProjectSync(templateProjectItem, keepFileNames); + } + + public override IEnumerable Process(bool split) + { + if (templateProjectItem.ProjectItems == null) + { + return new List(); + } + + var generatedFileNames = base.Process(split); + + projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null)); + + return generatedFileNames; + } + + protected override void CreateFile(string fileName, string content) + { + if (IsFileContentDifferent(fileName, content)) + { + CheckoutFileIfRequired(fileName); + File.WriteAllText(fileName, content); + } + } + + private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable keepFileNames) + { + var keepFileNameSet = new HashSet(keepFileNames); + var projectFiles = new Dictionary(); + var originalOutput = Path.GetFileNameWithoutExtension(templateProjectItem.FileNames[0]); + + foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) + { + projectFiles.Add(projectItem.FileNames[0], projectItem); + } + + // Remove unused items from the project + foreach (var pair in projectFiles) + { + if (!keepFileNames.Contains(pair.Key) + && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalOutput + ".")) + { + pair.Value.Delete(); + } + } + + // Add missing files to the project + foreach (string fileName in keepFileNameSet) + { + if (!projectFiles.ContainsKey(fileName)) + { + templateProjectItem.ProjectItems.AddFromFile(fileName); + } + } + } + + private void CheckoutFileIfRequired(string fileName) + { + if (dte.SourceControl == null + || !dte.SourceControl.IsItemUnderSCC(fileName) + || dte.SourceControl.IsItemCheckedOut(fileName)) + { + return; + } + + // run on worker thread to prevent T4 calling back into VS + checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null)); + } + } +#endif +} + +/// +/// Responsible creating an instance that can be passed +/// to helper classes that need to access the TextTransformation +/// members. It accesses member by name and signature rather than +/// by type. This is necessary when the +/// template is being used in Preprocessed mode +/// and there is no common known type that can be +/// passed instead +/// +public class DynamicTextTransformation +{ + private object _instance; + IDynamicHost _dynamicHost; + + private readonly MethodInfo _write; + private readonly MethodInfo _writeLine; + private readonly PropertyInfo _generationEnvironment; + private readonly PropertyInfo _errors; + private readonly PropertyInfo _host; + + /// + /// Creates an instance of the DynamicTextTransformation class around the passed in + /// TextTransformation shapped instance passed in, or if the passed in instance + /// already is a DynamicTextTransformation, it casts it and sends it back. + /// + public static DynamicTextTransformation Create(object instance) + { + if (instance == null) + { + throw new ArgumentNullException("instance"); + } + + DynamicTextTransformation textTransformation = instance as DynamicTextTransformation; + if (textTransformation != null) + { + return textTransformation; + } + + return new DynamicTextTransformation(instance); + } + + private DynamicTextTransformation(object instance) + { + _instance = instance; + Type type = _instance.GetType(); + _write = type.GetMethod("Write", new Type[] { typeof(string) }); + _writeLine = type.GetMethod("WriteLine", new Type[] { typeof(string) }); + _generationEnvironment = type.GetProperty("GenerationEnvironment", BindingFlags.Instance | BindingFlags.NonPublic); + _host = type.GetProperty("Host"); + _errors = type.GetProperty("Errors"); + } + + /// + /// Gets the value of the wrapped TextTranformation instance's GenerationEnvironment property + /// + public StringBuilder GenerationEnvironment { get { return (StringBuilder)_generationEnvironment.GetValue(_instance, null); } } + + /// + /// Gets the value of the wrapped TextTranformation instance's Errors property + /// + public System.CodeDom.Compiler.CompilerErrorCollection Errors { get { return (System.CodeDom.Compiler.CompilerErrorCollection)_errors.GetValue(_instance, null); } } + + /// + /// Calls the wrapped TextTranformation instance's Write method. + /// + public void Write(string text) + { + _write.Invoke(_instance, new object[] { text }); + } + + /// + /// Calls the wrapped TextTranformation instance's WriteLine method. + /// + public void WriteLine(string text) + { + _writeLine.Invoke(_instance, new object[] { text }); + } + + /// + /// Gets the value of the wrapped TextTranformation instance's Host property + /// if available (shows up when hostspecific is set to true in the template directive) and returns + /// the appropriate implementation of IDynamicHost + /// + public IDynamicHost Host + { + get + { + if (_dynamicHost == null) + { + if(_host == null) + { + _dynamicHost = new NullHost(); + } + else + { + _dynamicHost = new DynamicHost(_host.GetValue(_instance, null)); + } + } + return _dynamicHost; + } + } +} + + +/// +/// Reponsible for abstracting the use of Host between times +/// when it is available and not +/// +public interface IDynamicHost +{ + /// + /// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue + /// + string ResolveParameterValue(string id, string name, string otherName); + + /// + /// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath + /// + string ResolvePath(string path); + + /// + /// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile + /// + string TemplateFile { get; } + + /// + /// Returns the Host instance cast as an IServiceProvider + /// + IServiceProvider AsIServiceProvider(); +} + +/// +/// Reponsible for implementing the IDynamicHost as a dynamic +/// shape wrapper over the Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost interface +/// rather than type dependent wrapper. We don't use the +/// interface type so that the code can be run in preprocessed mode +/// on a .net framework only installed machine. +/// +public class DynamicHost : IDynamicHost +{ + private readonly object _instance; + private readonly MethodInfo _resolveParameterValue; + private readonly MethodInfo _resolvePath; + private readonly PropertyInfo _templateFile; + + /// + /// Creates an instance of the DynamicHost class around the passed in + /// Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost shapped instance passed in. + /// + public DynamicHost(object instance) + { + _instance = instance; + Type type = _instance.GetType(); + _resolveParameterValue = type.GetMethod("ResolveParameterValue", new Type[] { typeof(string), typeof(string), typeof(string) }); + _resolvePath = type.GetMethod("ResolvePath", new Type[] { typeof(string) }); + _templateFile = type.GetProperty("TemplateFile"); + + } + + /// + /// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue + /// + public string ResolveParameterValue(string id, string name, string otherName) + { + return (string)_resolveParameterValue.Invoke(_instance, new object[] { id, name, otherName }); + } + + /// + /// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath + /// + public string ResolvePath(string path) + { + return (string)_resolvePath.Invoke(_instance, new object[] { path }); + } + + /// + /// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile + /// + public string TemplateFile + { + get + { + return (string)_templateFile.GetValue(_instance, null); + } + } + + /// + /// Returns the Host instance cast as an IServiceProvider + /// + public IServiceProvider AsIServiceProvider() + { + return _instance as IServiceProvider; + } +} + +/// +/// Reponsible for implementing the IDynamicHost when the +/// Host property is not available on the TextTemplating type. The Host +/// property only exists when the hostspecific attribute of the template +/// directive is set to true. +/// +public class NullHost : IDynamicHost +{ + /// + /// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue + /// that simply retuns null. + /// + public string ResolveParameterValue(string id, string name, string otherName) + { + return null; + } + + /// + /// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath + /// that simply retuns the path passed in. + /// + public string ResolvePath(string path) + { + return path; + } + + /// + /// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile + /// that returns null. + /// + public string TemplateFile + { + get + { + return null; + } + } + + /// + /// Returns null. + /// + public IServiceProvider AsIServiceProvider() + { + return null; + } +} + +/// +/// Responsible for encapsulating the constants defined in Metadata +/// +public static class MetadataConstants +{ + public const string CSDL_EXTENSION = ".csdl"; + + public const string CSDL_EDMX_SECTION_NAME = "ConceptualModels"; + public const string CSDL_ROOT_ELEMENT_NAME = "Schema"; + public const string EDM_ANNOTATION_09_02 = "http://schemas.microsoft.com/ado/2009/02/edm/annotation"; + + public const string SSDL_EXTENSION = ".ssdl"; + + public const string SSDL_EDMX_SECTION_NAME = "StorageModels"; + public const string SSDL_ROOT_ELEMENT_NAME = "Schema"; + + public const string MSL_EXTENSION = ".msl"; + + public const string MSL_EDMX_SECTION_NAME = "Mappings"; + public const string MSL_ROOT_ELEMENT_NAME = "Mapping"; + + public const string TT_TEMPLATE_NAME = "TemplateName"; + public const string TT_TEMPLATE_VERSION = "TemplateVersion"; + public const string TT_MINIMUM_ENTITY_FRAMEWORK_VERSION = "MinimumEntityFrameworkVersion"; + + public const string DEFAULT_TEMPLATE_VERSION = "4.0"; + + public static readonly SchemaConstants V1_SCHEMA_CONSTANTS = new SchemaConstants( + "http://schemas.microsoft.com/ado/2007/06/edmx", + "http://schemas.microsoft.com/ado/2006/04/edm", + "http://schemas.microsoft.com/ado/2006/04/edm/ssdl", + "urn:schemas-microsoft-com:windows:storage:mapping:CS", + new Version("3.5")); + + public static readonly SchemaConstants V2_SCHEMA_CONSTANTS = new SchemaConstants( + "http://schemas.microsoft.com/ado/2008/10/edmx", + "http://schemas.microsoft.com/ado/2008/09/edm", + "http://schemas.microsoft.com/ado/2009/02/edm/ssdl", + "http://schemas.microsoft.com/ado/2008/09/mapping/cs", + new Version("4.0")); + + public static readonly SchemaConstants V3_SCHEMA_CONSTANTS = new SchemaConstants( + "http://schemas.microsoft.com/ado/2009/11/edmx", + "http://schemas.microsoft.com/ado/2009/11/edm", + "http://schemas.microsoft.com/ado/2009/11/edm/ssdl", + "http://schemas.microsoft.com/ado/2009/11/mapping/cs", + new Version("5.0")); +} + +public struct SchemaConstants +{ + public SchemaConstants(string edmxNamespace, string csdlNamespace, string ssdlNamespace, string mslNamespace, Version minimumTemplateVersion) : this() + { + EdmxNamespace = edmxNamespace; + CsdlNamespace = csdlNamespace; + SsdlNamespace = ssdlNamespace; + MslNamespace = mslNamespace; + MinimumTemplateVersion = minimumTemplateVersion; + } + + public string EdmxNamespace { get; private set; } + public string CsdlNamespace { get; private set; } + public string SsdlNamespace { get; private set; } + public string MslNamespace { get; private set; } + public Version MinimumTemplateVersion { get; private set; } +} #> \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/AuditInfoMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/AuditInfoMm.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/AuditInfoMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/AuditInfoMm.cs index 47b6dc90..c423baa9 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/AuditInfoMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/AuditInfoMm.cs @@ -1,20 +1,20 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace Another.Place -{ - using System; - using FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel; - - public class AuditInfoMm - { - public AuditInfoMm() - { - Concurrency = new ConcurrencyInfoMm(); - } - - public DateTime ModifiedDate { get; set; } - public string ModifiedBy { get; set; } - - public ConcurrencyInfoMm Concurrency { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace Another.Place +{ + using System; + using FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel; + + public class AuditInfoMm + { + public AuditInfoMm() + { + Concurrency = new ConcurrencyInfoMm(); + } + + public DateTime ModifiedDate { get; set; } + public string ModifiedBy { get; set; } + + public ConcurrencyInfoMm Concurrency { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/CustomerMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/CustomerMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/CustomerMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/CustomerMm.cs index f5fe320f..40d2dea7 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/CustomerMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/CustomerMm.cs @@ -1,30 +1,30 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace Another.Place -{ - using System.Collections.Generic; - using FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel; - - public class CustomerMm - { - public CustomerMm() - { - Orders = new HashSet(); - Logins = new HashSet(); - ContactInfo = new ContactDetailsMm(); - Auditing = new AuditInfoMm(); - } - - public int CustomerId { get; set; } - public string Name { get; set; } - - public ContactDetailsMm ContactInfo { get; set; } - public AuditInfoMm Auditing { get; set; } - - public virtual ICollection Orders { get; set; } - public virtual ICollection Logins { get; set; } - public virtual CustomerMm Husband { get; set; } - public virtual CustomerMm Wife { get; set; } - public virtual CustomerInfoMm Info { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace Another.Place +{ + using System.Collections.Generic; + using FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel; + + public class CustomerMm + { + public CustomerMm() + { + Orders = new HashSet(); + Logins = new HashSet(); + ContactInfo = new ContactDetailsMm(); + Auditing = new AuditInfoMm(); + } + + public int CustomerId { get; set; } + public string Name { get; set; } + + public ContactDetailsMm ContactInfo { get; set; } + public AuditInfoMm Auditing { get; set; } + + public virtual ICollection Orders { get; set; } + public virtual ICollection Logins { get; set; } + public virtual CustomerMm Husband { get; set; } + public virtual CustomerMm Wife { get; set; } + public virtual CustomerInfoMm Info { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/LicenseStateMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/LicenseStateMm.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/LicenseStateMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/LicenseStateMm.cs index 687b0051..13e2e923 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/LicenseStateMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/LicenseStateMm.cs @@ -1,11 +1,11 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace Another.Place -{ - public enum LicenseStateMm - { - Active = 1, - Suspended = 2, - Revoked = 3 - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace Another.Place +{ + public enum LicenseStateMm + { + Active = 1, + Suspended = 2, + Revoked = 3 + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/LoginMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/LoginMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/LoginMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/LoginMm.cs index 8aaaedbb..43a0b4bf 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/LoginMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/LoginMm.cs @@ -1,26 +1,26 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace Another.Place -{ - using System.Collections.Generic; - using FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel; - - public class LoginMm - { - public LoginMm() - { - SentMessages = new HashSet(); - ReceivedMessages = new HashSet(); - Orders = new HashSet(); - } - - public string Username { get; set; } - public int CustomerId { get; set; } - - public virtual CustomerMm Customer { get; set; } - public virtual LastLoginMm LastLogin { get; set; } - public virtual ICollection SentMessages { get; set; } - public virtual ICollection ReceivedMessages { get; set; } - public virtual ICollection Orders { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace Another.Place +{ + using System.Collections.Generic; + using FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel; + + public class LoginMm + { + public LoginMm() + { + SentMessages = new HashSet(); + ReceivedMessages = new HashSet(); + Orders = new HashSet(); + } + + public string Username { get; set; } + public int CustomerId { get; set; } + + public virtual CustomerMm Customer { get; set; } + public virtual LastLoginMm LastLogin { get; set; } + public virtual ICollection SentMessages { get; set; } + public virtual ICollection ReceivedMessages { get; set; } + public virtual ICollection Orders { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/PhoneMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/PhoneMm.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/PhoneMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/PhoneMm.cs index afebae31..641121f2 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/PhoneMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/PhoneMm.cs @@ -1,16 +1,16 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace Another.Place -{ - public class PhoneMm - { - public PhoneMm() - { - Extension = "None"; - } - - public string PhoneNumber { get; set; } - public string Extension { get; set; } - public PhoneTypeMm PhoneType { get; set; } - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace Another.Place +{ + public class PhoneMm + { + public PhoneMm() + { + Extension = "None"; + } + + public string PhoneNumber { get; set; } + public string Extension { get; set; } + public PhoneTypeMm PhoneType { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/PhoneTypeMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/PhoneTypeMm.cs similarity index 96% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/PhoneTypeMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/PhoneTypeMm.cs index a78ee2e9..c5a75024 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/PhoneTypeMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ExternalTypes/PhoneTypeMm.cs @@ -1,11 +1,11 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace Another.Place -{ - public enum PhoneTypeMm - { - Cell = 1, - Land = 2, - Satellite = 3, - } -} +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace Another.Place +{ + public enum PhoneTypeMm + { + Cell = 1, + Land = 2, + Satellite = 3, + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/IncorrectScanMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/IncorrectScanMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/IncorrectScanMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/IncorrectScanMm.cs index 954e7826..330376bf 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/IncorrectScanMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/IncorrectScanMm.cs @@ -1,26 +1,26 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class IncorrectScanMm - { - public int IncorrectScanId { get; set; } - public byte[] ExpectedCode { get; set; } - public byte[] ActualCode { get; set; } - public System.DateTime ScanDate { get; set; } - public string Details { get; set; } - - public virtual BarcodeMm ExpectedBarcode { get; set; } - public virtual BarcodeMm ActualBarcode { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class IncorrectScanMm + { + public int IncorrectScanId { get; set; } + public byte[] ExpectedCode { get; set; } + public byte[] ActualCode { get; set; } + public System.DateTime ScanDate { get; set; } + public string Details { get; set; } + + public virtual BarcodeMm ExpectedBarcode { get; set; } + public virtual BarcodeMm ActualBarcode { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/LastLoginMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/LastLoginMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/LastLoginMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/LastLoginMm.cs index 7291aaf8..39c4f167 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/LastLoginMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/LastLoginMm.cs @@ -1,23 +1,23 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class LastLoginMm - { - public string Username { get; set; } - public System.DateTime LoggedIn { get; set; } - public Nullable LoggedOut { get; set; } - - public virtual Another.Place.LoginMm Login { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class LastLoginMm + { + public string Username { get; set; } + public System.DateTime LoggedIn { get; set; } + public Nullable LoggedOut { get; set; } + + public virtual Another.Place.LoginMm Login { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/LicenseMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/LicenseMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/LicenseMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/LicenseMm.cs index db1f7fb3..ca326fff 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/LicenseMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/LicenseMm.cs @@ -1,31 +1,31 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class LicenseMm - { - public LicenseMm() - { - this.LicenseClass = "C"; - } - - public string Name { get; set; } - public string LicenseNumber { get; set; } - public string LicenseClass { get; set; } - public string Restrictions { get; set; } - public System.DateTime ExpirationDate { get; set; } - public Nullable State { get; set; } - - public virtual DriverMm Driver { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class LicenseMm + { + public LicenseMm() + { + this.LicenseClass = "C"; + } + + public string Name { get; set; } + public string LicenseNumber { get; set; } + public string LicenseClass { get; set; } + public string Restrictions { get; set; } + public System.DateTime ExpirationDate { get; set; } + public Nullable State { get; set; } + + public virtual DriverMm Driver { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/MessageMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/MessageMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/MessageMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/MessageMm.cs index 906bf7ad..63009942 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/MessageMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/MessageMm.cs @@ -1,28 +1,28 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class MessageMm - { - public int MessageId { get; set; } - public string FromUsername { get; set; } - public string ToUsername { get; set; } - public System.DateTime Sent { get; set; } - public string Subject { get; set; } - public string Body { get; set; } - public bool IsRead { get; set; } - - public virtual Another.Place.LoginMm Sender { get; set; } - public virtual Another.Place.LoginMm Recipient { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class MessageMm + { + public int MessageId { get; set; } + public string FromUsername { get; set; } + public string ToUsername { get; set; } + public System.DateTime Sent { get; set; } + public string Subject { get; set; } + public string Body { get; set; } + public bool IsRead { get; set; } + + public virtual Another.Place.LoginMm Sender { get; set; } + public virtual Another.Place.LoginMm Recipient { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/OrderLineMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/OrderLineMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/OrderLineMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/OrderLineMm.cs index 44d6428b..de82a8ac 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/OrderLineMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/OrderLineMm.cs @@ -1,30 +1,30 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class OrderLineMm - { - public OrderLineMm() - { - this.Quantity = 1; - } - - public int OrderId { get; set; } - public int ProductId { get; set; } - public int Quantity { get; set; } - public string ConcurrencyToken { get; set; } - - public virtual OrderMm Order { get; set; } - public virtual ProductMm Product { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class OrderLineMm + { + public OrderLineMm() + { + this.Quantity = 1; + } + + public int OrderId { get; set; } + public int ProductId { get; set; } + public int Quantity { get; set; } + public string ConcurrencyToken { get; set; } + + public virtual OrderMm Order { get; set; } + public virtual ProductMm Product { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/OrderMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/OrderMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/OrderMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/OrderMm.cs index 10c0b709..bb8ea7cd 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/OrderMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/OrderMm.cs @@ -1,34 +1,34 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class OrderMm - { - public OrderMm() - { - this.OrderLines = new HashSet(); - this.Notes = new HashSet(); - this.Concurrency = new ConcurrencyInfoMm(); - } - - public int OrderId { get; set; } - public Nullable CustomerId { get; set; } - - public ConcurrencyInfoMm Concurrency { get; set; } - - public virtual Another.Place.CustomerMm Customer { get; set; } - public virtual ICollection OrderLines { get; set; } - public virtual ICollection Notes { get; set; } - public virtual Another.Place.LoginMm Login { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class OrderMm + { + public OrderMm() + { + this.OrderLines = new HashSet(); + this.Notes = new HashSet(); + this.Concurrency = new ConcurrencyInfoMm(); + } + + public int OrderId { get; set; } + public Nullable CustomerId { get; set; } + + public ConcurrencyInfoMm Concurrency { get; set; } + + public virtual Another.Place.CustomerMm Customer { get; set; } + public virtual ICollection OrderLines { get; set; } + public virtual ICollection Notes { get; set; } + public virtual Another.Place.LoginMm Login { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/OrderNoteMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/OrderNoteMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/OrderNoteMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/OrderNoteMm.cs index c2373ef6..66b71010 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/OrderNoteMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/OrderNoteMm.cs @@ -1,22 +1,22 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class OrderNoteMm - { - public int NoteId { get; set; } - public string Note { get; set; } - - public virtual OrderMm Order { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class OrderNoteMm + { + public int NoteId { get; set; } + public string Note { get; set; } + + public virtual OrderMm Order { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/OrderQualityCheckMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/OrderQualityCheckMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/OrderQualityCheckMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/OrderQualityCheckMm.cs index d39422fd..40ffd9c5 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/OrderQualityCheckMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/OrderQualityCheckMm.cs @@ -1,23 +1,23 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class OrderQualityCheckMm - { - public int OrderId { get; set; } - public string CheckedBy { get; set; } - public System.DateTime CheckedDateTime { get; set; } - - public virtual OrderMm Order { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class OrderQualityCheckMm + { + public int OrderId { get; set; } + public string CheckedBy { get; set; } + public System.DateTime CheckedDateTime { get; set; } + + public virtual OrderMm Order { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/PageViewMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/PageViewMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/PageViewMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/PageViewMm.cs index 352c31cb..f7bb299a 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/PageViewMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/PageViewMm.cs @@ -1,24 +1,24 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class PageViewMm - { - public int PageViewId { get; set; } - public string Username { get; set; } - public System.DateTime Viewed { get; set; } - public string PageUrl { get; set; } - - public virtual Another.Place.LoginMm Login { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class PageViewMm + { + public int PageViewId { get; set; } + public string Username { get; set; } + public System.DateTime Viewed { get; set; } + public string PageUrl { get; set; } + + public virtual Another.Place.LoginMm Login { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/PasswordResetMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/PasswordResetMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/PasswordResetMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/PasswordResetMm.cs index f78f21e4..c663c399 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/PasswordResetMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/PasswordResetMm.cs @@ -1,24 +1,24 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class PasswordResetMm - { - public int ResetNo { get; set; } - public string Username { get; set; } - public string TempPassword { get; set; } - public string EmailedTo { get; set; } - - public virtual Another.Place.LoginMm Login { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class PasswordResetMm + { + public int ResetNo { get; set; } + public string Username { get; set; } + public string TempPassword { get; set; } + public string EmailedTo { get; set; } + + public virtual Another.Place.LoginMm Login { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductDetailMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductDetailMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductDetailMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductDetailMm.cs index 13d7f2c8..48046dce 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductDetailMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductDetailMm.cs @@ -1,22 +1,22 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class ProductDetailMm - { - public int ProductId { get; set; } - public string Details { get; set; } - - public virtual ProductMm Product { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class ProductDetailMm + { + public int ProductId { get; set; } + public string Details { get; set; } + + public virtual ProductMm Product { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductMm.cs index 59f947f7..077ff8ad 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductMm.cs @@ -1,44 +1,44 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class ProductMm - { - public ProductMm() - { - this.Suppliers = new HashSet(); - this.Replaces = new HashSet(); - this.Reviews = new HashSet(); - this.Photos = new HashSet(); - this.Barcodes = new HashSet(); - this.Dimensions = new DimensionsMm(); - this.ComplexConcurrency = new ConcurrencyInfoMm(); - this.NestedComplexConcurrency = new Another.Place.AuditInfoMm(); - } - - public int ProductId { get; set; } - public string Description { get; set; } - public string BaseConcurrency { get; set; } - - public DimensionsMm Dimensions { get; set; } - public ConcurrencyInfoMm ComplexConcurrency { get; set; } - public Another.Place.AuditInfoMm NestedComplexConcurrency { get; set; } - - public virtual ICollection Suppliers { get; set; } - public virtual ICollection Replaces { get; set; } - public virtual ProductDetailMm Detail { get; set; } - public virtual ICollection Reviews { get; set; } - public virtual ICollection Photos { get; set; } - public virtual ICollection Barcodes { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class ProductMm + { + public ProductMm() + { + this.Suppliers = new HashSet(); + this.Replaces = new HashSet(); + this.Reviews = new HashSet(); + this.Photos = new HashSet(); + this.Barcodes = new HashSet(); + this.Dimensions = new DimensionsMm(); + this.ComplexConcurrency = new ConcurrencyInfoMm(); + this.NestedComplexConcurrency = new Another.Place.AuditInfoMm(); + } + + public int ProductId { get; set; } + public string Description { get; set; } + public string BaseConcurrency { get; set; } + + public DimensionsMm Dimensions { get; set; } + public ConcurrencyInfoMm ComplexConcurrency { get; set; } + public Another.Place.AuditInfoMm NestedComplexConcurrency { get; set; } + + public virtual ICollection Suppliers { get; set; } + public virtual ICollection Replaces { get; set; } + public virtual ProductDetailMm Detail { get; set; } + public virtual ICollection Reviews { get; set; } + public virtual ICollection Photos { get; set; } + public virtual ICollection Barcodes { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductPageViewMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductPageViewMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductPageViewMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductPageViewMm.cs index baa8dc4f..ab4d5a91 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductPageViewMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductPageViewMm.cs @@ -1,21 +1,21 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class ProductPageViewMm : PageViewMm - { - public int ProductId { get; set; } - - public virtual ProductMm Product { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class ProductPageViewMm : PageViewMm + { + public int ProductId { get; set; } + + public virtual ProductMm Product { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductPhotoMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductPhotoMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductPhotoMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductPhotoMm.cs index 05c1020e..971e4557 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductPhotoMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductPhotoMm.cs @@ -1,28 +1,28 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class ProductPhotoMm - { - public ProductPhotoMm() - { - this.Features = new HashSet(); - } - - public int ProductId { get; set; } - public int PhotoId { get; set; } - public byte[] Photo { get; set; } - - public virtual ICollection Features { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class ProductPhotoMm + { + public ProductPhotoMm() + { + this.Features = new HashSet(); + } + + public int ProductId { get; set; } + public int PhotoId { get; set; } + public byte[] Photo { get; set; } + + public virtual ICollection Features { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductReviewMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductReviewMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductReviewMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductReviewMm.cs index 8560886b..1ee42f4f 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductReviewMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductReviewMm.cs @@ -1,29 +1,29 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class ProductReviewMm - { - public ProductReviewMm() - { - this.Features = new HashSet(); - } - - public int ProductId { get; set; } - public int ReviewId { get; set; } - public string Review { get; set; } - - public virtual ProductMm Product { get; set; } - public virtual ICollection Features { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class ProductReviewMm + { + public ProductReviewMm() + { + this.Features = new HashSet(); + } + + public int ProductId { get; set; } + public int ReviewId { get; set; } + public string Review { get; set; } + + public virtual ProductMm Product { get; set; } + public virtual ICollection Features { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductWebFeatureMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductWebFeatureMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductWebFeatureMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductWebFeatureMm.cs index 26edbef2..87ec0961 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ProductWebFeatureMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ProductWebFeatureMm.cs @@ -1,26 +1,26 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class ProductWebFeatureMm - { - public int FeatureId { get; set; } - public Nullable ProductId { get; set; } - public Nullable PhotoId { get; set; } - public int ReviewId { get; set; } - public string Heading { get; set; } - - public virtual ProductReviewMm Review { get; set; } - public virtual ProductPhotoMm Photo { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class ProductWebFeatureMm + { + public int FeatureId { get; set; } + public Nullable ProductId { get; set; } + public Nullable PhotoId { get; set; } + public int ReviewId { get; set; } + public string Heading { get; set; } + + public virtual ProductReviewMm Review { get; set; } + public virtual ProductPhotoMm Photo { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/RSATokenMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/RSATokenMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/RSATokenMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/RSATokenMm.cs index 111a508d..36c61573 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/RSATokenMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/RSATokenMm.cs @@ -1,22 +1,22 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class RSATokenMm - { - public string Serial { get; set; } - public System.DateTime Issued { get; set; } - - public virtual Another.Place.LoginMm Login { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class RSATokenMm + { + public string Serial { get; set; } + public System.DateTime Issued { get; set; } + + public virtual Another.Place.LoginMm Login { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ResolutionMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ResolutionMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ResolutionMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ResolutionMm.cs index 0794e002..c2be47b4 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/ResolutionMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/ResolutionMm.cs @@ -1,22 +1,22 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class ResolutionMm - { - public int ResolutionId { get; set; } - public string Details { get; set; } - - public virtual ComplaintMm Complaint { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class ResolutionMm + { + public int ResolutionId { get; set; } + public string Details { get; set; } + + public virtual ComplaintMm Complaint { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/SmartCardMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/SmartCardMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/SmartCardMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/SmartCardMm.cs index 14de5eb0..01b624dd 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/SmartCardMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/SmartCardMm.cs @@ -1,24 +1,24 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class SmartCardMm - { - public string Username { get; set; } - public string CardSerial { get; set; } - public System.DateTime Issued { get; set; } - - public virtual Another.Place.LoginMm Login { get; set; } - public virtual LastLoginMm LastLogin { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class SmartCardMm + { + public string Username { get; set; } + public string CardSerial { get; set; } + public System.DateTime Issued { get; set; } + + public virtual Another.Place.LoginMm Login { get; set; } + public virtual LastLoginMm LastLogin { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/SupplierInfoMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/SupplierInfoMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/SupplierInfoMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/SupplierInfoMm.cs index c70cb0db..190f7bb9 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/SupplierInfoMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/SupplierInfoMm.cs @@ -1,22 +1,22 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class SupplierInfoMm - { - public int SupplierInfoId { get; set; } - public string Information { get; set; } - - public virtual SupplierMm Supplier { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class SupplierInfoMm + { + public int SupplierInfoId { get; set; } + public string Information { get; set; } + + public virtual SupplierMm Supplier { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/SupplierLogoMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/SupplierLogoMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/SupplierLogoMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/SupplierLogoMm.cs index fe3f26ed..b721869b 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/SupplierLogoMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/SupplierLogoMm.cs @@ -1,20 +1,20 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class SupplierLogoMm - { - public int SupplierId { get; set; } - public byte[] Logo { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class SupplierLogoMm + { + public int SupplierId { get; set; } + public byte[] Logo { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/SupplierMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/SupplierMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/SupplierMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/SupplierMm.cs index 71aeef0b..1d03b35c 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/SupplierMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/SupplierMm.cs @@ -1,30 +1,30 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class SupplierMm - { - public SupplierMm() - { - this.Products = new HashSet(); - this.BackOrderLines = new HashSet(); - } - - public int SupplierId { get; set; } - public string Name { get; set; } - - public virtual ICollection Products { get; set; } - public virtual ICollection BackOrderLines { get; set; } - public virtual SupplierLogoMm Logo { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class SupplierMm + { + public SupplierMm() + { + this.Products = new HashSet(); + this.BackOrderLines = new HashSet(); + } + + public int SupplierId { get; set; } + public string Name { get; set; } + + public virtual ICollection Products { get; set; } + public virtual ICollection BackOrderLines { get; set; } + public virtual SupplierLogoMm Logo { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/SuspiciousActivityMm.cs b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/SuspiciousActivityMm.cs similarity index 97% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/SuspiciousActivityMm.cs rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/SuspiciousActivityMm.cs index 99d41db0..af9c7102 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/CsMonsterModel/SuspiciousActivityMm.cs +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/CsMonsterModel/SuspiciousActivityMm.cs @@ -1,20 +1,20 @@ -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel -{ - using System; - using System.Collections.Generic; - - public partial class SuspiciousActivityMm - { - public int SuspiciousActivityId { get; set; } - public string Activity { get; set; } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel +{ + using System; + using System.Collections.Generic; + + public partial class SuspiciousActivityMm + { + public int SuspiciousActivityId { get; set; } + public string Activity { get; set; } + } +} diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/ProcessCsTemplate.bat b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/ProcessCsTemplate.bat similarity index 99% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/ProcessCsTemplate.bat rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/ProcessCsTemplate.bat index f423a63d..c38e5a3b 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/ProcessCsTemplate.bat +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/ProcessCsTemplate.bat @@ -1,5 +1,5 @@ -copy /Y %SDXROOT%\ndp\fx\src\DataEntityDesign\Design\T4Templates\CSharpDbContext.ContextV4.5.tt %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityFunctionalTests\ProductivityApi\TemplateModels\%1\%1.Context.tt -copy /Y %SDXROOT%\ndp\fx\src\DataEntityDesign\Design\T4Templates\CSharpDbContext.TypesV4.5.tt %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityFunctionalTests\ProductivityApi\TemplateModels\%1\%1.tt - -TemplateReplace %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityFunctionalTests\ProductivityApi\TemplateModels\%1\%1.Context.tt %2 -TemplateReplace %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityFunctionalTests\ProductivityApi\TemplateModels\%1\%1.tt %2 +copy /Y %SDXROOT%\ndp\fx\src\DataEntityDesign\Design\T4Templates\CSharpDbContext.ContextV4.5.tt %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityFunctionalTests\ProductivityApi\TemplateModels\%1\%1.Context.tt +copy /Y %SDXROOT%\ndp\fx\src\DataEntityDesign\Design\T4Templates\CSharpDbContext.TypesV4.5.tt %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityFunctionalTests\ProductivityApi\TemplateModels\%1\%1.tt + +TemplateReplace %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityFunctionalTests\ProductivityApi\TemplateModels\%1\%1.Context.tt %2 +TemplateReplace %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityFunctionalTests\ProductivityApi\TemplateModels\%1\%1.tt %2 diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/ProcessTemplates.bat b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/ProcessTemplates.bat similarity index 99% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/ProcessTemplates.bat rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/ProcessTemplates.bat index 8100000a..fe4bd86f 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/ProcessTemplates.bat +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/ProcessTemplates.bat @@ -1,4 +1,4 @@ -call ProcessCsTemplate CsMonsterModel ..\Schemas\MonsterModel.csdl -call ProcessCsTemplate CsAdvancedPatterns ..\Schemas\AdvancedPatterns.edmx -call ProcessVbTemplate VbMonsterModel ..\..\ProductivityFunctionalTests\ProductivityApi\TemplateModels\Schemas\MonsterModel.csdl -call ProcessVbTemplate VbAdvancedPatterns ..\..\ProductivityFunctionalTests\ProductivityApi\TemplateModels\Schemas\AdvancedPatterns.edmx +call ProcessCsTemplate CsMonsterModel ..\Schemas\MonsterModel.csdl +call ProcessCsTemplate CsAdvancedPatterns ..\Schemas\AdvancedPatterns.edmx +call ProcessVbTemplate VbMonsterModel ..\..\ProductivityFunctionalTests\ProductivityApi\TemplateModels\Schemas\MonsterModel.csdl +call ProcessVbTemplate VbAdvancedPatterns ..\..\ProductivityFunctionalTests\ProductivityApi\TemplateModels\Schemas\AdvancedPatterns.edmx diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/ProcessVbTemplate.bat b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/ProcessVbTemplate.bat similarity index 99% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/ProcessVbTemplate.bat rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/ProcessVbTemplate.bat index 9a3a3181..1e4842e7 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/ProcessVbTemplate.bat +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/ProcessVbTemplate.bat @@ -1,5 +1,5 @@ -copy /Y %SDXROOT%\ndp\fx\src\DataEntityDesign\Design\T4Templates\VBDbContext.ContextV4.5.tt %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityVBTests\%1\%1.Context.tt -copy /Y %SDXROOT%\ndp\fx\src\DataEntityDesign\Design\T4Templates\VBDbContext.TypesV4.5.tt %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityVBTests\%1\%1.tt - -TemplateReplace %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityVBTests\%1\%1.Context.tt %2 -TemplateReplace %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityVBTests\%1\%1.tt %2 +copy /Y %SDXROOT%\ndp\fx\src\DataEntityDesign\Design\T4Templates\VBDbContext.ContextV4.5.tt %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityVBTests\%1\%1.Context.tt +copy /Y %SDXROOT%\ndp\fx\src\DataEntityDesign\Design\T4Templates\VBDbContext.TypesV4.5.tt %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityVBTests\%1\%1.tt + +TemplateReplace %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityVBTests\%1\%1.Context.tt %2 +TemplateReplace %SDXROOT%\qa\Devdiv\dptest\DataEntity\CheckinTests\CodeFirst\ProductivityVBTests\%1\%1.tt %2 diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/Schemas/AdvancedPatterns.edmx b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/Schemas/AdvancedPatterns.edmx similarity index 98% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/Schemas/AdvancedPatterns.edmx rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/Schemas/AdvancedPatterns.edmx index 76632404..385e80ef 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/Schemas/AdvancedPatterns.edmx +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/Schemas/AdvancedPatterns.edmx @@ -1,578 +1,578 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/Schemas/MonsterModel.csdl b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/Schemas/MonsterModel.csdl similarity index 98% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/Schemas/MonsterModel.csdl rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/Schemas/MonsterModel.csdl index 58c6661d..17fead45 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/Schemas/MonsterModel.csdl +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/Schemas/MonsterModel.csdl @@ -1,925 +1,925 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Year(CurrentDateTime()) - Year(CutOffDate) - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Year(CurrentDateTime()) - Year(CutOffDate) + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/Schemas/MonsterModel.msl b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/Schemas/MonsterModel.msl similarity index 98% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/Schemas/MonsterModel.msl rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/Schemas/MonsterModel.msl index 611fae63..851cab16 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/Schemas/MonsterModel.msl +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/Schemas/MonsterModel.msl @@ -1,514 +1,514 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/Schemas/MonsterModel.ssdl b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/Schemas/MonsterModel.ssdl similarity index 98% rename from test/EntityFramework/FunctionalTests/TestModels/TemplateModels/Schemas/MonsterModel.ssdl rename to test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/Schemas/MonsterModel.ssdl index 59a941b8..58ca3c74 100644 --- a/test/EntityFramework/FunctionalTests/TestModels/TemplateModels/Schemas/MonsterModel.ssdl +++ b/test/EntityFramework/FunctionalTests.Transitional/TestModels/TemplateModels/Schemas/MonsterModel.ssdl @@ -1,958 +1,958 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SELECT TOP 2 * FROM Computera8d8de12c8a44e65b1e1b6221c08df53 - - - SET @int = 5 -SET @string = '230' - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SELECT TOP 2 * FROM Computera8d8de12c8a44e65b1e1b6221c08df53 + + + SET @int = 5 +SET @string = '230' + + + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests.Transitional/packages.config b/test/EntityFramework/FunctionalTests.Transitional/packages.config new file mode 100644 index 00000000..bcd9cac9 --- /dev/null +++ b/test/EntityFramework/FunctionalTests.Transitional/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/test/EntityFramework/FunctionalTests/App.config b/test/EntityFramework/FunctionalTests/App.config index 055c110b..1374abb7 100644 --- a/test/EntityFramework/FunctionalTests/App.config +++ b/test/EntityFramework/FunctionalTests/App.config @@ -25,22 +25,22 @@ - + - - + + - + - - + + diff --git a/test/EntityFramework/FunctionalTests/FunctionalTests.csproj b/test/EntityFramework/FunctionalTests/FunctionalTests.csproj index ccb878cb..b695e64e 100644 --- a/test/EntityFramework/FunctionalTests/FunctionalTests.csproj +++ b/test/EntityFramework/FunctionalTests/FunctionalTests.csproj @@ -106,15 +106,6 @@ Properties\FinalPublicKey.snk - - - - - - - - - Designer @@ -128,41 +119,6 @@ FunctionalTests.ProductivityApi.SpatialTvfsModel.226644SpatialModel.ssdl - - TextTemplatingFileGenerator - CsAdvancedPatterns.Context.cs - FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns - - - TextTemplatingFileGenerator - CsAdvancedPatterns.cs - FunctionalTests.ProductivityApi.TemplateModels.CsAdvancedPatterns - - - TextTemplatingFileGenerator - CsMonsterModel.Context.cs - FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel - - - TextTemplatingFileGenerator - CsMonsterModel.cs - FunctionalTests.ProductivityApi.TemplateModels.CsMonsterModel - - - - - - FunctionalTests.ProductivityApi.TemplateModels.Schemas.AdvancedPatterns.edmx - - - FunctionalTests.ProductivityApi.TemplateModels.Schemas.MonsterModel.csdl - - - FunctionalTests.ProductivityApi.TemplateModels.Schemas.MonsterModel.msl - - - FunctionalTests.ProductivityApi.TemplateModels.Schemas.MonsterModel.ssdl - @@ -177,34 +133,22 @@ {E06D1C12-EFE8-4413-A15C-AE01FC158F2F} EntityFramework + + {3d65611f-e8fb-4a33-9196-7836969d6378} + FunctionalTests.Transitional + - - - - - - - - - - - - - - - - @@ -222,14 +166,10 @@ - - - - @@ -237,189 +177,34 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -437,7 +222,6 @@ - @@ -459,258 +243,30 @@ - - - - - - - - - - - - - - CsAdvancedPatterns.tt - - - CsAdvancedPatterns.tt - - - CsAdvancedPatterns.tt - - - True - True - CsAdvancedPatterns.Context.tt - - - True - True - CsAdvancedPatterns.tt - - - CsAdvancedPatterns.tt - - - CsAdvancedPatterns.tt - - - CsAdvancedPatterns.tt - - - CsAdvancedPatterns.tt - - - - - - - - - - - CsAdvancedPatterns.tt - - - CsAdvancedPatterns.tt - - - CsAdvancedPatterns.tt - - - CsAdvancedPatterns.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - True - True - CsMonsterModel.Context.tt - - - True - True - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - - - - - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - CsMonsterModel.tt - - - - - - 201112202056275_InitialCreate.cs - - - - 201112202056573_AddUrlToBlog.cs - - - - - - - - - - Component - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/EntityFramework/FunctionalTests/ProductivityApi/InvalidTypeTests.cs b/test/EntityFramework/FunctionalTests/ProductivityApi/InvalidTypeTests.cs index d1c62d22..5b472f42 100644 --- a/test/EntityFramework/FunctionalTests/ProductivityApi/InvalidTypeTests.cs +++ b/test/EntityFramework/FunctionalTests/ProductivityApi/InvalidTypeTests.cs @@ -126,7 +126,7 @@ public void Set_throws_only_when_used_if_type_derives_from_valid_type() // Create a derived type in a new assembly var provider = new CSharpCodeProvider(); var result = provider.CompileAssemblyFromSource( - new CompilerParameters(new[] { GetType().Assembly.Location }), + new CompilerParameters(new[] { typeof(Category).Assembly.Location }), "public class DerivedCategory : SimpleModel.Category { }"); var derivedCategoryType = result.CompiledAssembly.GetTypes().Single(); diff --git a/test/EntityFramework/UnitTests/App.config b/test/EntityFramework/UnitTests/App.config index 7a1dade8..a1db9e75 100644 --- a/test/EntityFramework/UnitTests/App.config +++ b/test/EntityFramework/UnitTests/App.config @@ -11,7 +11,7 @@ - + diff --git a/test/EntityFramework/UnitTests/UnitTests.csproj b/test/EntityFramework/UnitTests/UnitTests.csproj index 0f8ff822..bff29fae 100644 --- a/test/EntityFramework/UnitTests/UnitTests.csproj +++ b/test/EntityFramework/UnitTests/UnitTests.csproj @@ -610,6 +610,10 @@ Migrate migrate + + {3d65611f-e8fb-4a33-9196-7836969d6378} + FunctionalTests.Transitional + {23330EF8-2593-4B0A-A70F-12E6BE1F46C4} FunctionalTests @@ -621,17 +625,17 @@ - if not exist "$(TargetDir)x86" md "$(TargetDir)x86" -xcopy /s /y /d "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\x86\*.*" "$(TargetDir)x86" -if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64" + if not exist "$(TargetDir)x86" md "$(TargetDir)x86" +xcopy /s /y /d "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\x86\*.*" "$(TargetDir)x86" +if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64" xcopy /s /y /d "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64" - \ No newline at end of file diff --git a/test/EntityFramework/VBTests/App.Config b/test/EntityFramework/VBTests/App.Config index 403fada3..6aaefd33 100644 --- a/test/EntityFramework/VBTests/App.Config +++ b/test/EntityFramework/VBTests/App.Config @@ -15,7 +15,7 @@ - + \ No newline at end of file diff --git a/test/EntityFramework/VBTests/VBTests.vbproj b/test/EntityFramework/VBTests/VBTests.vbproj index 41f69113..3863a861 100644 --- a/test/EntityFramework/VBTests/VBTests.vbproj +++ b/test/EntityFramework/VBTests/VBTests.vbproj @@ -311,6 +311,10 @@ {E06D1C12-EFE8-4413-A15C-AE01FC158F2F} EntityFramework + + {3d65611f-e8fb-4a33-9196-7836969d6378} + FunctionalTests.Transitional + {23330EF8-2593-4B0A-A70F-12E6BE1F46C4} FunctionalTests